Goto page 1, 2 Next
Atlantis
Guest
Sat Feb 23, 2013 1:02 pm
Co prawda pytanie dotyczy programowania, ale chodzi o programowanie AVR,
więc chyba mieści się w tematyce tej grupy. ;)
Mianowicie kontynuuję temat analizy odpowiedzi na komendy AT przy
komunikacji między Atmegą8 a modułem GSM. Do tej pory stosowałem mało
eleganckiego i mało rozwiązania nie wymagającego angażowania stdio.h.
Teraz jednak potrzebuję możliwości odczytania wartości liczbowych
zwracanych przez niektóre polecenia (AT+CPAS, AT+CSQ) i zapisania ich do
zmiennej liczbowej.
W przypadku polecenia AT+CPAS mój moduł GSM zawsze odpowiada w
następujący sposób:
"+CPAS: 00x\r\n" (x to liczba z zakresu 0-5)
W odpowiedniej funkcji przepisuję znaki pojawiające się w buforze
(circular buffer) do tabeli. Gdy pojawi się znak \r dopisuję za nim
jeszcze zero, a potem przystępuję do wydzielenia wartości liczbowej:
sscanf(tablica, "+CPAS: %d\r", &zmienna_int);
następnie funkcja zwraca wartość zapisaną w zmiennej.
Robię coś nie tak? A może %d nie przyjmie liczby poprzedzonej zerami? Z
drugiej strony próbowałem także zapisu "+CPAS: 00%d\r" i także nic nie
dało...
Jak powinno wyglądać pobranie wartości zwracanych przez "AT+CSQ"?
Format wygląda następująco: "+CSQ: xxx, xxx\r\n"
Rozumiem, że sscanf(tablica, "+CSQ: %d, %d\r", zmienna1, zmienna2)
również nie zadziała?
J.F.
Guest
Sat Feb 23, 2013 2:53 pm
Dnia Sat, 23 Feb 2013 13:02:00 +0100, Atlantis napisał(a):
Quote:
Mianowicie kontynuuję temat analizy odpowiedzi na komendy AT przy
komunikacji między Atmegą8 a modułem GSM. Do tej pory stosowałem mało
eleganckiego i mało rozwiązania nie wymagającego angażowania stdio.h.
Zawsze mozesz wrocic - lepiej korzystac ze zgrabnego i dzialajacego
rozwiazania, niz angazowac kobyle ktora robi za duzo i niepewnie.
Quote:
W przypadku polecenia AT+CPAS mój moduł GSM zawsze odpowiada w
następujący sposób:
"+CPAS: 00x\r\n" (x to liczba z zakresu 0-5)
W odpowiedniej funkcji przepisuję znaki pojawiające się w buforze
(circular buffer) do tabeli. Gdy pojawi się znak \r dopisuję za nim
jeszcze zero, a potem przystępuję do wydzielenia wartości liczbowej:
Ja bym sie juz w to \r nie bawil.
Quote:
sscanf(tablica, "+CPAS: %d\r", &zmienna_int);
Robię coś nie tak? A może %d nie przyjmie liczby poprzedzonej zerami?
Wyglada na to ze poprawnie wszystko.
http://www.cplusplus.com/reference/cstdio/scanf/
Ale sprawdz jeszcze raz czy _wszystko_ jest poprawnie, no i co zwraca
sscanf ?
tablica jest tablica znakow, zmienna_int zmienna int itp ?
Quote:
drugiej strony próbowałem także zapisu "+CPAS: 00%d\r" i także nic nie
dało...
Jeszcze mozesz sprobowac %s i zobaczyc gdzie przerywa analize ...
hm, tego \r w formacie nie jestem pewien, moze usun ?
Quote:
Jak powinno wyglądać pobranie wartości zwracanych przez "AT+CSQ"?
Format wygląda następująco: "+CSQ: xxx, xxx\r\n"
Rozumiem, że sscanf(tablica, "+CSQ: %d, %d\r", zmienna1, zmienna2)
również nie zadziała?
ale powinno.
J.
JDX
Guest
Sat Feb 23, 2013 3:56 pm
On 2013-02-23 13:02, Atlantis wrote:
[...]
Quote:
sscanf(tablica, "+CPAS: %d\r", &zmienna_int);
następnie funkcja zwraca wartość zapisaną w zmiennej.
Robię coś nie tak? A może %d nie przyjmie liczby poprzedzonej zerami? Z
drugiej strony próbowałem także zapisu "+CPAS: 00%d\r" i także nic nie
dało...
To w końcu funkcja zwraca to co chcesz czy nie? Dawno już nie zaglądałem
do wnętrzności stdio, ale jakaś taka dziwna myśl chodzi mi po głowie że
funkcje z rodziny scanf "pod spodem" korzystają z dynamicznej alokacji
pamięci i w związku z tym musisz dostarczyć taki alokator. Jeśli tego
nie zrobisz to jest używany jakiś "place holder".
W każdym razie poniższy programik skompilowany gcc 4.7.2 pod WinXP/MinGW
działa zgodnie z oczekiwaniami.
/******************* Utnij tutaj *******************/
/* Kompilacja: gcc -O3 -s -o ssctest ssctest.c */
#include <stdio.h>
const char *tablica1 = "+CPAS: 002\r\0";
const char *tablica2 = "+CSQ: 123, 010\r\0";
int main ( int argc, char *argv[] )
{
int i, j, k;
sscanf (tablica1, "+CPAS: %d\r", &i);
printf ("Odczytana licba: %d\n", i);
sscanf (tablica2, "+CSQ: %d, %d\r", &j, &k);
printf ("Odczytane licby: %d, %d\n", j, k);
return 0;
}
/******************* Utnij tutaj *******************/
shg
Guest
Sat Feb 23, 2013 5:53 pm
On Feb 23, 1:02 pm, Atlantis <marekw1986NOS...@wp.pl> wrote:
Quote:
Robię coś nie tak?
Tak, używasz sscanf().
Napisz normalny interpreter składni na jakiejś maszynie stanów. Będzie
mniejszy, elastyczniejszy i bardziej niezawodny.
Poza tym będzie można przetwarzać dane bez zbędnych buforów.
Marek Borowski
Guest
Sat Feb 23, 2013 8:55 pm
On 2013-02-23 16:53, shg wrote:
Quote:
On Feb 23, 1:02 pm, Atlantis <marekw1986NOS...@wp.pl> wrote:
Robię coś nie tak?
Tak, używasz sscanf().
Napisz normalny interpreter składni na jakiejś maszynie stanów. Będzie
mniejszy, elastyczniejszy i bardziej niezawodny.
Poza tym będzie można przetwarzać dane bez zbędnych buforów.
Mozna zawsze isc po bandzie ;-)
int getStatusFromResponse(const char* response)
{
return response[9] - '0';
}
Pozdrawiam
Marek
Atlantis
Guest
Sat Feb 23, 2013 10:07 pm
W dniu 2013-02-23 20:55, Marek Borowski pisze:
Quote:
Mozna zawsze isc po bandzie
To się sprawdzi tylko wówczas, gdy wartość jest jednocyfrowa, jak w
przypadku +CPAS. Sprawa się komplikuje w sytuacji, gdy trzeba odebrać
coś większego, jak np. poziom sygnału z +CSQ.
#include <stdio.h> istotnie powoduje zauważalny wzrost rozmiaru hex'a,
ale tragedii nie ma. Jeszcze sporo brakuje do całkowitego zapchania
flasha Atmegi8.
BTW problem rozwiązany. Okazało się, że moduł wysyłał dodatkową linijkę
\r\n przed głównym komunikatem - coś, czego nie było w przykładach z
dokumentacji. Szukałem przyczyny wszędzie, ale na to nie wpadłem.
J.F.
Guest
Sun Feb 24, 2013 12:12 pm
Dnia Sat, 23 Feb 2013 22:07:25 +0100, Atlantis napisał(a):
Quote:
W dniu 2013-02-23 20:55, Marek Borowski pisze:
Mozna zawsze isc po bandzie
To się sprawdzi tylko wówczas, gdy wartość jest jednocyfrowa, jak w
przypadku +CPAS. Sprawa się komplikuje w sytuacji, gdy trzeba odebrać
coś większego, jak np. poziom sygnału z +CSQ.
A po co ci ten poziom ? Moze wystarczy sama druga cyfra :-)
Podobna konwersja dla 2-3 cyfr jest trywialna, jest jeszcze atoi().
Quote:
#include <stdio.h> istotnie powoduje zauważalny wzrost rozmiaru hex'a,
ale tragedii nie ma. Jeszcze sporo brakuje do całkowitego zapchania
flasha Atmegi8.
Owszem, ale patrzac na to co sscanf potrafi ... za duzo. Niepotrzebne
obciazenie :-)
J.
Atlantis
Guest
Sun Feb 24, 2013 1:22 pm
W dniu 2013-02-24 12:12, J.F. pisze:
Quote:
A po co ci ten poziom ? Moze wystarczy sama druga cyfra :-)
Podobna konwersja dla 2-3 cyfr jest trywialna, jest jeszcze atoi().
Po chwili zastanowienia przyznaję rację. Uparłem się na stdio.h ze
względów "dydaktycznych" sądząc, że funkcje w nim zawarte i tak mi się
przydadzą (myślę o dodaniu obsługi odbieranych SMS-ów via morse code w
słuchawce ;P).
Po chwili zastanowienia wróciłem jednak do starej koncepcji. Liczę
napływające znaki, i w odpowiedniej chwili zwracam znak-'0' w przypadku
+CPAS oraz 10*(znak1-'0')+(znak2-'0') w przypadku CSQ. Sprawdzanie czy
wcześniejsze znaki pasują odpuściłem sobie.
Pszemol
Guest
Sun Feb 24, 2013 2:27 pm
"Atlantis" <marekw1986NOSPAM@wp.pl> wrote in message
news:kgd0mp$32l$1@portraits.wsisiz.edu.pl...
Quote:
Sprawdzanie czy wcześniejsze znaki pasują odpuściłem sobie.
To błąd, bo tak się rodzą potem problemy przy zmianie sprzętu.
Atlantis
Guest
Sun Feb 24, 2013 3:01 pm
W dniu 2013-02-24 14:27, Pszemol pisze:
Quote:
To błąd, bo tak się rodzą potem problemy przy zmianie sprzętu.
Funkcje i tak piszę z myślą o ściśle określonym module.
Jeśli zajdzie konieczność jego zmiany (na co się nie zanosi) i tak będę
musiał przejrzeć całość kodu odpowiedzialnego za komunikację.
Adam Wysocki
Guest
Mon Feb 25, 2013 12:58 pm
Atlantis <marekw1986NOSPAM@wp.pl> wrote:
Quote:
To błąd, bo tak się rodzą potem problemy przy zmianie sprzętu.
Funkcje i tak piszę z myślą o ściśle określonym module.
Jeśli zajdzie konieczność jego zmiany (na co się nie zanosi) i tak będę
musiał przejrzeć całość kodu odpowiedzialnego za komunikację.
Nie do końca o to chodzi.
Ukrywanie błędów nigdy nie kończy się dobrze. Miałeś dobry przykład -
coś nie przyszło tak, jak zakładałeś, a ty szukałeś błędu zupełnie gdzie
indziej. Dobry program to taki program, który sprawdza takie niepewne
rzeczy. Im mniej ślepych założeń odnośnie wejściowych danych, tym lepiej
(a jak się spodziewasz, że takie będą, to daj asserta lub jego swój
odpowiednik).
--
"Project Manager to człowiek, który myśli, że jak weźmie
dziewięć kobiet, to urodzą dziecko w miesiąc."
Adam Wysocki
Guest
Mon Feb 25, 2013 12:59 pm
JDX <jdx@onet.pl> wrote:
Quote:
funkcje z rodziny scanf "pod spodem" korzystają z dynamicznej alokacji
pamięci i w związku z tym musisz dostarczyć taki alokator. Jeśli tego
nie zrobisz to jest używany jakiś "place holder".
avr-libc ma normalnego malloca, żaden placeholder.
--
"Project Manager to człowiek, który myśli, że jak weźmie
dziewięć kobiet, to urodzą dziecko w miesiąc."
Adam Wysocki
Guest
Mon Feb 25, 2013 1:00 pm
shg <shogoonn@gmail.com> wrote:
Quote:
Robię coś nie tak?
Tak, używasz sscanf().
Napisz normalny interpreter składni na jakiejś maszynie stanów.
Będzie mniejszy, elastyczniejszy i bardziej niezawodny.
Wymyślanie koła na nowo to niestety cecha początkujących programistów
i amatorów. Syndrom NIH.
Ja jestem jak najbardziej za sscanf. O ile nie ma przeciwwskazań, typu
brak miejsca we flashu, to ma to same zalety - głównie taką, że błąd w
sscanf jest raczej mało prawdopodobny. Dostajesz coś, co działa.
--
"Project Manager to człowiek, który myśli, że jak weźmie
dziewięć kobiet, to urodzą dziecko w miesiąc."
Adam Dybkowski
Guest
Tue Feb 26, 2013 8:42 pm
W dniu 2013-02-25 12:00 Adam Wysocki napisał(a):
Quote:
Robię coś nie tak?
Tak, używasz sscanf().
Napisz normalny interpreter składni na jakiejś maszynie stanów.
Będzie mniejszy, elastyczniejszy i bardziej niezawodny.
Wymyślanie koła na nowo to niestety cecha początkujących programistów
i amatorów. Syndrom NIH.
Ja jestem jak najbardziej za sscanf. O ile nie ma przeciwwskazań, typu
brak miejsca we flashu, to ma to same zalety - głównie taką, że błąd w
sscanf jest raczej mało prawdopodobny. Dostajesz coś, co działa.
Oj coś masz podejście zbyt wysokopoziomowe jak do tego zastosowania.
Znam takich - najczęściej speców od Javy i wszystkich możliwych
frameworków. Program wynikowy puchnie w takich przypadkach o cały worek
różnistych bibliotek a czas kompilacji sięga zenitu - tylko po to aby
kilka linii mniej napisać własnego kodu (niemały czas potrzebny na
obczajenie każdego nowego frameworka pomijam).
Wg mnie zrobienie automatu analizującego znaki odczytywane z modułu GSM
(i to "karmionego" znak po znaku) jest najlepszym z zaproponowanych
rozwiązań. Oczywiście jeżeli zrobi się to z głową i odpowiednio obsłuży
sytuacje nadzwyczajne (asynchronicznie przychodzące komunikaty na inny
temat gdy się spodziewamy danej odpowiedzi modułu). Przy okazji
włączyłbym także echo w module GSM (ATE1) dla pewności czy każda komenda
została poprawnie przesłana.
Natomiast jeżeli dla uproszczenia chcemy jednak zbierać całe linie
znaków i dopiero potem je analizować - to w takim przypadku przydadzą
się raczej funkcje strstr, memchr i atoi/atol a nie moloch sscanf.
--
Adam Dybkowski
http://dybkowski.net/
Uwaga: przed wysłaniem do mnie maila usuń cyfry z adresu.
Anerys
Guest
Wed Feb 27, 2013 2:27 am
Całkiem niezgodnie z Netykietą, ale nie mogłem się powstrzymać...
Użytkownik "Adam Wysocki" <gof@somewhere.invalid> napisał w wiadomości
news:gof.pme.1361790049@news.chmurka.net...
Quote:
--
"Project Manager to człowiek, który myśli, że jak weźmie
dziewięć kobiet, to urodzą dziecko w miesiąc."
Gorzej, gdy z tego wyjdzie 49 miesięcy, znając pomysły niektórych "szpecuff"
(absolutnie nie mam na myśli nikogo z naszej grupy), to zagrożenie jest
całkiem realne...
--
Pod żadnym pozorem nie zezwalam na wysyłanie mi jakichkolwiek reklam,
ogłoszeń, mailingów, itd., ani nawet zapytań o możliwość ich wysyłki.
Nie przyjmuję ŻADNYCH tłumaczeń, że mój adres e-mail jest ogólnodostępny
i nie został ukryty. Wszelkie próby takich wysyłek potraktuję jako stalking.
Goto page 1, 2 Next