Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

STM32F0 ADS1234 pomiar z belki tensometrycznej

wados0 21 Cze 2012 20:03 6150 39
  • #1 21 Cze 2012 20:03
    wados0
    Poziom 10  

    Witam

    Mam pewien problem z urządzeniem do pomiaru masy (tj. waga ;)), które będzie wysyłało mierzoną wartość po CANie do innego urządzenia. W załączniku jest schemat płytki.

    Mój problem polega na tym, że odczyt pomiaru lata jak szalony, ale jest cykliczny. Wyrzucając sobie przez rs232 debugujące dane wartości wysyłane przez adc różnią się od siebie o rząd wielkości. Poniżej załączam kod

    Code:

    /*
     * adc.c
     *
     *  Created on: 17-02-2012
     *      Author: Robert Wadowski
     */

    #include "global.h"

    #define SPI_PORT         GPIOA

    enum
    {
       CS = GPIO_Pin_4,
       SCLK = GPIO_Pin_5,
       MISO = GPIO_Pin_6,
       MOSI = GPIO_Pin_7,
       GAIN0 = GPIO_Pin_2,
       GAIN1 = GPIO_Pin_3,
       SPEED = GPIO_Pin_1,
    };

    #define SCLK_HIGH   GPIO_SetBits(SPI_PORT,SCLK)
    #define SCLK_LOW   GPIO_ResetBits(SPI_PORT,SCLK)
    #define DOUT_STATE   GPIO_ReadInputDataBit(SPI_PORT,MISO)

    int adcInit(void)
    {
       GPIO_InitTypeDef   GPIO_InitStructure;
       
       /* CS */
       GPIO_InitStructure.GPIO_Pin = CS;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(SPI_PORT, &GPIO_InitStructure);

         /* SCLK   */
         GPIO_InitStructure.GPIO_Pin = SCLK;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(SPI_PORT,&GPIO_InitStructure);

         /* MISO */
         GPIO_InitStructure.GPIO_Pin = MISO;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(SPI_PORT, &GPIO_InitStructure);

         /* MOSI */
       /*GPIO_InitStructure.GPIO_Pin = MOSI;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(SPI_PORT, &GPIO_InitStructure); */

       /*SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
         SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;




         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
         SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
         SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;     
         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
         SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_RxOnly;
         SPI_InitStructure.SPI_CRCPolynomial = 7;
         SPI_Init(SPI1,&SPI_InitStructure);

         SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_RXNE,ENABLE);
       SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_TXE | SPI_I2S_IT_ERR,DISABLE);
        */

         /* GAIN0 */
         GPIO_InitStructure.GPIO_Pin = GAIN0;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(SPI_PORT,&GPIO_InitStructure);

         /* GAIN1   */
         GPIO_InitStructure.GPIO_Pin = GAIN1;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(SPI_PORT,&GPIO_InitStructure);

         /* SPEED   */
         GPIO_InitStructure.GPIO_Pin = SPEED;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(SPI_PORT,&GPIO_InitStructure);

    //   GPIO_ResetBits(SPI_PORT,CS);   
       GPIO_SetBits(SPI_PORT,GAIN0);   
       GPIO_SetBits(SPI_PORT,GAIN1);   
       GPIO_ResetBits(SPI_PORT,SPEED);   

       delay_ms(1000);

       GPIO_SetBits(SPI_PORT,CS);   
          
       return 0;
    }

    int adcStartMeasurement(void)
    {
       SCLK_LOW;
       return 0;
    }

    int32_t adcNoInterrupt(void)
    {
       int32_t       data = 0;
       uint32_t      tmp = 0;
       uint32_t      neg = 0;
       uint8_t         i = 0;
       uint8_t         sign = 0;
       
       //while(DOUT_STATE != 0);
       
       if(DOUT_STATE == 0)
          {                   
             SCLK_LOW;
             delay_ms(1);
             for(i = 0; i < 24; i++)
                {
                   SCLK_HIGH;
                   delay_ms(1);
                   if(DOUT_STATE == 1) {
                         tmp |= (1<<(23-i));
                         if(i == 0) {
                            sign = 1;   
                         }
                      }                              
                   SCLK_LOW;
                   delay_ms(1);
                }
             SCLK_HIGH;
             delay_ms(1);
             SCLK_LOW;
             /*delay_ms(1);
             SCLK_HIGH;
             delay_ms(1);
             SCLK_LOW;
             delay_ms(1);
             SCLK_HIGH;
             delay_ms(1);
             SCLK_LOW;**/   
             //if((tmp & (1<<23)) == (1<<23)) {
             if(sign == 1) {
                   //tmp = tmp & 0x7FFFFFFF;
                   debug_msg("Changing sign data = %x\r\n", tmp);                     
                   for(i = 0; i < 24; i++) {
                      if((tmp & (1<<i)) == (1<<i)) {
                         neg &= ~(1<<i);
                      } else {
                         neg |= (1<<i);
                      }
                   }
                   debug_msg("Changing sign negation = %x \r\n", neg);
                   debug_msg("Changing sign cutting = %x \r\n", neg & 0x00FFFFFF);
                   debug_msg("Changing sign jedynka = %x \r\n", (neg & 0x00FFFFFF) + 1);

                   data = (int32_t) (neg & 0x00FFFFFF) + 1;
                } else {                             
                   data = (int32_t) tmp;
                }
          }   
       debug_msg("Adc pomiar = %i \r\n", data);                        
       return data;
    }


    W zasadzie cały pomiar odbywa się w funkcji adc int32_t adcNoInterrupt(void) która jest wywoływana w pętli głównej.

    Code:

    #include "global.h"

    int main(void)
    {
       u8   loopFlag = 1;
       oscInit();
       timerInit();
       nvicInit();
       ledOutputConfig();
       initDebugInterface();
       canInit();
       adcInit();
       terminalSendTxt("Entering main loop\r\n");
       while(loopFlag == 1)
          {
             parseStackData(&canStack);
             debug();
             adcStartMeasurement();
             delay_ms(110);         
             terminalSendTxt("Loop\r\n");
             adcNoInterrupt();
             delay_ms(900);
          }
       return 0;
    }


    Cały projekt powstał w keilu, jak widać z użyciem biblioteki firmware stma. Jeśli jest tu nie czytelnie w załączniku również jest cały projekt.

    Załączyłem również widok z terminala
    Tekst Adc pomiar = 8389308 to wynik pomiaru
    Changing sign to konwersja na znak przeciwny.

    Być może popełniłem jakiś prosty błąd, zwłaszcza, że sporo kodu dopisałem do debugowania, niestety nie bardzo wiem w którym kierunku iść by znaleźć problem. Będę wdzięczny za wszelkie sugestie albo znalezione moje błędy. Z góry dziękuję.
    Pozdrawiam,
    Robert Wadowski

    0 29
  • #2 21 Cze 2012 21:01
    atom1477
    Poziom 43  

    Zły program to jedno.
    Ale powodem tych śmieci jest (albo będzie jak program już poprawisz) też to że masz źle zaprojektowaną część zasilania i analogową.
    Np. nie masz żadnego kondensatora 100nF na zasilaniu procka czy ADC.

    0
  • #3 21 Cze 2012 21:05
    wados0
    Poziom 10  

    No na analogówce kompletnie się nie znam, belkę podłączyłem wg data sheeta, zworkami podałem na nią i na ads 5V (shemet 43) więc możliwe, brakuje czegoś na tym schemacie z karty katalogowej ads1234 ?

    Pozdrawiam,
    Robert

    0
  • #4 21 Cze 2012 21:11
    atom1477
    Poziom 43  

    No tak jak pisałem brakuje przede wszystkim kondensatorów na szynach zasilania.
    Poza tym filtrów na wejściach ADC.
    Cykliczność tych zakłóceń wynika pewnie tego że zbierasz też zakłócenia sieciowe 50Hz.
    Płytka pewnie jest jednostronna? Nie sądzę że to będzie działało na takiej.
    A na pewno nie przy rozdzielczości rzędu 20-bitów.
    Jak by nie było pokaż też wzór PCB.
    I sprawdź jakie wyniki zwraca ten cały układ jak w przetworniku zewrzesz wejścia.

    0
  • #5 21 Cze 2012 21:16
    wados0
    Poziom 10  

    Poniżej załączona płytka. Z to co wypluwa ads przy zwarciu nóżek zaraz sprawdzę.
    Po zwarciu wskazywał same zera, więc rozumiem, że to brak kondensatorów, jeśli tak to jaki rząd wielkości ?

    0
  • #6 21 Cze 2012 21:28
    atom1477
    Poziom 43  

    No to ja już się nie dziwę że to nie działa.

    0
  • #7 21 Cze 2012 21:30
    wados0
    Poziom 10  

    atom1477 napisał:
    No to ja już się nie dziwę że to nie działa.


    Hehe ok, mam świadomość swojej znikomej wiedzy na temat elektroniki analogowej, czyli rozumiem, że dodanie kondensatorów ustabilizuje pomiar ?

    0
  • #8 21 Cze 2012 21:42
    atom1477
    Poziom 43  

    A gdzie je teraz dodasz jak płytka jest już gotowa?
    Chyba że przylutujesz do ścieżek.
    Ale dodanie kondensatorów niestety tutaj i tak niewiele pomoże bo liczy się też kolejność ich podłączenia (w szereg z biegiem linii zasilania a nie byle gdzie).
    Niestety kondensatory nie są magicznym rozwiązaniem które cudownie naprawia każdą płytkę.
    Poza tym tutaj nie masz pola masy co też jest dużą wadą tej płytki.
    No chyba że pole masy tam jest tylko go w tym PDFie nie widać. Zdaje się że Eagle tak dziwnie to pokazuje zawsze. No ale ja tam nie wiem.

    0
  • #9 21 Cze 2012 22:03
    wados0
    Poziom 10  

    Masa jest wylana na całą płytkę z obu stron. To, że to jest prostowanie obręczy to wiem, ale żeby nie popełnić błędów na przyszłość mógłbyś mi napisać jak to ma wyglądać lub skierować mnie do jakichś źródeł gdzie w miarę przystępnie jest to opisane. No kondensatory bym przylutował do ścieżek, ale pewnie to nie pomoże jak znam życie.
    Jakie ewentualnie filtry na wejściu musiały by być ?
    Ewentualnie spróbować wlutować te kondensatory jak powinny być, ale jak napisałem muszę najpierw dobrze wiedzieć co źle zrobiłem, na błędach człowiek się uczy :)

    0
  • Pomocny post
    #10 21 Cze 2012 22:33
    atom1477
    Poziom 43  

    Lepiej by było jak by masa była z jednej strony możliwie ciągła.
    Czyli lepiej dać lepszą masę z jednej strony kosztem masy z drugiej strony.
    Niż dawać posiekane masy z obu stron.
    Kondensatory to tak jak tutaj na stronie 14:
    http://www.ti.com/lit/an/scaa082/scaa082.pdf
    A poza tym to jeszcze to poczytaj:
    http://www.x2y.com/filters/TechDay09kr_hpa_Tr...g_Designs_Demand_GoodPCBLayouts%20_JohnWu.pdf (O, tutaj też jest o tych kondensatorach :D. O#2, tutaj też jest o ADS1234:D)
    Nie przejmuj się że jest tego tak dużo. Na razie potrzebne są tylko podstawowe informacje.
    Np. na stronie 47 i 48: jak najwięcej ścieżek na warstwie Top, żeby na warstwie Bottom móc dać jak najlepszą masę. I ta masa wtedy jest poprzerywana jedynie niewielką ilością krótkich ścieżek których już się nie dało inaczej puścić.
    Acha, poza tym to kondensatory umieszczaj jak najbliżej stabilizatorów napięcia. Bo na razie masz jakoś daleko.
    Kondensatorów przy procku i ADC na razie w ogóle nie masz :D, ale jak je już dasz to też jak najbliżej procka/ADC.
    Do procka w tej obudowie potrzebujesz minimum 4 kondensatory 100nF i jeden 4,7uF (Ten 4,7uF to nie elektrolityczny tylko też monolityczny. Powinien on być blisko jednego konkretnego pina procka, ale nie wiem teraz którego. Trzeba by sprawdzić w datsheecie).

    0
  • #11 21 Cze 2012 23:06
    wados0
    Poziom 10  

    Daleko bo chciałem dać radiatory, ale jak widać radośnie w swojej niewiedzy wybrałem najmniej istotną kwestię jako najważniejszą :D

    Dodano po 15 [minuty]:

    Dobra zapoznam się z tymi informacjami i jutro wieczorem pokażę co mi wyjdzie w eaglu z tego, ale będzie wesoło :D. Dzięki za pomoc w każdym razie.

    0
  • #12 21 Cze 2012 23:45
    markosik20
    Poziom 33  

    To nie błąd projektu płytki powoduje takie różnice w odczycie. ADS1234 po odpowiednim ustawieniu ma naprawdę niezłe odczyty nawet na źle zaprojektowanej płytce. Dodatkowo odpowiednio podpięte Vref do ADS'a powoduje że jest w ogóle nie czuły na brak stabilnego źródła napięcia.

    0
  • #13 21 Cze 2012 23:48
    atom1477
    Poziom 43  

    No w programie też może być jakiś błąd.
    Ale brak kondensatorów na zasilaniu musiałem przecież wytknąć :D

    0
  • #14 21 Cze 2012 23:55
    markosik20
    Poziom 33  

    atom1477 napisał:
    No w programie też może być jakiś błąd.
    Ale brak kondensatorów na zasilaniu musiałem przecież wytknąć :D


    W programie MUSI być błąd :) .... a brak kondensatorów to "grzech" :).
    Proponuję przed zaprojektowaniem nowej płytki pobawić się starą i spróbować uzyskać prawidłowe (powtarzalne) odczyty. Na dzień dobry obetnij 4 najmłodsze bity :) oraz sprawdź czy czujnik jest DOBRZE podpięty.

    0
  • #15 22 Cze 2012 00:02
    atom1477
    Poziom 43  

    No tak. Stara płytka nie musi iść od razu do kosza.
    Póki co wyniki z przetwornika skaczą w pełnym zakresie 24bitów, więc wygląda to na błąd polegający na pomyleniu najmłodszego i najstarszego bajtu wyniku.

    0
  • #16 22 Cze 2012 14:09
    wados0
    Poziom 10  

    markosik20 napisał:
    atom1477 napisał:
    No w programie też może być jakiś błąd.
    Ale brak kondensatorów na zasilaniu musiałem przecież wytknąć :D


    W programie MUSI być błąd :) .... a brak kondensatorów to "grzech" :).
    Proponuję przed zaprojektowaniem nowej płytki pobawić się starą i spróbować uzyskać prawidłowe (powtarzalne) odczyty. Na dzień dobry obetnij 4 najmłodsze bity :) oraz sprawdź czy czujnik jest DOBRZE podpięty.


    Jestem teraz w pracy, ale co do bawienia się płytką, na pewno ustawienie czasu trwania prostokąta sygnału SCLKa ma znaczny wpływ na pomiary, potrafi wskazywać same zera albo wskazywać jakąś ustaloną wartość, często wartości podobne do 0x3FF, 0x7FFF.
    Są duże szanse na błąd w sofcie, staram się podać wyczerpujące info na temat projektu. :D

    Co do podłączenia płytki dodam sposób podłączenia i załączę kartę katalogową belki wieczorem.

    0
  • #17 22 Cze 2012 14:32
    markosik20
    Poziom 33  

    wados0 napisał:
    ... na pewno ustawienie czasu trwania prostokąta sygnału SCLKa ma znaczny wpływ na pomiary, potrafi wskazywać same zera albo wskazywać jakąś ustaloną wartość, często wartości podobne do 0x3FF, 0x7FFF.


    A założymy się że nie ma żadnego wypływu? :)
    Coś mi się wydaje że Ty cały czas "ciągniesz" dane z ADS'a bez wykonania kalibracji i czekania na koniec konwersji :)

    Sekwencja startowa

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #18 22 Cze 2012 16:50
    wados0
    Poziom 10  

    Do kolegi markosik:

    Zastosowałem się do Twojego przykładu i mam poniższy kod, rozdzieliłem funkcję od kalibracji i pomiaru i wprowadziłem takie zmiany

    Code:

    /*
     * adc.cpp
     *
     *  Created on: 17-02-2012
     *      Author: Robert Wadowski
     */

    #include "global.h"

    spi_buffer_t spi_buffer;

    #define SCLK_HIGH   GPIO_SetBits(SPI_PORT,SCLK)
    #define SCLK_LOW   GPIO_ResetBits(SPI_PORT,SCLK)
    #define DOUT_STATE   GPIO_ReadInputDataBit(SPI_PORT,MISO)

    void adcCalibration(void);

    int adcInit(void)
    {
       GPIO_InitTypeDef   GPIO_InitStructure;
       
       /* CS */
       GPIO_InitStructure.GPIO_Pin = CS;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(SPI_PORT, &GPIO_InitStructure);

         /* SCLK   */
         GPIO_InitStructure.GPIO_Pin = SCLK;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(SPI_PORT,&GPIO_InitStructure);

         /* MISO */
         GPIO_InitStructure.GPIO_Pin = MISO;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(SPI_PORT, &GPIO_InitStructure);

         /* MOSI */
       /*GPIO_InitStructure.GPIO_Pin = MOSI;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(SPI_PORT, &GPIO_InitStructure); */

       /*SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
         SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
         SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
         SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;     
         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
         SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_RxOnly;
         SPI_InitStructure.SPI_CRCPolynomial = 7;
         SPI_Init(SPI1,&SPI_InitStructure);

         SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_RXNE,ENABLE);
       SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_TXE | SPI_I2S_IT_ERR,DISABLE);
        */

         /* GAIN0 */
         GPIO_InitStructure.GPIO_Pin = GAIN0;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(SPI_PORT,&GPIO_InitStructure);

         /* GAIN1   */
         GPIO_InitStructure.GPIO_Pin = GAIN1;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(SPI_PORT,&GPIO_InitStructure);

         /* SPEED   */
         GPIO_InitStructure.GPIO_Pin = SPEED;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(SPI_PORT,&GPIO_InitStructure);

    //   GPIO_ResetBits(SPI_PORT,CS);   
       GPIO_SetBits(SPI_PORT,GAIN0);   
       GPIO_SetBits(SPI_PORT,GAIN1);   
       GPIO_ResetBits(SPI_PORT,SPEED);   

       //delay_ms(30*1000);

       GPIO_SetBits(SPI_PORT,CS);   
       SCLK_LOW;
       debug_info("Calibration start\r\n");
       while(DOUT_STATE == 1) {};
       debug_info("Calibration end\r\n");

       adcCalibration();
          
       return 0;
    }

    int adcStartMeasurement(void)
    {
       SCLK_LOW;
       return 0;
    }

    /*int32_t adcNoInterrupt(void)
    {
       int32_t       data = 0;
       uint32_t      tmp = 0;
       uint32_t      neg = 0;
       uint8_t         i = 0;
       uint8_t         sign = 0;
       
       //while(DOUT_STATE != 0);
       
       if(DOUT_STATE == 0)
          {                   
             SCLK_LOW;
             delay_ms(1);
             for(i = 0; i < 24; i++)
                {
                   SCLK_HIGH;
                   delay_ms(1);
                   if(DOUT_STATE == 1) {
                         tmp |= (1<<(23-i));
                         if(i == 0) {
                            sign = 1;   
                         }
                      }                              
                   SCLK_LOW;
                   delay_ms(1);
                }
             SCLK_HIGH;
             delay_ms(1);
             SCLK_LOW;
                
             //if((tmp & (1<<23)) == (1<<23)) {
             if(sign == 1) {
                   //tmp = tmp & 0x7FFFFFFF;
                   debug_msg("Changing sign data = %x\r\n", tmp);                     
                   for(i = 0; i < 24; i++) {
                      if((tmp & (1<<i)) == (1<<i)) {
                         neg &= ~(1<<i);
                      } else {
                         neg |= (1<<i);
                      }
                   }
                   debug_msg("Changing sign negation = %x \r\n", neg);
                   debug_msg("Changing sign cutting = %x \r\n", neg & 0x00FFFFFF);
                   debug_msg("Changing sign jedynka = %x \r\n", (neg & 0x00FFFFFF) + 1);

                   data = (int32_t) (neg & 0x00FFFFFF) + 1;
                } else {                             
                   data = (int32_t) tmp;
                }
          }   
       debug_msg("Adc pomiar = %i \r\n", data);                        
       return data;
    } */


    void adcCalibration(void)
    {
       int32_t data = 0;
       uint8_t i = 0;

       for(i = 0;i < 24; i++)
       {
          SCLK_HIGH;
          if(DOUT_STATE == 1)data |= 0x01;
          if(i<24)data<<=1;
          SCLK_LOW;
     
       }
     
       SCLK_HIGH;
       SCLK_LOW;
       //calibration
       SCLK_HIGH;
       SCLK_LOW;
       SCLK_HIGH;
       SCLK_LOW;
    }


    int16_t adcNoInterrupt(void)
    {
       int32_t data = 0;
       uint8_t i = 0;

       for(i = 0;i < 24; i++)
       {
          SCLK_HIGH;
          if(DOUT_STATE == 1) data |= 0x01;
          if(i<24) data<<=1;
          SCLK_LOW;   
       }
     
       SCLK_HIGH;
       SCLK_LOW;
       debug_msg("Adc pomiar = %i \r\n",(int16_t) data >> 8);                        
       return (int16_t) data>>8;
    }


    reszta plików bez zmian (oczywiście w pliku ads1234.h zmieniłem prototyp funkcji od pomiaru). W załączniku przedstawiam zrzut pomiaru - na pewno nie lata, przyjmuje wartości -1 lub 0 (może wychodzi po za zakres pomiaru).

    Dokumentacja belki poniżej, belkę zasilam 5V.
    Podłączenie belki wydaje mi się dobre exc+ do vdd, exc- gnd, sig+ do AINP, sig- AINN

    Podłączenie belki:
    pin 1: czarny
    pin 2: biały
    pin 3: zielony
    pin 4: czerwony

    Proszę o umieszczenie kodu, w znacznikach SYNTAX.
    [zumek]

    0
  • #19 22 Cze 2012 17:13
    markosik20
    Poziom 33  

    A w którym momencie odczytujesz dane z ADS'a?
    Wklejaj kod za pomocą "SYTNAX'u" bo strasznie się ten post długi robi :)

    Twoja kalibracja jest zła. Musisz poczekać na DOUT, dobrze by było mieć jeszcze sterowanie pinem PWDN :)

    Kod: c
    Zaloguj się, aby zobaczyć kod


    jak po 30sekundach "nie wstanie" znaczy że coś z zasilaniem jest nie tak

    0
  • #20 22 Cze 2012 18:52
    wados0
    Poziom 10  

    A nóżkę PWDN opuszczałem przed funkcją wraz SCLKa, ale, żeby nie było pierdzielnika (za dużego ;)) w kodzie przeniosłem do funkcji. W każdym razie dostaje same zera nadal, chyba czas wziąć się za rysowanie nowej płytki :/.

    Kod: c
    Zaloguj się, aby zobaczyć kod



    Dane odczytuję względem tej pętli. Narazie są delaye, ten delay_ms(900) to tylko do debugowania, a ten 110 ms ma zostać ponieważ z tego co wyczytałem w dokumentacji adsa bo mniej więcej co tyle chcę odczytywać dane.

    Może ta moje funkcja adsStartMeasurement() (ona tylko wyłącznie opuszcza nóżke SCLK na dół) coś miesza ?

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #21 22 Cze 2012 19:04
    markosik20
    Poziom 33  

    wados0 napisał:
    W każdym razie dostaje same zera nadal, chyba czas wziąć się za rysowanie nowej płytki :/.


    Uparty jesteś.. ale nie w tę stronę :). Odpal najpierw to co masz bo powielisz błędy na nowej płytce.

    PWDN_LOW ma włączyć.. nie wyłączyć :)
    U mnie PWDN_OFF oznacza wyłączenie trybu POWER_DOWN.

    0
  • #22 22 Cze 2012 19:12
    wados0
    Poziom 10  

    Fakt był błąd, bo wyłączyłem ads1234, ale po poprawce wynik ten sam. Chyba czegoś nie do końca rozumiem.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #23 22 Cze 2012 19:27
    markosik20
    Poziom 33  

    A co tu rozumieć :)
    Masz tutaj wyraźny przebieg, jak nie pojawi się DataReady to nie ma sensu robić cokolwiek dalej z ADS'em.
    STM32F0 ADS1234 pomiar z belki tensometrycznej

    Swoją drogą to dziwne że masz cały czas odczyty "0", powinno być generalnie na odwrót przy wyłączonym ADS.

    0
  • #24 22 Cze 2012 19:45
    wados0
    Poziom 10  

    No tak dodałem nawet pętlę while przed każdym pomiarem, wiec nie ma opcji żeby nie czekał układ na adsa - czeka aż ads ustawi DOUT w stanie niskim.
    Może jakoś belkę uszkodziłem albo adsa czy co. Jak na tą chwilę to chyba tor jest zwalony jak kolega atom zasugerował tj. jego schemat.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #25 26 Cze 2012 20:20
    wados0
    Poziom 10  

    Witam

    Chcąc niechcąc wziąłem się za kolejne podejście do płytki, ale tym razem zanim zacznę się brać za jej robienie chciałbym usłyszeć Wasze opinie. Dodatkowo mam pare pytań :
    1. Ten monolityczny kondensator 4,7 uF to szukałem w dokumentacji stm32 i nie znalazłem miejsca mówiącego do którego pina podłączyć. Była informacja tylko o 100 nF i jednym 10 uF, można wiedzieć gdzie można znaleźć tą informację ?
    2. Jak się zajrzy na tą płytkę w obecnej wersji idąc za radą atoma starałem się jak najmniej dawać ścieżek na bottomie, czy przy ads1234 mogą być takie jak na płytce, co prawda jeszcze postaram się pozbyć tych przelotek bo chyba się da prowadząc odpowiednio ścieżki ?
    3. Czy można prowadzić ścieżki z zasilaniem czy jakiekolwiek pod ads1234 ?

    W załącznikach jest projekt i widoki płytek. Będę wdzięczny jeśli ktoś to sprawdzi i ewentualnie wypunktuje mi moje błędy albo da jakieś wskazówki.

    Pozdrawiam,
    Robert

    0
  • #26 26 Cze 2012 21:05
    atom1477
    Poziom 43  

    wados0 napisał:
    Chcąc niechcąc wziąłem się za kolejne podejście do płytki, ale tym razem zanim zacznę się brać za jej robienie chciałbym usłyszeć Wasze opinie.

    Ja bym jednak radził najpierw przetestować ten układ co masz. Bo jakoś to jednak powinien działać. Tzn. dawać chociaż ze 4...8 stabilnych bitów z ADC.

    wados0 napisał:
    1. Ten monolityczny kondensator 4,7 uF to szukałem w dokumentacji stm32 i nie znalazłem miejsca mówiącego do którego pina podłączyć. Była informacja tylko o 100 nF i jednym 10 uF, można wiedzieć gdzie można znaleźć tą informację ?

    Jak byk pisze żeby podłączyć do VDD3 :D
    STM32F0 ADS1234 pomiar z belki tensometrycznej


    wados0 napisał:
    2. Jak się zajrzy na tą płytkę w obecnej wersji idąc za radą atoma starałem się jak najmniej dawać ścieżek na bottomie, czy przy ads1234 mogą być takie jak na płytce, co prawda jeszcze postaram się pozbyć tych przelotek bo chyba się da prowadząc odpowiednio ścieżki ?

    No na pewno można jeszcze usunąć przelotki z tych ścieżek które w ogóle ich nie wymagają. :D Bo widzę że co najmniej kilka ścieżek przechodzi przez przelotkę zupełnie po nic, bo idzie później z 1...2cm nie krzyżując się z żadną inną ścieżką i trafia do punktu docelowego już drugą warstwą. A mogła by iść aż do samego końca poprzednią warstwą.


    wados0 napisał:
    2. Jak się zajrzy na tą płytkę w obecnej wersji idąc za radą atoma starałem się jak najmniej dawać ścieżek na bottomie, czy przy ads1234 mogą być takie jak na płytce, co prawda jeszcze postaram się pozbyć tych przelotek bo chyba się da prowadząc odpowiednio ścieżki ?
    3. Czy można prowadzić ścieżki z zasilaniem czy jakiekolwiek pod ads1234 ?

    W sumie pod ADC1234 puszczanie jakichś ścieżek może być minimalnie niepożądane (na warstwie top, czyli w bezpośredniej bliskości układu), ale myślę że i tak niewiele to przeszkadza.
    Więc puszczaj spokojnie.
    Ale tak jak już pisałem to najpierw zajął bym się naprawą programu.

    0
  • #27 26 Cze 2012 21:38
    wados0
    Poziom 10  

    Hmmm co do programu to nie bardzo wiem w którą stronę iść bo sekwencja odczytu jest taka sama (a co mnie najbardziej przeraża wydaje się być prosta)- wzorowałem się na przykładzie markosika i jakoś nie mam pojęcia co robię źle. Dałem pętlę while czekającą aż ads1234 opuści Dout na stan niski i faktycznie pomiar się odbywa bo ads1234 wprowadza Dout w stan niski. Jedyny sposób w jaki mogę wpłynąć na podczas pomiaru to wysyłanie SCLK, ale to mam jak u markosika (albo tak mi się tylko wydaje). Mam rozumieć, że piszesz o najwyższych 4-8 bitach ? Na dziś dam sobie spokój z programem, ale jutro spróbuję po prostu napisać od nowa te funkcje, być może gdzieś coś za dużo namieszałem albo czegoś nie dopisałem, chociaż tyle już na to patrzyłem, że mogę i o północy recytować sekwencję odczytu. Ale póki co to maszyna ze mną nie wygra :D.

    PS. Mikrontroler to STM32F103C6T6 i datasheeta brałem z kamami.pl - tam gdzie kupowałem kontrolera i nie ma tam tych 4,7uF a 10 uF. Zdaje się, że skopałem temat postu i wprowadziłem Was w błąd bo zapewne myśleliście o STM32F100....

    0
  • #28 27 Cze 2012 18:42
    wados0
    Poziom 10  

    Witam

    Dzisiaj spróbowałem przepisać kod od nowa i wynik niestety ten sam (tak jak w załączniku). Napisałem funkcje wzorując się na przykładach markosika z tą różnicą, że program dalej nie pójdzie jeśli kalibaracja adsa się nie zakończy.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    A plik h wygląda teraz tak

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Wydaje mi się, że ten kod działa tak samo jak u markosika, niemniej jednak wartości są takie jak na zrzucie z terminala "pomiar3.jpg", jak daję delaye 1 ms to coś widać na terminalu ("pomiar4.jpg"), czy to może oznaczać problem z odczytem uC <- ads1234 ?

    Kod: c
    Zaloguj się, aby zobaczyć kod

    STM32F0 ADS1234 pomiar z belki tensometrycznej STM32F0 ADS1234 pomiar z belki tensometrycznej

    0
    Załączniki:
  • #29 29 Cze 2012 16:49
    wados0
    Poziom 10  

    Witam,
    Poprawiłem płytkę, usunąłem zbędne przelotki, ale ścieżki biegną pod adsem, co jest lepsze ścieżki pod ads czy dodatkowe przelotki ?
    Po za tym mam zasilanie dla adsa 5V i 10V, chciałbym jedne wyrzucić, które jest lepsze ?

    0
  • #30 05 Lip 2012 16:44
    markosik20
    Poziom 33  

    Max napięcia dla ADS1234 to 5V, nie wiem skąd u Ciebie 10V :)
    To

    Code:
    delay_ms(1);
    u Ciebie to na pewno jest 1ms ?

    0
  Szukaj w 5mln produktów