Konstigt beteende på program.

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Konstigt beteende på program.

Inlägg av newbadboy »

Har skrivit koden för ett billarm. Den har en acceleroemeter (ADXL345) som jag initierar för single tap och som känner av en smäll mot bilen. Kretsen känner av batterispänningen för att aktivera/ deaktivera. Larmet.

Jag har eg två problem jag kämpat med som jag inte kommer vidare med och behöver tips.

1 Det finns en utgång (INT1) på ADXL345 kretsen som går hög vid rörelse. Detta skall då kännas av med en IO och då skickas det jag kallar sms1, "inbrott".
Det underliga är att varje gång denna pinne går hög så startar programmet om och går in i Init_Main() och kör allt från början. det verkar alltså som om kretsen startar om. Det finns i nuläget inget som tyder på att det är hårdvaran som hittar på ngt men jag kan inte hitta ngt annat fel heller. Varje gång denna omstart sker så skickar kortet mig det jag kallar sms0, dvs att larmet är startat. Matningen och reset pinnen är stabil när detta sker.

2 Varje gång Int1 pinnen på ADXL345 går hög måste den nollställas manuellt. För detta skickar jag några i2c kommandon. Jag märker dock att om jag skickar dessa reset kommandon i funktionen ADXL_Init() så verkar inte i2c funka bra alls. Kollat med logik analysator så skickar jag endast det första kommandot där jag frågar efter device id, sedan är det helt tyst på bussen och det verkar då hänga sig. Skickar jag inte resett kommandot så kan jag sniffa ut på bussen det jag exakt skickat och jag läser även ut varje register så att det verkligen är ok, och allt stämmer så länge jag inte skickar resett.
På flera ställen behöver jag nollställa Int1 genom att skicka samma kommande och då hänger sig också programmet. Därför är allt som har med reset att göra bortkommenterat just nu.




https://www.analog.com/media/en/technic ... dxl345.pdf

Kod: Markera allt

#define LED_RFstat PORTD.F6
#define LED_Stat   PORTD.F7
#define RF_EN      PORTD.F1
#define CAN_stby   PORTB.F4
#define Vbat_adc   PORTA.F1
#define SDO        PORTE.F2
#define SIM800_rst PORTD.F0
#define Int1       PORTE.F0


char AT[]="AT";   // To initialize mode
char noecho[]="ATE0";   // To stop echo
char mode_text[]="AT+CMGF=1";   // to set text mode
char char_mode[]="AT+CSCS=\"GSM\"";   // to set character mode
char param[]="AT+CSMP=17,167,0,0";   // set the parameter of character
char mobile_no[]="AT+CMGS=\"+46723970467\"";   //use to set receinpent number and mesg
char mobile_no1[]="AT+CMGS=\"+46xxxxxxxxxx\"";   //use to set receinpent number and mesg
char terminator=0x1A;     // chartacter form of control + z terminator character


int counter=0, l=0, b=0, j=0, y=0, i=0, m=0, Vbat, Int1Value, VbatOld, VbatCalc ;
long int k=0;
unsigned short DevID;

//Warning messages to be sent thru SMS
char mesg0[]="GSM Bil startad.";
char mesg1[]="!!!INBROTT!!! Billarm aktiverad!!";


//function to write anything serially.
void send_to_modem(char *s){
        while(*s)
            UART1_WRITE(*s++);
            UART1_WRITE(0X0D);
        }


void send_to_modem1(char *s){
        while(*s)
            UART1_WRITE(*s++);
        }


//Send different message
void send_sms(int b){
        if(b==0)
          send_to_modem1(mesg0);
        else if(b==1)
          send_to_modem1(mesg1);
        delay_ms(100);
        uart1_write(terminator);
        delay_ms(1000);
        }



void Send_GSM(){
     send_to_modem(AT);
     delay_ms(2000);
     send_to_modem(noecho);
     delay_ms(2000);
     send_to_modem(mode_text);
     delay_ms(2000);
     send_to_modem(mobile_no);
     delay_ms(2000);
     send_sms(b);
     }



void ADXL345_init(){

//Read out device id ocf the ADXL345 chip. By sniffing the I2C, the
//device id should be seen as 229
                I2C1_Start();
                I2C1_Wr(0xA6);
                I2C1_Wr(0x00);
                I2C1_Repeated_Start();
                I2C1_Wr(0xA7);
                DevID=I2C1_Rd(0);
                I2C1_Stop();

//Set power control to normal.
                I2C1_Start();
                I2C1_Wr(0xA6);
                I2C1_Wr(0x2D);
                I2C1_Wr(0x08);
                I2C1_Repeated_Start();
                I2C1_Wr(0xA7);
                DevID=I2C1_Rd(0);
                I2C1_Stop();

//Set tap axes. Use xyz axis
                I2C1_Start();
                I2C1_Wr(0xA6);
                I2C1_Wr(0x2A);
                I2C1_Wr(0x01);
                I2C1_Repeated_Start();
                I2C1_Wr(0xA7);
                DevID=I2C1_Rd(0);
                I2C1_Stop();

//Set threshold for single tap detection
                I2C1_Start();
                I2C1_Wr(0xA6);
                I2C1_Wr(0x1D);
                I2C1_Wr(40);
                I2C1_Repeated_Start();
                I2C1_Wr(0xA7);
                DevID=I2C1_Rd(0);
                I2C1_Stop();
                
//Set the duration for single tap detection
                I2C1_Start();
                I2C1_Wr(0xA6);
                I2C1_Wr(0x21);
                I2C1_Wr(32);  //625us/LSB
                I2C1_Repeated_Start();
                I2C1_Wr(0xA7);
                DevID=I2C1_Rd(0);
                I2C1_Stop();

//Set the latency for single tap detection, disable double tap
                I2C1_Start();
                I2C1_Wr(0xA6);
                I2C1_Wr(0x22);
                I2C1_Wr(80);
                I2C1_Repeated_Start();
                I2C1_Wr(0xA7);
                DevID=I2C1_Rd(0);
                I2C1_Stop();

//Map single tap interupt to INT1 pin
                I2C1_Start();
                I2C1_Wr(0xA6);
                I2C1_Wr(0x2F);
                I2C1_Wr(0x00);   //00000000
                I2C1_Repeated_Start();
                I2C1_Wr(0xA7);
                DevID=I2C1_Rd(0);
                I2C1_Stop();
                
//Enable INT1
                I2C1_Start();
                I2C1_Wr(0xA6);
                I2C1_Wr(0x2E);
                I2C1_Wr(0x40);   //01000000
                I2C1_Repeated_Start();
                I2C1_Wr(0xA7);
                DevID=I2C1_Rd(0);
                I2C1_Stop();

/*//Reset INT1 output if needed
                 I2C1_Start();
                 I2C1_Wr(0xA6);
                 I2C1_Wr(0x30);
                 I2C1_Repeated_Start();
                 I2C1_Wr(0xA7);
                 DevID=I2C1_Rd(0);
                 I2C1_Stop();
*/
}


//Led blink in normal mode
void Led(){
     k++;
     if(k==9000)
       LED_Stat=1;
     if(k==500)
       LED_Stat=0;
     if(k==12000)
        k=0;
     }



void Init_Main(){
    
     OSCCON=0b01110110; //Set 8MHz clock
     CMCON=0b00000111;
     
     TRISA=0b00000010;
     TRISB=0b00011000;
     TRISC=0b10000000;
     TRISD=0b00000000;
     TRISE=0b00000011;
     
     ADCON0.F0=1;
     ADCON1=0b00001001;
     ADCON2=0b00001000;
     
     SDO=0; // do not alter to avoid short circuit!!!!!
     
     UART1_Init(9600);
     I2C1_Init(100000);
     ADC_Init();

     
     for(l=0; l<11; l++){
     LED_Stat=1;
     LED_RFstat=1;
     Delay_ms(50);
     LED_Stat=0;
     LED_RFstat=0;
     Delay_ms(50);
     }
     
     ADXL345_init();
     
     //send start sms
     RF_EN=1;
     Delay_ms(100);
     SIM800_rst=1;
     LED_Stat=1;
     LED_RFstat=1;
     Delay_ms(30000);   //gsm net connect
   //  Send_GSM();       //send message 0
     Delay_ms(20000);
     SIM800_rst=0;
     Delay_ms(100);
     RF_EN=0;
     LED_Stat=0;
     LED_RFstat=0;
     }
     
void ADXL345_Reset(){
     I2C1_Start();
     I2C1_Wr(0xA6);
     I2C1_Wr(0x30);
     I2C1_Repeated_Start();
     I2C1_Wr(0xA7);
     DevID=I2C1_Rd(0);
     I2C1_Stop();
}

void Set_Trigger(){
      counter=0;
      Int1Value=ADC_Read(5);
      if(Int1Value>511){ //2,5V
         //Reset INT1 output
       //  ADXL345_Reset();
         m++;
         b=1;
      //Send SMS. Max twice to avoid many sms
      if(m<3){
         LED_Stat=1;
         LED_RFstat=1;
         RF_EN=1;
         Delay_ms(100);
         SIM800_rst=1;
         Delay_ms(35000);    //Gsm net search
         //  Send_GSM();
         Delay_ms(20000);
         SIM800_rst=0;
         Delay_ms(100);
         RF_EN=0;
         LED_Stat=0;
         LED_RFstat=0;
         
         }
      }
}

                  
void Read_Vbat(){

     Vbat=ADC_Read(1);
     if(Vbat>895){     //14V
     //engine started
     while(Vbat>895){
         Vbat=ADC_Read(1);
         LED_Stat=1;
         Delay_ms(100);
         LED_Stat=0;
         Delay_ms(100);
         }
         LED_Stat=0;
     while(j<375){        //Step out time ~5min
          j++;
          LED_Stat=1;
          Delay_ms(400);
          LED_Stat=0;
          Delay_ms(400);
          }
          j=0;
          //Reset INT1 output
       //   ADXL345_Reset();
          }

          VbatOld=Vbat;
          Vbat=ADC_Read(1);
          VbatCalc=VbatOld-Vbat;
          if(VbatCalc>62||Vbat<790){    //>300mv  <12.35V
            //doors opened
            //stay in loop for 5min or as long as Vbat>14V
            while((j<700)||(Vbat>895)){
                 LED_Stat=1;
                 Delay_ms(100);
                 LED_Stat=0;
                 Delay_ms(100);
                 j++;
                 }
            //Reset INT1 output
           // ADXL345_Reset();
            j=0;
           }
}

void main(){
    
    Init_main();
     
     while(1){
          Led();
          Read_Vbat();
          Set_Trigger();
          }
} :( 
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
TheUnreal
Inlägg: 115
Blev medlem: 4 september 2005, 16:04:57
Ort: Sundsvall
Kontakt:

Re: Konstigt beteende på program.

Inlägg av TheUnreal »

Int för interupt?

Var har du din funktion för att hantera interuptrutinen?
Användarvisningsbild
Wedge
Inlägg: 1026
Blev medlem: 8 juli 2012, 17:33:33

Re: Konstigt beteende på program.

Inlägg av Wedge »

SIM-modulen drar en helsikes massa ström (uppemot 2A) under nån millisekund, inte omöjligt att den tar ned matningsspänningen kortvarigt så att processorn gör reset. Häng på några biffiga kondensatorer nära dess matning.
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Konstigt beteende på program.

Inlägg av newbadboy »

TheUnreal skrev:Int för interupt?

Var har du din funktion för att hantera interuptrutinen?
pinnen heter alltså int men går i princip bara hög tills jag resettar den via I2C. så jag har ingen interupthantering. Bara läser den som en vanlig ingång på Pic'en

pinnen är alltså utgång från accelerometern och ingång på mcu
Senast redigerad av newbadboy 26 februari 2019, 15:08:38, redigerad totalt 1 gång.
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Konstigt beteende på program.

Inlägg av newbadboy »

Wedge skrev:SIM-modulen drar en helsikes massa ström (uppemot 2A) under nån millisekund, inte omöjligt att den tar ned matningsspänningen kortvarigt så att processorn gör reset. Häng på några biffiga kondensatorer nära dess matning.

Jepp det är kollat med ocsilloscope. Samt även förstärkt med extra cappar.

Sedan måste jag upprepa att den skickar det första sms't som vanligt. Den som finns i Init_main. Så därför bör det fallera och starta om sig redan där ifall det är matningen som är svag.
Användarvisningsbild
Klas-Kenny
Inlägg: 11292
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Konstigt beteende på program.

Inlägg av Klas-Kenny »

Har inget med problemet att göra, men varför läser du int-signalen analogt? :humm:
Sätt pinnen digitalt och läs den direkt istället..

I koden du postar har du kommenterat bort själva sändningen av meddelandet, resettar processorn då också?
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Konstigt beteende på program.

Inlägg av newbadboy »

Jag läser den analogt för att jag är så jävla dum.

Tänkte inte på att accellerometern jobbar med 3.3V och mcun med 5V. Satte en nivåskiftare på på i2c men glömde de andra pinnarna. Sen är just den pinnen på mcun en cmos ingång och inte TTL.

och ja, programmet resettar även med send gsm bortkommenterat. Mest att jag vill spara pengarna på kontantkortet
TheUnreal
Inlägg: 115
Blev medlem: 4 september 2005, 16:04:57
Ort: Sundsvall
Kontakt:

Re: Konstigt beteende på program.

Inlägg av TheUnreal »

Men med en interuptrutin kan du verifiera att det inte är det som händer, eller hantera på ett kontrollerat sätt i stället för att hamna i odefinierat läge ;)
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Konstigt beteende på program.

Inlägg av newbadboy »

Det verkar nu onekligen som om hela hänger ihop med just i2c skrivningen.

När jag först initierar accellerometern så verkar programmet lira så länge alla andra skrivningar till kretsen är borta. Dock triggar ju kretsen hela tiden efter en stöt eftersom jag inte nollställer INT1 pinnen.

Sålänge jag har i2c skrivningar på fler ställen än just init_main så verkar det ge upphov till både omstart och hängning. Det verkar bara balla ur.




Ser inte riktigt hur en interupt skulle kunna bota detta i nuläget.
Mr Andersson
Inlägg: 1394
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Konstigt beteende på program.

Inlägg av Mr Andersson »

Verifiera att du kör open drain på i2c-pinnarna och att adc:n inte håller datalinan låg. Om de drar åt olika håll kan du lätt få problem.
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Konstigt beteende på program.

Inlägg av newbadboy »

Är inte helt säker på hur detta görs faktiskt, men jag kan se via logikanalysatorn att när jag knackar på sensorn och skickar reset till den så kommer precis bara den och inget annat de gångerna det funkar som det skall.
När programmet startar om sig ser jag inte ens att jag skickat reset till sensorn utan att den direkt börjar printa ut datat som står i Init_Main.

knackar jag 10 ggr på sensorn så funkar det bra 8-9ggr.

Börjar kännas helt uppgivet
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4689
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: Konstigt beteende på program.

Inlägg av Swech »

Du har troligtvis problem med ACK / NACK I2C
Sista byte som du läser skall avslutas med NACK, annars tror enheten att du vill läsa fler bytes

Swech
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Konstigt beteende på program.

Inlägg av newbadboy »

Finns det ngt sätt att testa denna tesen? Typ skicka ngn extra data eller ngt.

Är första gången jag pillar på i2c.
Användarvisningsbild
Icecap
Inlägg: 26106
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Konstigt beteende på program.

Inlägg av Icecap »

Läs databladet för sensorn! Där står det.
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4689
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: Konstigt beteende på program.

Inlägg av Swech »

Det är inte lätt att hitta om man inte vet exakt vad man letar efter.
Börja kika på generella I2C beskrivningar
Där är ACK / NACK beskrivet
Alltså typ Wiki , inte i ditt datablad eftersom det var dåligt/ inte alls beskrivet där

Swech
Skriv svar