eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronika › sscanf() - co robię źle?
Ilość wypowiedzi w tym wątku: 16

  • 1. Data: 2013-02-23 13:02:00
    Temat: sscanf() - co robię źle?
    Od: Atlantis <m...@w...pl>

    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?


  • 2. Data: 2013-02-23 14:53:05
    Temat: Re: sscanf() - co robię źle?
    Od: "J.F." <j...@p...onet.pl>

    Dnia Sat, 23 Feb 2013 13:02:00 +0100, Atlantis napisał(a):
    > 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.

    > 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.

    > 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 ?

    > 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 ?

    > 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.


  • 3. Data: 2013-02-23 15:56:40
    Temat: Re: sscanf() - co robię źle?
    Od: JDX <j...@o...pl>

    On 2013-02-23 13:02, Atlantis wrote:
    [...]
    > 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 *******************/


  • 4. Data: 2013-02-23 16:53:53
    Temat: Re: sscanf() - co robię źle?
    Od: shg <s...@g...com>

    On Feb 23, 1:02 pm, Atlantis <m...@w...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.


  • 5. Data: 2013-02-23 20:55:14
    Temat: Re: sscanf() - co robię źle?
    Od: Marek Borowski <m...@...borowski.com>

    On 2013-02-23 16:53, shg wrote:
    > On Feb 23, 1:02 pm, Atlantis <m...@w...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




  • 6. Data: 2013-02-23 22:07:25
    Temat: Re: sscanf() - co robię źle?
    Od: Atlantis <m...@w...pl>

    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.

    #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. :)


  • 7. Data: 2013-02-24 12:12:09
    Temat: Re: sscanf() - co robię źle?
    Od: "J.F." <j...@p...onet.pl>

    Dnia Sat, 23 Feb 2013 22:07:25 +0100, Atlantis napisał(a):
    > 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().

    > #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.


  • 8. Data: 2013-02-24 13:22:49
    Temat: Re: sscanf() - co robię źle?
    Od: Atlantis <m...@w...pl>

    W dniu 2013-02-24 12:12, J.F. pisze:

    > 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.


  • 9. Data: 2013-02-24 14:27:38
    Temat: Re: sscanf() - co robię źle?
    Od: "Pszemol" <P...@P...com>

    "Atlantis" <m...@w...pl> wrote in message
    news:kgd0mp$32l$1@portraits.wsisiz.edu.pl...
    > Sprawdzanie czy wcześniejsze znaki pasują odpuściłem sobie.

    To błąd, bo tak się rodzą potem problemy przy zmianie sprzętu.


  • 10. Data: 2013-02-24 15:01:06
    Temat: Re: sscanf() - co robię źle?
    Od: Atlantis <m...@w...pl>

    W dniu 2013-02-24 14:27, Pszemol pisze:

    > 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ę.

strony : [ 1 ] . 2


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: