I wrote a code that interacts with my car can data.
I wish to put the Arduino to sleep when the car if off and no data is transmitted (I need to read information on the bus before the car starts, so I most use the constant 12v to run the Arduino).
I can use the CAN.onReceive(function_name) for waking up the CPU form it sleep mode, but I could not find how to stop the interrupt and allow my normal code to handle the can communication.
I tried CAN.onReceive(null); but it would not compile. CAN.onReceive(0) would connect the setup to the interrupt.
How should this be done?
#include <CAN.h>
#include <Arduino.h>
#include <avr/sleep.h>
void setup() {
Serial.begin(9600);
if (!CAN.begin(1000E3)) {
Serial.println("Starting CAN failed!");
Serial.println("Stoping the program!!");
while (1);
}
Serial.println("CAN connected");
}
long time = millis();
void loop() {
int packetSize = CAN.parsePacket(); // looks for a package
if (packetSize) { // received a packet
time = millis();
// analyze the can command
}
if (millis()- time >=3000) {
Serial.println(" going to sleep");
sleep_enable();//Enabling sleep mode
set_sleep_mode(SLEEP_MODE_PWR_DOWN);//Setting the sleep mode.
CAN.onReceive(wakeUp);
CAN.sleep();
delay(100);
sleep_cpu(); //activating sleep mode
Serial.println("just woke up!"); //next line of code executed after the interrupt
time = millis();
}
}
void wakeUp(){
Serial.println("Interrrupt Fired");//Print message to serial monitor
sleep_disable();//Disable sleep mode
CAN.wakeup();
CAN.onReceive(null); //<<<< Does not work
}
You need to be careful of your "power off" current draw, a few mills will kill the battery in short order. Not sure today but one of the requirements was that the car was parked at the airport for two weeks and the the customer expected to get in it and drive it away.
Is it a real uno? How about posting a link to the MCP2515 showing "Technical data" I have several MPC2515 modules and they are different. Which CAN library, there are many? Adding aschematic would help, a frizzy picture would be useless.
hey @ZoharML did u find the solution ? and do someone tell me how CAN.onRecieve() function works ?, is it work as a thread ? i m having repeated output from CAN on my esp can reciever .
Yes, I managed to put the board into sleep and wake from can commands.
It works fine inside my car on a dialy use.
I'ts all inside a big code, So I hope I managed to cut out all the needed code lines:
#include <CAN.h>
#include <avr/sleep.h> //controls the sleep modes
long last_pid_update= millis();
void setup() {
Serial.begin(9600);
if (!CAN.begin(1000E3)) {
Serial.println(F("Starting CAN failed!"));
Serial.println(F("Stoping the program!!"));
while (1);
}
Serial.println(F("CAN connected"));
last_pid_update=millis(); // allow sleep mode before first pid command
}
void loop() {
int packetSize = CAN.parsePacket(); // looks for a package
if (packetSize) { // received a packet
count++; // add one for the can command (when the car is off there are hardly any commands).
last_can_update= millis();
your code here...
}
if ((millis()-last_can_update) >=5*display_Update_time) { //long time with no can data => time to go to sleep
Serial.println(F("***__ going to sleep"));
delay(250); //wait a bit before the sleep
sleep_enable(); //Enabling sleep mode
set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Setting the sleep mode, in our case full sleep
CAN.end(); //diconnect from the can library (if not it will not work after the wake)
attachInterrupt(digitalPinToInterrupt(2), wakeUp, LOW); //attaching a interrupt to pin d2
delay(50); //wait a bit before the sleep
sleep_cpu(); //activating sleep mode
Serial.println(F("just woke up!")); //next line of code executed after the interrupt
last_can_update=millis(); // reset the timeout counter
}
}
void wakeUp(){ //jump here when can command comes in sleep
Serial.println(F("Interrrupt Fired")); //Print message to serial monitor
sleep_disable(); //Disable sleep mode
detachInterrupt(digitalPinToInterrupt(2)); //Removes the interrupt from pin 2;
delay (10);
if (!CAN.begin(1000E3)) { // reconnect the CAN
Serial.println(F("Starting CAN failed after sleep"));
Serial.println(F("Stoping the program!!"));
while (1);
}
Serial.println(F("CAN connected after sleep"));
}