między Atmegą a modułem G

Nie widziałem wątku od początku i może top pytanie już padło: z czego zasilasz ten moduł?

Reply to
Marek
Loading thread data ...

W dniu 2012-12-14 23:29, Marek pisze:

Głównym źródłem zasilania jest zasilacz CB, dający na wyjściu 13,8V. Oczywiście za nim dałem 78T05. Na wejściu kondensator 470uF i 330nF, na wyjściu 220uF i 100nF. Przy pinach zasilania modułu (zgodnie z manualem)

1000uF i 100nF.

Atmega zasilana jest z tego samego stabilizatora (próbowałem już rozdzielenia zasilania, ale nic to nie zmieniło). Oczywiście przy kluczowych pinach ma kondensatorki filtrujące.

Co do samego zasilacza, to może ciągle dawać 3A, w porywach do 5A, tak więc ma odpowiednią wydajność...

Tak mi jeszcze przyszło do głowy... Może to nie jest wcale błąd transmisji? Może to coś związanego z konfiguracją modułu? Tylko w takim razie dlaczego problemy nie występowałyby przy pracy z samym komputerem?

Reply to
Atlantis

Jest jeszcze jedna rzecz o której chyba zapomniałem wspomnieć, a która może być wartą odnotowania. Mianowicie mam dwa takie moduły i obydwa zachowuję się identycznie. Zastanawia mnie niezwykła regularność tej anomalii. Przecież gdyby to były jakieś zakłócenia od niefiltrowanego zasilania albo jakichś lokalnych pół EM, oddziałujących na urządzenie, to przychodziłyby różne krzaczki. A tak nie jest. Problem występuje w dwóch konkretnych miejscach...

Nie znam się aż do tego stopnia na specyfice transmisji rs232, więc chciałbym zapytać czy:

1) Możliwe jest, żeby moduł zachowywał się inaczej w stosunku do Amtegi niż do PC z odpalonym HyperTerminalem? Na przykład żeby wysyłał jakieś dodatkowe dane? 2) Możliwe jest, żeby HyperTerminal "ukrywał" pewne rzeczy przy normalnej komunikacji z modułem, gdy był z nim połączony obiema liniami, ale już pokazywał je przy "podsłuchiwaniu" linią odbiorczą? 3) Możliwe jest, żeby jednego komunikatu nie dało się wysłać z Atmegi do modułu (chociaż HyperTerminal go odbierał), a co więcej - żeby "podsłuchujący" komputer nic nie widział?
Reply to
Atlantis

Dnia Sat, 15 Dec 2012 00:16:00 +0100, Atlantis napisał(a):

Niestety - ale GSM bierze duzo pradu i generuje mocna fale. Mozliwe.

Dziesiatki roznic moga byc. Napieciowe dopasowanie jest ? bity parzystosci ? 2 bity stopu ? Predkosc ta sama ? linie dodatkowe ? sterowanie przeplywem ?

Norma. Jeb*y MS, jeb* windows, jeb* programisci, jeb* projektanci, jeb* prezesi i uczciwych programow juz nie ma. Podstawa to terminal z trybem hex ... tylko ktory to ? Odkurzyc stary komputer z DOS i xtalk ? Tez nie byl idealny.

Wlacz logowanie do pliku ... a i za to nie recze, poza tym ... czym to potem obejrzec, zeby bylo uczciwie ..

To juz moze mniej...

A to juz mniej ... ale w czym oprogramowane ? Tylko assembler prawde ci powie .. o ile go dobrze znasz :-)

Skoro nie wysyla, to logiczne ze nie widac :-) Chyba o jakas inna kombinacje chodzi..

J.

Reply to
J.F.

W dniu 2012-12-15 00:16, Atlantis pisze:

Hyperterminala zazwyczaj nie używam właśnie z tego powodu. Bywa że nie pokaże ci niczego jeśli nie masz dokładnie ustawionych parametrów transmisji. Czyli jak przyjdzie ramka nie pasująca do ilości bitów czy parzystości to jej może nie pokazać. Użyj Terminal v1.90b by Bray++.

Reply to
Mario

Hyperterminal to chyba najgorszy program jaki mogłeś użyć. Spróbuj programu Tera Term (działa na XP i 7), albo też Realterm.

pytający

Reply to
pytajacy

Rozumiem ze to moduł 5V? Możesz mi podać jego model? W dalszej części przez ze nie ma problemu przy komunikacji z komputerem a później masz wątpliwisci co do działania hyperterminala. W jaki sposób atmega (opisz procedurę odbioru znaku) komunikuje sie z modulem? Czy nie występuje sytuacja w ktorej atmega wysyla do modulu komendy at, gdy moduł nie jest gotowy na ich otrzymywanie (nie czekasz na wszystkie znaki z poprzedniego komunikatu z modulu lub znaku gotowosci). Najczestsza przyczyną problemow to za szybkie wysyłanie komend nie czekając na poprawne zakończenie poprzednich (transmisja kolejnego polecenia w trakcie odbierania wyników z poprzedniego). Np. na sam początek wysylasz at&f i atmega czeka tylko na OK i wysyła kolejne polecenie, a trzeba czekać na OK\r\n dopiero po ostatnim \n z odpowiedzi może transmitowac kolejne polecenie. Kiedyś miałem podobny problem ze moduł dziwnie się zachowywał z mcu a w terminalu było prawidłowo. Był błąd w kodzie programu, mcu wysyłał kolejne polecenie w trakcie transmisji ostatniego \n z odpowiedzi poprzedniego polecenia i moduł albo się "przytykal" albo wysylal krzaczek. Na pc w terminalu problemów nie będzie bo wklepujac polecenia przerwy między poleceniami sa naturalne i wtedy wszystko działa.

Reply to
Marek

W dniu 2012-12-15 09:12, Marek pisze:

Wydawało mi się, że już wcześniej wspominałem. Moduł to Motorola D15. Może pracować z napięciem zasilania od 3V do 6V. Niezależnie od tego stan wysoki na liniach rs232 wynosi 5V. W tej chwili się tym szczególnie nie martwię, bo Atmega zasilana jest ze stabilizatora 5V, ale faktycznie ta kwestia chodzi mi po głowie, bo docelowo układ ma być zasilany z akumulatorka 3,6V.

Będę wtedy chyba potrzebował jakiegoś level shiftera?

Manual podaje następującą informację.

The signal thresholds are: Vih 2.0V min. Vil 0.8V max. Voh 4.4V min. @ 50uA or 3.8V min. @ 8mA. Vol 0.1 max. @ 50uA or 0.44V @ 8mA.

Po prostu starałem się doszukiwać przyczyn tam, gdzie tylko się dało. Program pisałem w oparciu o wskazania HT, więc zacząłem nawet podejrzewać, że to on coś ukrywał i mogłem tego nie uwzględnić w kodzie. Wychodzi jednak na to, że przyczyna była zgoła inna...

No i to chyba będzie to... Dopiero wróciłem z pracy i nie miałem czasu na eksperymenty, ale to najbardziej prawdopodobne wytłumaczenie. Po prostu nie wiedziałem o tej własności modułu - sądziłem, że komunikaty się kolejkują i wymiana informacji w obydwie strony odbywa się niezależenie. Faktycznie dotychczasowy kod ma opisaną przez Ciebie cechę.

Krótko rzecz ujmując używam dwóch tablic: rx_buffer[] i last_line[]. Do pierwszej napływają wszystkie znaki z modułu GSM, za wyjątkiem \n, które są pomijane. Wystąpienie \r powoduje przepisanie wszystkich poprzedzających go znaków z bufora do last_line[]. Pierwszy element tablicy last_line[] pełni też funkcję flagi informującej o przyjęciu odpowiedzi (kopiowanie odbywa się w przerwaniu, więc z punktu widzenia reszty programu całość przybywa za jednym razem).

Jednak zgodnie z tym co piszesz po wystąpieniu \r moduł odbierał jeszcze \n (tyle tylko, że go nigdzie nie zapisywał). Co więcej - w niektórych przypadkach potem leciała jeszcze pusta linie (\r\n). A tymczasem flaga była już postawiona i zaczynało się nadawanie kolejnej komendy...

Teraz zrobię to inaczej. Wystąpienie \n będzie inicjowało kopiowanie danych z bufora do last_line[], aż do wystąpienia znaku \r. Wyjątkiem będzie sytuacja, kiedy \r znajdzie się w pierwszym polu bufora - wtedy zostanie on po prostu wyczyszczony (ignorowanie pustych linii). Dodatkowo, przed nadaniem każdej komendy zastosuję opóźnienie.

BTW jeszcze pytanie natury formalnej. Jak inteligentny jest kompilator w zakresie makrodefinicji zastępujących wartości liczbowe? Jeśli np. dam:

#define WARTOSC 31

a potem w programie dam:

if (zmienna < (WARTOSC-1))

To w którym momencie zostanie obliczona wartość? Podczas kompilacji, czy też za każdym razem uC będzie sobie musiał odejmować jedynkę? ;)

Reply to
Atlantis

Jakie masz wyjście z module? Bo może to jest OC z jakimś słabym pullupem i pojemności pasożytnicze nie przeładowują się wystarczająco szybko?

Sprawdzałeś kształt obu zboczy na wyjściu z modułu oraz z AVR-a?

Tak mi jeszcze przyszło do głowy - jakie masz opóźnienie między kolejnymi znakami, wysyłanymi do modułu?

Może odsyła coś ze złym baudrate? A może to fałszywa transmisja, wynikająca z tego, że moduł się włącza, resetuje, inicjalizuje i na chwilę zmienia stan linii? Oglądałeś ten krzaczek na oscyloskopie?

W takich przypadkach (diagnozowanie problemów komunikacji) oscyloskop jest podstawowym narzędziem... gdzieś coś jest źle, oscyloskop pomoże Ci zobaczyć, gdzie.

Kiedy ten krzaczek w ogóle przychodzi? Gdy coś wyślesz? Czy może wcześniej, przy starcie modułu, ale odczytujesz go dopiero wtedy, gdy coś wyślesz?

Generalnie z RS-em jest tak, że warto opróżnić bufor odbiorczy przed pierwszą komunikacją. Diabli wiedzą, co się tam dzieje przy włączaniu modułu.

Reply to
Adam Wysocki

Zasilacz tak (i to o rzędy wielkości - to że moduł pobiera ampery w peakach nie znaczy, że średni pobór prądu też taki jest) - ale jak widzieliśmy (oscylacje na zasilaniu) reszta układu zasilania (stabilizator, pojemności, a nawet przewody) ma kiepską odpowiedź na nagły impuls prądowy. Właśnie po to są te małe kondensatory. W układach cyfrowych i modułach GSM (i innych zastosowaniach, gdzie są nagłe zmiany poboru prądu) to ma kluczowe znaczenie.

Ale jeżeli sprawdziłeś zasilanie przy module i te oscylacje zniknęły, masz pewność, że zasilanie (przy module! to ważne) jest stabilne, gdy moduł komunikuje się z siecią (wtedy są peaki poboru prądu), to zasilanie mamy załatwione.

Reply to
Adam Wysocki

Widziałem kiedyś fajny level shifter na takie okazje.

formatting link
Stosowałem z powodzeniem na BSS138.

Daj 20ms (na ślepe oko) przed każdym znakiem.

Kompilator zobaczy w tym miejscu "zmienna < (31 - 1)" (bo preprocesor podstawi

31 za WARTOSC) i od razu obliczy do 30.

Optymalizatorem się nie martw - dzisiejsze optymalizatory są wystarczająco inteligentne :) Mało jest przypadków, gdy trzeba poprawiać optymalizator.

Poza tym najpierw zrób, żeby działało, a potem baw się w optymalizacje.

Reply to
Adam Wysocki

Jeśli tylko elektrycznie wszystko jest OK (prawidłowe zbocza, prawidłowe poziomy napięć), to jest to mało prawdopodobne. Tzn. modem będzie wysyłał to samo (taka natura RS-232), ale różne odbiorniki mogą różnie to odbierać. Tutaj oscyloskop jest Twoim najlepszym przyjacielem.

Nie. To nie ma znaczenia. Ale nie zdziwiłbym się (chociaż nie wiem tego, bo bardzo dawno używałem HT), gdyby HT np. ukrywał NUL-e (znaki 0x00).

Nie. RS jest bardzo prosty i nie ingeruje w wysyłane komunikaty. Dla niego to po prostu ciąg znaków.

Reply to
Adam Wysocki

Linux i hexdump -C /dev/ttyS0 :)

notepad++ jest w miarę uczciwy, jeśli chodzi o znaki specjalne.

Assembler? Ja ufam kompilatorowi :) Błędy kompilatora to bardzo rzadkie stworzenia. Są możliwe, ale nieprawdopodobne. Chociaż zdarzały mi się różne jaja, gdy źle były poustawiane np. opcje linkera. Ale w tak dużym programie to by już dawno powychodziło.

Reply to
Adam Wysocki

Pisząc rs232 nasz na myśli usart mcu? Używasz jakieś przejściówki usart<->rs232 czy usart<->usb w przypadku łączenia się z pc?

jeśli atmega nie może na 3.3v, to owszem albo level shifter ale można też obniżyć dzielnikami a podciagnac dioda + rez. osobiście używałem ten drugi sposób z powodzeniem.

last_line[]. Do

ja jestem zwolennikiem buforu odbiorczego typu ring, które wypełnia przerwanie po odbiorze znaku + funkcje odczytu zawartosci bufora. Algorytm to m.in. dwie funkcje (w psedokodzie): wyslij("at&f\r\n"); czekajna("OK\r\n", 1000); Pierwsza wysyła string polecenia, druga odczytuje bufor (nie będę wnikał w obsługę bufora, sloty itp. ) czekając aż się pojawi oczekiwany string w określonym czasie (timeout w ms), jeśli się nie pojawi to funkcją zwraca błąd, który możemy obsłużyć. Bufor ring bardzo ładnie jest opisany wraz z przykładami w nocie an2120 dla m68hc08, polecam. Oczywiście ważne jest aby do funkcji oczekującej podawać "cały koniec" oczekiwanego stringu (wraz z "\r\n") aby nie doprowadzić do zbyt wczesnego nadania kolejnego polecenia.

kompilator w

kompilacji, czy

Nie powinien przy włączonej optymalizacji (to się chyba nazywa constant folding), po prostu sprawdzi czy,zmienna<30. Ale to zalezy od kompilatora i włączonego poziomu optymalizacji.

Reply to
Marek

W dniu 2012-12-15 20:04, Marek pisze:

Tak, miałem na myśli właśnie usart Atmegi. Łącząc się z pecetem używam modułu na max3232. Przelotkę na USB będę musiał kupić, ale do takich "warsztatowych" zastosowań używam leciwego ThinkPada T23, który posiada port COM.

Hmm... Zainteresuję się tematem. Na razie zrobiłem to "po swojemu". Jest to może rozwiązanie proste, nawet i nieco toporne, ale w pewnym sensie to jego zaleta.

W każdym razie najważniejsze - miałeś rację co do przyczyny. Zmieniłem procedurę odbierającą znaki. W sposób opisany w poprzedniej wiadomości i teraz transmisja przebiega prawidłowo. W komunikatach wysyłanych przez moduł nie ma żadnych "krzaczków". Wracają czyste komunikaty.

Jednak teraz w oczy rzuciła mi się jeszcze jedna kwestia, której nie dostrzegłem wcześniej. Mianowicie komunikaty są odbierane liniami. Puste są ignorowane, ale przyjście każdej następnej pełnej zastępuje poprzednią zawartość last_line[]. Sęk w tym, że np. na zapytanie "AT+CPIN?" moduł odpowiada w następujący sposób:

+CPIN: SIM PIN\r\n \r\n\ OK\r\n

Efekt jest oczywisty - oczekiwana, pierwsza linia zostaje niemal momentalnie zastąpiona przez trzecią (druga zostaje zignorowana). Można by to wyłączyć (np. jakąś komendą AT) czy jedynie w grę wchodzi zmiana algorytmu odbierania komunikatów?

Reply to
Atlantis

Niektóre odpowiedzi modemu można zamienić na kody numeryczne poleceniem atv0 (np. zamiast "OK" modem odpowie "0"). Ale nie sądzę ze tez to może dotyczyć polecen rozszerzonych dot. np. nr pin. Proponuje zmianę algorytmu z zastosowaniem bufora, tak aby czekał na podany wzorzec stringu odpowiedzi. Po wyslaniu polecenia, które podałeś jako przykład czekamy na string "OK\r\n". Nie ma znaczenia czy w odpowiedzi sa 2 czy 3 linie. Po odebraniu wzorca odpowiedzi (wszystkich 4 znakow O+K+\r+\n) w buforze odbiorczym będzie cała odpowiedź modulu (można ja później parsowac itp.).

Reply to
Marek

Buforuj do cyklicznego bufora i wyciągaj z niego kolejne linie, parsując je od razu.

Reply to
Adam Wysocki

W dniu 2012-12-15 20:04, Marek pisze:

Hmm... Wydaje mi się, że w tym projekcie nawet nie występuje konieczność implementacji ring bufora. Nie będzie występował ciągły przepływ danych. Jedynie w określonych momentach będą przybywały komunikaty o możliwej do przewidzenia długości (odpowiedzi na komunikaty oraz cyklicznie pojawiający się "RING\r\n\r\n" w przypadku połączenia przychodzącego.

Czyszczenie bufora przed wysłaniem polecenie oraz po sprawdzeniu odpowiedzi (a także wykryciu sygnału dzwonka) powinno wystarczyć, o ile dodatkowo zastosuję jakieś zabezpieczenie przed jego przepełnieniem.

Niemniej w celach dydaktycznych przyjrzę się temu zagadnieniu.

Później pewnie będę musiał zastosować też obsługę linii RTS.

Reply to
Atlantis

W dniu 2012-12-15 19:14, Adam Wysocki pisze:

Hmm... Chyba nie do końca na takie okazje... Z tego co widzę tutaj potrzebuję dwóch napięć zasilania - 3.3V oraz 5V. Moduł D15 może pracować na dowolnym napięciu zasilania pomiędzy 3V a 6V. Logiczny stan wysoki jest jednak niezależny od VCC i wynosi 5V. W tej chwili nie ma problemu, bo zarówno moduł jak i uC zasilam ze stabilizatora 78T05.

Martwi mnie jednak zapis w manualu Atmegi8 (a także ATTiny 4313), który dość jasno mówi, że najwyższe dopuszczalne napięcie na każdym pinie (za wyjątkiem resetu) wynosi VCC+0,5V.

Jeśli zastosuję zasilanie z akumulatorka 3,6V z punktu widzenia D15 nic się nie zmieni. VCC będzie mieściło się w widełkach, na liniach danych stan wysoki wciąż będzie wynosił 5V. Jednak z punktu widzenia uC będzie to prawie o jeden wolt za dużo.

Jednocześnie w takim układzie nie będę miał 5V do zasilenia tego shiftera. Gdybym miał, po prostu zasiliłbym z niego całość układu. :)

Reply to
Atlantis

Tak więc reasumując widzę tutaj tylko dwa możliwe rozwiązania:

1) Zasilanie układu z akumulatorka, który (wraz z ewentualnym stabilizatorem) dawałby około 5V. Wolałbym uniknąć takiego rozwiązania - akumulatorem 3,6V z odpowiednim sterownikiem pozwoli mi na korzystanie z typowej ładowarki od komórki. 2) Zastosowanie shiftera, który nie wymaga innego zasilania, jak tylko to pochodzące z baterii. W końcu max232 też nie potrzebuje napięć -15V i +15V do prawidłowej pracy.
Reply to
Atlantis

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.