Re: Konstigt beteende på program.
Postat: 14 mars 2019, 12:57:04
Hur menar du att det var kopplat innan då? Och nu?
Svenskt forum för elektroniksnack.
https://elektronikforumet.com/forum/
Kod: Markera allt
//Rev Hist
//R2.1 New mcu 16F1937
//R2.2 Comparator module used for fast reading
#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=\"+467xxxxxxxxx\""; //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 l=0, b=0, j=0, m=0, n=0, k, i=0, Vbat, Int1Value, prioCount;
unsigned short DevID;
//Warning messages to be sent thru SMS
char mesg0[]="GSM Bil OK Rev2.2";
char mesg1[]="!!**INBROTT i Bilen**!!";
char mesg2[]="Svagt bilbatteri";
//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);
else if(b==2)
send_to_modem1(mesg2);
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);
}
//Reset commands to reset adxl345 output
void ADXL345_Reset(){
I2C1_Start();
I2C1_Wr(0xA6);
I2C1_Wr(0x30);
I2C1_Repeated_Start();
I2C1_Wr(0xA7);
DevID=I2C1_Rd(0);
I2C1_Stop();
}
//ADX345 setup
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(5); //(40) iinnan
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(0);
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
ADXL345_Reset();
}
void Init_Main(){
//Set 16MHz clock 0b01110110
OSCCON=0b01111000;
TRISA=0b00000011;
TRISB=0b00011000;
TRISC=0b10000000;
TRISD=0b00000000;
TRISE=0b00000011;
ANSELA=0b00000011;
ANSELB=0b00000000;
ANSELD=0b00000000;
ANSELE=0b00000001;
//Do not alter SDO to avoid short circuit!!!!!
SDO=0;
//DAC setup and connect to comparator
DACCON0=0b11000000;
DACCON1=0b00011001; // below ~3.8V at voltage divider
//Comparator setup
CM1CON0=0b10010110;
CM1CON1=0b01010000;
UART1_Init(9600);
I2C1_Init(100000);
ADC_Init();
for(l=0; l<7; l++){
LED_Stat=1;
LED_RFstat=1;
Delay_ms(50);
LED_Stat=0;
LED_RFstat=0;
Delay_ms(50);
}
LED_Stat=0;
LED_RFstat=0;
ADXL345_Init();
//Send startupSMS and set b=1 for sms2
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); //Time to send sms
SIM800_rst=0;
Delay_ms(100);
RF_EN=0;
LED_Stat=0;
LED_RFstat=0;
b=1;
Delay_ms(1000);
// enable interrupts & reset adxl
ADXL345_Reset();
}
void Read_ADXL345(){
Int1Value=ADC_Read(5);
if(Int1Value>511){ //2,5V
//Send SMS. Max 1 time
ADXL345_Reset();
if(m<1){
Delay_ms(10);
m++;
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(1000);
Send_GSM();
Delay_ms(20000);
}
SIM800_rst=0;
Delay_ms(100);
RF_EN=0;
LED_RFstat=0;
ADXL345_Reset();
}
}
void Read_Vbat_ADC(){
Vbat=ADC_Read(1);
if(Vbat>831){ //14-0,7V
Delay_ms(3000);
//engine started
while(Vbat>831 ){
Vbat=ADC_Read(1);
LED_Stat=1;
Delay_ms(100);
LED_Stat=0;
Delay_ms(100);
m=0;
n=0;
}
while(j<800){ //Step out time ~5min
j++;
LED_Stat=1;
Delay_ms(400);
LED_Stat=0;
Delay_ms(400);
}
j=0;
ADXL345_Reset();
//Send sms, low battery
Vbat=ADC_Read(1);
if(Vbat<671){ //<11.5V-0,7
Delay_ms(10000);
Vbat=ADC_Read(1);
if((Vbat<671)&&(n==0)){
n++;
b=2;
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); //Time to send sms
SIM800_rst=0;
Delay_ms(100);
RF_EN=0;
LED_Stat=0;
LED_RFstat=0;
b=1;
}
ADXL345_Reset();
}
}
}
void Read_Vbat_COMP(){
if(CM1CON0.C1OUT==0){
for(i=0; i<800; i++){
LED_Stat=1;
Delay_ms(400);
LED_Stat=0;
Delay_ms(400);
}
}
}
void main(){
Init_main();
while(1){
prioCount++;
Read_Vbat_COMP();
if(prioCount==10000){
Read_Vbat_ADC();
Read_ADXL345();
prioCount=0;
LED_Stat=1;
}
}
}
Kod: Markera allt
//Rev Hist
//R2.1 New mcu 16F1937
//R2.2 Comparator module used for fast reading. Use with PCBcad rev 1.2
//R_debug. Use only to debug restart issue
#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
#include <stdint.h>
//Gsm modem setup data
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
// Vbat is reading from battery voltage
// Int1Value is adc reading from the output of accelerometer
// prioCount is used to set prio in main. Read comparator value every cycle
// but other instructions is done 1/10000
// DevID is used to read back i2c registers from accelerometer and to be able to sniff with analyzer
// Sometimes chip restarts when reset i2c is sent to ADXL. If restart occurs correct sms can still be sent
int l=0, b=0, j=0, m=0, n=0, k, i=0, Vbat, Int1Value, prioCount;
unsigned short DevID, Restart_Flag;
unsigned int mStatus = 0;
unsigned int mPCON = 0;
char ut1[15];
char ut2[15];
//Warning messages to be sent thru SMS
char mesg0[]="GSM Bil OK Rev2.2";
char mesg1[]="!!**INBROTT i Bilen**!!";
char mesg2[]="Svagt bilbatteri";
//function to write anything serially.
void send_to_modem(char *s){
while(*s)
UART1_WRITE(*s++);
UART1_WRITE(0X0D);
}
void send_nibble(uint8_t x)
{
if (x >= 10) x += 7;
UART1_WRITE(0x30+x);
}
void send_hex_byte(uint8_t y)
{
send_nibble(y >> 4);
send_nibble(y & 0xF);
}
void send_to_modem1(char *s){
while(*s)
UART1_WRITE(*s++);
}
//Send different message. Int b is set to proper values by software depending of state
void send_sms(int b){
if(b==0)
//send_to_modem1(mStatus);
send_hex_byte(mStatus);
send_hex_byte(mPcon);
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);
}
//Reset commands to reset adxl345 output. Need to be sent everytime
//accelerometer is trigged to reset output
void ADXL345_Reset(){
I2C1_Start();
I2C1_Wr(0xA6);
I2C1_Wr(0x30);
I2C1_Repeated_Start();
I2C1_Wr(0xA7);
DevID=I2C1_Rd(0);
I2C1_Stop();
}
//ADX345 setup
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(5); //Can be set 0-255. Set to low value to trigger
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(5); //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(0);
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
ADXL345_Reset();
}
void Init_Main(){
//Set 16MHz clock 0b01110110
OSCCON=0b01111000;
TRISA=0b00000011;
TRISB=0b00011000;
TRISC=0b10000000;
TRISD=0b00000000;
TRISE=0b00000011;
ANSELA=0b00000011;
ANSELB=0b00000000;
ANSELD=0b00000000;
ANSELE=0b00000001;
//Do not alter SDO to avoid short circuit!!!!!
SDO=0;
//DAC setup and connect to comparator
DACCON0=0b11000000;
DACCON1=0b00011001; // below ~3.8V at voltage divider
//Comparator setup
CM1CON0=0b10010110;
CM1CON1=0b01010000;
UART1_Init(9600);
I2C1_Init(100000);
ADC_Init();
for(l=0; l<4; l++){
LED_Stat=1;
LED_RFstat=1;
Delay_ms(50);
LED_Stat=0;
LED_RFstat=0;
Delay_ms(50);
}
LED_Stat=0;
LED_RFstat=0;
ADXL345_Init();
//Monitors if mcu has restarted due to i2c crash or not
Restart_Flag=EEPROM_Read(0x00);
if(Restart_Flag!=1)
b=0;
else if(Restart_Flag==1){
b=1;
m=2;
}
mStatus = STATUS;
mPcon = PCON;
send_hex_byte(mStatus);
send_hex_byte(mPcon);
//Send startupSMS and set b=1 for sms2
LED_Stat=1;
LED_RFstat=1;
RF_EN=1;
Delay_ms(100);
SIM800_rst=1;
Delay_ms(35000); //Gsm net search
b=0;
Send_GSM();
Delay_ms(1000);
b=1; //Send twice if restart has occured
Send_GSM();
Delay_ms(20000); //Time to send sms
SIM800_rst=0;
Delay_ms(100);
RF_EN=0;
LED_Stat=0;
LED_RFstat=0;
b=1;
Delay_ms(1000);
ADXL345_Reset();
}
//Read the int1Value from accelerometer. If triggered (1), (above 2,5V)
//send 2 sms. Before actually sending sms controll that engine is not started
//This because auto start/stop in new cars
//Int m is used to make sure to not send several sms. Int m is reset
//when engine is started
void Read_ADXL345(){
Int1Value=ADC_Read(5);
if(Int1Value>511){ //2,5V.
EEPROM_Write(0x00,1); //Set restart flag to be used if restart occurs
//Send SMS.Once
ADXL345_Reset();
if(m<1){
Delay_ms(10);
m++;
LED_Stat=1;
LED_RFstat=1;
RF_EN=1;
Delay_ms(100);
SIM800_rst=1;
Delay_ms(20000); //Gsm net search. Average connection time is 12,6s for gsm module
Vbat=ADC_Read(1);
/* if(Vbat<825){ //Car started or not?
Send_GSM();
Delay_ms(1000);
Send_GSM();
Delay_ms(20000);
} */
}
SIM800_rst=0;
Delay_ms(100);
RF_EN=0;
LED_RFstat=0;
ADXL345_Reset();
}
}
//When Vbat is above 14V engine is started and alarm is disabled. After
//engine is stopped a step out time of ~10min is enabled.
//Before alarm enters guard mode the battery voltage is checked and low bat sms
//is sent if it's below 14-0.7V. 0.7V is forvard voltage drop of a serial diode
void Read_Vbat_ADC(){
Vbat=ADC_Read(1);
if(Vbat>831){ //14-0,7V
Delay_ms(3000);
//engine started
while(Vbat>831){
Vbat=ADC_Read(1);
LED_Stat=1;
Delay_ms(100);
LED_Stat=0;
Delay_ms(100);
m=0;
n=0;
}
while(j<10){ //Step out time ~10min
j++;
LED_Stat=1;
Delay_ms(400);
LED_Stat=0;
Delay_ms(400);
}
j=0;
EEPROM_Write(0x00,0); //Reset restart_flag
ADXL345_Reset();
//Send sms, low battery
Vbat=ADC_Read(1);
if(Vbat<671){ //<11.5V-0,7
Delay_ms(10000);
Vbat=ADC_Read(1);
if((Vbat<671)&&(n==0)){
n++;
b=2;
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); //Time to send sms
SIM800_rst=0;
Delay_ms(100);
RF_EN=0;
LED_Stat=0;
LED_RFstat=0;
b=1;
}
ADXL345_Reset();
}
}
}
//comparator voltage output is read by reading the flag below.
//alarm is not active until engine has been started and stopped once
void Read_Vbat_COMP(){
if(CM1CON0.C1OUT==0){
while(i<800){
LED_Stat=1;
Delay_ms(400);
LED_Stat=0;
Delay_ms(400);
}
ADXL345_Reset();
}
}
void main(){
Init_main();
while(1){
prioCount++;
Read_Vbat_COMP();
if(prioCount==10000){
Read_Vbat_ADC();
Read_ADXL345();
prioCount=0;
LED_Stat=1;
}
}
}