so I have made some adjustments to the code after working with gwe89 - it appears the code successfully detects and responds to ignition on and off signals - and the relay behaves as expected
Initially the code was not detecting the iginition codes, and when i added some debug output, it showed me the problem - and a query @go4it
You mentioned that byte D3 held the ignition sense code, but the ignition code needed is below:
0048FF076C092702E0A0
Id ID 0048, Data 0xFF, 0x07, 0x6C, 0x09, 0x27, 0x02, 0xE0, 0xA0
I assume this is to do with the Endian-ness of the transmission - but the problem is that the array is storing the data D0-D7 but it's actually being read in D7-D0, so to access the correct data i need to reference D5! is there a way to resolve this, or am i doing something wrong!
Would also appreciate anyone's comments about the sleep states and how i'm handling the relay switching - this is very much a learning process so all input welcomed!
/*
* CAN Based ignition simulator v0.5
* Simulates ignition on to drive relay to power device on and off
* Designed for Ford Mondeo Mk4, CAN ID 0x048 for ignition state
* (c) 2019 Ian Rushton
*/
#include <SPI.h>
#include <mcp_can.h>
#include <TimerOne.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
volatile long unsigned int BusID; // CAN ID of received info
volatile unsigned char len = 0; // received message DLC
volatile char Busbuffer [8]; // array to store 8 byte CAN message
volatile byte RelayState = HIGH; // byte used to to store relay state, set to High (OFF)
volatile unsigned int RelayPin = 8; // Pin to which relay trigger is attached
volatile unsigned long RelayDelay; // Used to store timer info to Interrupt
// * Define board connections
#define MSCAN_INT_PIN 2 // Interrupt pin for MSCAN_INT_PIN
MCP_CAN MSCAN(10); // Cable Select pin for MS-CAN
void setup ()
{
// * Configure Serial Baud Rate
Serial.begin (9600);
// * Setup MS-CAN shield to only read CAN ID 0x048
MSCAN.begin (MCP_STDEXT, CAN_125KBPS, MCP_8MHZ); //change to MCP_16MHZ for 16MHz crystal board
MSCAN.setMode (MODE_CONFIG);
MSCAN.init_Mask (0,0,0x07FF0000);
MSCAN.init_Filt (0,0,0x00480000);
MSCAN.init_Mask (1,0,0x07FF0000);
MSCAN.init_Filt (0,0,0x00480000);
MSCAN.setMode (MCP_LISTENONLY);
// * Configure Relay settings
pinMode (RelayPin, OUTPUT); // Configure Relay pin as an output port
digitalWrite(RelayPin, RelayState); //Set initial state of relay to High (Off)
// * Initialise timer for relay state.
RelayDelay = 60; // Relay Delay set for 60ms
Timer1.initialize (RelayDelay);
Timer1.attachInterrupt (relay_int);
// * Initialise MS_CAN shield /INT pin
pinMode (digitalPinToInterrupt (MSCAN_INT_PIN), INPUT_PULLUP);
// If /INT of MS-CAN shield goes low, read message from bus (wakeup from sleep)
attachInterrupt (digitalPinToInterrupt (MSCAN_INT_PIN), mscan_init, LOW);
// Configure watchdog to restart module if WD timer not reset properly from loop (set to 8secs)
wdt_enable (WDTO_8S);
}
// * ISR for MS-CAN incoming message ID 0x048
void mscan_init ()
{
wdt_enable (WDTO_8S);
wdt_reset ();
MSCAN.readMsgBuf (& BusID, len, Busbuffer);
set_sleep_mode (SLEEP_MODE_IDLE);
}
// * ISR for Relay Control
void relay_int ()
{
wdt_reset ();
// Confirm CanBUS message received
if ((Busbuffer [4] >=0x24) && (Busbuffer [4] <=0x27)) // Byte D5 between 0x24>0x27 - Ignition On
{
/* Serial.print("Ignition State detected, contents of Byte 5 : 0x");
Serial.print(Busbuffer [4], HEX); */
RelayState = LOW; // Set Relay state to Low (On)
}
else if ((Busbuffer [4] == 0x20) || (Busbuffer [4] == 0x21) ) // Signal of Ignition Off
{
/* Serial.print("Ignition Off detected, contents of Byte 5 : 0x");
Serial.print(Busbuffer [4], HEX); */
RelayState = HIGH; // Set Relay state to High (Off)
}
else
{
/* Serial.print("Ignition State indeterminate, contents of Byte 5 : 0x");
Serial.print(Busbuffer [4], HEX); */
RelayState = RelayState; // In all other conditions, leave RelayState unchanged
}
digitalWrite (RelayPin, RelayState); // Write result to Relay output pin
}
// * Main Program Loop
void loop ()
{
sleep_enable();
sleep_mode ();
sleep_disable ();
}