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();
}
} :(