Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[Atmega32][Bascom] GPS zapis na SD w funkcji szybkości

Elektronik_Kraków 28 May 2011 10:36 2479 6
  • #1
    Elektronik_Kraków
    Level 13  
    Witam
    Mam program, który wyświetla na LCD współrzędne oraz prędkość ( prędkości jeszcze nie sprawdzałem w terenie ) oraz zapisuje na karcie SD. Na razie zapis na SD jest ręczny, przez przycisk.
    Chciałbym żeby zapis dokonywał się ze zmienną częstotliwością zależną od szybkości, (szybkość mam jako String i Integer), np:
    0 km/h - co 30 minut
    0- 10 km/h - co 1 minutę
    11-45 km/h - co 40 sekund
    46-100 km/ - co 15 sekund

    Druga sprawa to optymalizacja, może ktoś mógłby doradzić, jak zmniejszyć zużycie pamięci SRAM - może inaczej wykorzystać zmienne, bo chciałem ten program upchnąć w Atmega16 i być może podpiąć do modułu GSM - ale to już chyba Atmega32 musi być.
    Mam też problem z czasem, bo moduł pobiera czas z satelity, jest to dwie godziny do tyłu w stosunku do naszego czasu.

    Program jest taki:
    Code:

    $regfile = "m32def.dat"
    $crystal = 8000000
    $baud = 9600                                                ' predkość transmisji
    $hwstack = 100                                              ' rozmiar stosu sprzętowego
    $swstack = 128                                              ' rozmiar stosu programowego
    $framesize = 100                                            ' rozmiar ramki

    '********************* Konfiguracja dodatkowych bibliotek

    $include "Config_AVR-DOS.BAS"                               'Biblioteka AVR-DOS

    '********************* Konfiguracja wyświetlacza
    Config Lcdbus = 4
    Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portc.2 , Rs = Portc.3
    Config Lcd = 24 * 2

    '********************* Konfiguracja znaków specjalnych LCD
    Deflcdchar 1 , 2 , 5 , 5 , 2 , 32 , 32 , 32 , 32            ' symbol stopnia
    Deflcdchar 2 , 4 , 4 , 4 , 32 , 32 , 32 , 32 , 32           ' symbol minuty
    Deflcdchar 3 , 5 , 5 , 5 , 32 , 32 , 32 , 32 , 32           ' symbol sekundy

    '********************* Konfiguracja wejść i wyjść

    Config Porta.5 = Input
    Set Porta.5
    Config Portd.3 = Output
    Set Portd.3

    '********************* Deklaracje zmiennych
    Dim Rs1 As String * 68
    Dim Gps1 As Byte
    Dim Rs2 As String * 68
    Dim Gps2 As Byte
    Dim Rs3 As String * 68
    Dim Gps3 As Byte
    Dim Rs4 As String * 68
    Dim Gps4 As Byte

    Dim A1 As String * 7
    Dim A2 As String * 7
    Dim A3 As String * 7
    Dim A4 As String * 7
    Dim Ramka As Byte
    Dim Ramka1 As String * 10
    Dim Ramka2 As Byte
    Dim Ramka3 As String * 10
    Dim Ramka4 As Byte
    Dim Ramka5 As String * 10
    Dim Ramka6 As Byte
    Dim Ramka7 As String * 10

    Dim Czas1 As String * 2
    Dim Czas2 As String * 2
    Dim Czas3 As String * 2
    Dim Dat1 As String * 6
    Dim Dat2 As Byte
    Dim Dat3 As String * 6
    Dim Dat4 As String * 2
    Dim Dat5 As String * 2
    Dim Dat6 As String * 2
    Dim L_sat As String * 3

    Dim La1 As String * 2
    Dim La2 As String * 2
    Dim La3 As String * 3
    Dim Lak As String * 1

    Dim Lo1 As String * 2
    Dim Lo2 As String * 2
    Dim Lo3 As String * 3
    Dim Lok As String * 1
    Dim N_sig1 As String * 2
    Dim Speed1 As String * 5
    Dim Speed2 As Byte
    Dim Speed3 As String * 5
    Dim Speed4 As Integer
    Dim Speed5 As Integer
    Dim Speed55 As String * 3

    Dim Znaczek As String * 1

    '********************* Deklaracje zmiennych karty SD

    Dim Blad_sd As Bit
    Dim Zapisano As Bit
    Dim Gps_data As String * 25
    Dim Data_czas As String * 18

    '********************* Deklaracje podprogramów

    Declare Sub Write_to_sd()


    '********************* Deklaracje Aliasów

    Lcd1 Alias Portd.3



    '********************* Konfiguracja SD/MMC

    'MMC -->ATMega32
    'DATA3 -> PORTB.4
    'DI    -> PORTB.5
    'CLK   -> PORTB.7
    'DATA0 -> PORTB.6

    Const Cmmc_soft = 0                                         'SPI Sprzętowe

       ' Podanie pinu wyboru układu
       Config Pinb.4 = Output                                   'wskazanie, który Pin jest CS karty MMC/SD
       Mmc_cs Alias Portb.4
       Set Mmc_cs

       ' Definiowanie Pinu układu HW-SPI, który ma sygnał SS
       Config Pinb.7 = Output                                   ' definowanie Pin'u sygnału SPI SS
       Spi_ss Alias Portb.7
       Set Spi_ss                                               ' Set SPI-SS to Output and High por Proper work of
                                                      ' SPI as Master

       ' HW-SPI konfigurowane dla szybszej pracy
      Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 4 , Noss = 1       'Config Spi = Soft , Din = Pinb.3 , Dout = Portb.2 , Ss = Portb.0 , Clock = Portb.1
       Spsr.0 = 1                                               ' Podwójna prędkość na ATMega128
       Spiinit                                                  ' Inicjowanie SPI

    'Spiinit

    ' Błędy
    Const Cperrdrivereset = 225                                 ' Error response Byte at Reset command
    Const Cperrdriveinit = 226                                  ' Error response Byte at Init Command
    Const Cperrdrivereadcommand = 227                           ' Error response Byte at Read Command
    Const Cperrdrivewritecommand = 228                          ' Error response Byte at Write Command
    Const Cperrdrivereadresponse = 229                          ' No Data response Byte from MMC at Read
    Const Cperrdrivewriteresponse = 230                         ' No Data response Byte from MMC at Write
    Const Cperrdrive = 231
    Const Cperrdrivenotsupported = 232                          ' return code for DriveGetIdentity, not supported yet
    Waitms 700
    Dim Gbdriveerror As Byte                                    ' General Driver Error register
    Dim Gbdriveerrorreg As Byte                                 ' Driver load Error-Register of HD in case of error
    Dim Gbdrivestatusreg As Byte                                ' Driver load Status-Register of HD on case of error
    Dim Gbdrivedebug As Byte
    $lib "MMC.LIB"                                              ' link do biblioteki drivera
    $external _mmc




    '********************* Wartości początkowe
    Lcd1 = 1
    A1 = "$GPGGA"
    A2 = "$GPGSA"
    A3 = "$GPRMC"
    A4 = "$GPGSV"
    Znaczek = ","
    Zapisano = 0
    Blad_sd = 0



    Cursor Off
    Cls

    Do

    If N_sig1 = "V" Then


    Locate 1 , 1
    Lcd "Brak ramki!!"

    Locate 2 , 1
    Lcd "           "

    Locate 1 , 13
    Lcd "            "

    Locate 2 , 13
    Lcd "            "

    Else

    Locate 2 , 1
    Lcd "L. sat: " ; L_sat

    Locate 1 , 1
    Lcd Speed5 ; " km/h      "



    Locate 1 , 13
    Lcd La1 ; Chr(1) ; La2 ; Chr(2) ; La3 ; Chr(3) ; Lak

    Locate 2 , 13
    Lcd Lo1 ; Chr(1) ; Lo2 ; Chr(2) ; Lo3 ; Chr(3) ; Lok


    End If

    Do

        Gps1 = Inkey()
        If Gps1 = 13 Then Exit Do                               ' jeśli koniec linii
        Rs1 = Rs1 + Chr(gps1)                                   ' utwórz ciąg

    Loop

    Do

       Gps2 = Inkey()
       If Gps2 = 13 Then Exit Do                                ' jeśli koniec linii
        Rs2 = Rs2 + Chr(gps2)                                   ' utwórz ciąg

    Loop

    Do

        Gps3 = Inkey()
        If Gps3 = 13 Then Exit Do                               ' jeśli koniec linii
        Rs3 = Rs3 + Chr(gps3)                                   ' utwórz ciąg

    Loop

    Do

        Gps4 = Inkey()
        If Gps4 = 13 Then Exit Do                               ' jeśli koniec linii
        Rs4 = Rs4 + Chr(gps4)                                   ' utwórz ciąg

    Loop

    '***************************** składam string z danymi do zapisu

    Gps_data = La1 + " " + La2 + " " + La3 + " " + Lak + " " + Lo1 + " " + Lo2 + " " + Lo3 + " " + Lok
    Data_czas = Dat4 + "/" + Dat5 + "/" + Dat6 + " " + Czas1 + ":" + Czas2 + ":" + Czas3


    '***************************** szuka ramki

    Ramka = Instr(rs1 , A1)                                     ' szukaj w zmiennej Rs ciągu A1
    Ramka1 = Mid(rs1 , Ramka , 6)                               ' zwraca fragment tekstu ze zmiennej Rs

    Ramka2 = Instr(rs2 , A2)                                    ' szukaj w zmiennej Rs ciągu A2
    Ramka3 = Mid(rs2 , Ramka2 , 6)                              ' zwraca fragment tekstu ze zmiennej Rs

    Ramka4 = Instr(rs3 , A3)                                    ' szukaj w zmiennej Rs ciągu A3
    Ramka5 = Mid(rs3 , Ramka4 , 6)                              ' zwraca fragment tekstu ze zmiennej Rs

    Ramka6 = Instr(rs4 , A4)                                    ' szukaj w zmiennej Rs ciągu A3
    Ramka7 = Mid(rs4 , Ramka6 , 6)                              ' zwraca fragment tekstu ze zmiennej Rs

    '***************************** szuka ramki  odczytuje z ramki



    If Ramka1 = "$GPGGA" Then                                   ' jesli zmienna Ramka1 =  "$GPGGA" wtedy
    'Czas = Mid(rs1 , 8 , 6)                                     ' zwróć wartość 6 kolejnych pól licząc od znaku 8-go z ciągu Rs

    End If


    If Ramka5 = "$GPRMC" Then                                   ' jesli zmienna Ramka1 =  "$GPRMC" wtedy
    Czas1 = Mid(rs3 , 9 , 2)                                    ' zwróć wartość 2 kolejnych pól licząc od znaku 9-go z ciągu Rs
    Czas2 = Mid(rs3 , 11 , 2)                                   ' zwróć wartość 2 kolejnych pól licząc od znaku 11-go z ciągu Rs
    Czas3 = Mid(rs3 , 13 , 2)                                   ' zwróć wartość 2 kolejnych pól licząc od znaku 13-go z ciągu Rs
    La1 = Mid(rs3 , 18 , 2)                                     ' zwróć wartość 2 kolejnych pól licząc od znaku 18-go z ciągu Rs
    La2 = Mid(rs3 , 20 , 2)
    La3 = Mid(rs3 , 23 , 3)
    Lak = Mid(rs3 , 29 , 1)

    Lo1 = Mid(rs3 , 32 , 2)
    Lo2 = Mid(rs3 , 34 , 2)
    Lo3 = Mid(rs3 , 37 , 3)
    Lok = Mid(rs3 , 43 , 1)

    Speed1 = Mid(rs3 , 45 , 3 )                                 'wartość 3 kolejnych pól licząc od znaku 45
    Speed2 = Instr(speed1 , Znaczek )                           'określa numer miejsca położenia ","
    Speed3 = Mid(speed1 , 1 , Speed2)
    Speed4 = Val(speed3)

    Speed5 = Speed4 * 1.852                                     ' prędkość jako string do wyświetlania

    Speed55 = Str(speed5)                                       ' prędkość jako string dla zapisu na Sd

    Dat1 = Mid(rs3 , 55 , 6 )
    Dat2 = Instr(dat1 , Znaczek )
    Dat3 = Mid(dat1 , 1 , Dat2)
    Dat4 = Mid(dat3 , 1 , 2)
    Dat5 = Mid(dat3 , 3 , 2)
    Dat6 = Mid(dat3 , 5 , 2)

    N_sig1 = Mid(rs3 , 10 , 1)                                  'wykrywa literę V, co oznacza brak ramki

    End If

    If Ramka7 = "$GPGSV" Then                                   ' jesli zmienna Ramka1 =  "$GPGSV" wtedy
    L_sat = Mid(rs4 , 13 , 2)                                   ' zwróć wartość 2 kolejnych pól licząc od znaku 13-go z ciągu Rs

    End If


    Waitms 199
    Rs1 = ""
    Rs2 = ""
    Rs3 = ""
    Rs4 = ""


    '***************************** warunek określający częstość zapisu na SD


    If Pina.5 = 0 Then
      Call Write_to_sd()                                        'Idzie zapisać wyniki
    End If


    Loop

    End

    '***********************  Obsługa zapisu na SD

    Sub Write_to_sd()
    Local Errorcode As Byte                                     ''()
         Gbdriveerror = Driveinit()
        If Gbdriveerror = 0 Then
          Errorcode = Initfilesystem(1)
          If Errorcode <> 0 Then
             Blad_sd = 1
          Else

             Open "gps.txt" For Append As #2                    'otwórz plik pomiar.txt aby dopisać dane
             Write #2 , Data_czas , Gps_data , Speed55          'zapisz dane: data, czas , odczyt temperatury
             Flush #2                                           'zapisz bufor pliku na karcie SD
             Close #2                                           'zamknij kanał transmisji sprzętowego urządzenia
             Blad_sd = 0                                        'ustaw zmienna na 0
          End If
        Else
         
          Blad_sd = 1
       End If

    End Sub
  • #2
    rafcio363
    Level 30  
    Avr-dos zabiera 1kb sram na dzień dobry więc raczej do atmega16 się nie zmieścisz(chyba że przesiądziesz się na C).Jak masz podpiętą kartę do procka przez rezystory ( bo właśnie sam borykam się z tym problemem).
    Quote:
    $hwstack = 100 ' rozmiar stosu sprzętowego
    $swstack = 128 ' rozmiar stosu programowego
    $framesize = 100

    Z tego co pamiętam minimalne powinny być 128.
  • #3
    Elektronik_Kraków
    Level 13  
    Z zapisem nie ma problemu. Od wczoraj testuję na tych wartościach i działa bez problemu, ale częstotliwość zapisu nie może być zbyt duża, testowałem co 5 sekund i czasem zgubi jakiś zapis.
    Przy ustawieniach:
    Code:

    $hwstack = 128                                              ' rozmiar stosu sprzętowego
    $swstack = 128                                              ' rozmiar stosu programowego
    $framesize = 128                                            ' rozmiar ramki

    i zapisie co 5 sekund też gubi, sprawdzałem, zapisał 6 stringów na 10 naciśnięć przycisku. Przy zapisie co 10 sekund gubi mniej.

    Dane na kartę SD idą przez dzielnik z rezystorów ( taką już kupiłem płytkę testową EVB 4.3 ). Też miałem problemy z odpaleniem zapisu na SD - nawet mimo użycia gotowego i skopiowanego kodu. Pomogła wymiana kwarcu z 16 MHz na 8 MHz i wtedy ruszyło od razu.
  • #4
    Elektronik_Kraków
    Level 13  
    Dołożyłem mu obsługę zegara PCF8563 i wyrabia się do 4 zapisów na minutę.
    A zapisuje:
    data,
    czas,
    współrzędne xx xx xxx N
    współrzędne xx xx xxx E
    prędkość

    Podobno przy zapisie na kartę trzeba mieć zegar, bo inaczej występują problemy.
  • #5
    dondu
    Moderator on vacation ...
    Elektronik_Kraków wrote:
    Druga sprawa to optymalizacja, może ktoś mógłby doradzić, jak zmniejszyć zużycie pamięci SRAM - może inaczej wykorzystać zmienne, bo chciałem ten program upchnąć w Atmega16 i być może podpiąć do modułu GSM - ale to już chyba Atmega32 musi być.

    Przejdź na C.
  • #6
    Elektronik_Kraków
    Level 13  
    Na C to w przyszłości - niedalekiej ( literatura już jest ). Na razie wybrałem Bascom, żeby zrozumieć o co w tym biega. Jestem raczej "manualny", czyli łatwo mi się składa układy. Ale chciałem coś swojego mieć, coś co się przyda. Na razie utknąłem na UART ( sterowanie mikrokontrolerem przez RS485, generalnie przez RS ), więc dla chwili przerwy zająłem się GPS.