I cannot get the RPMcmdin variable to update on the slave device. The SPI ISR is at the bottom. Help?
#include <Servo.h> //BLDC operations -> 50Hz pwm generation ESC input
volatile byte command = 0;
void ss_falling (){ // start of SPI transaction, no command yet
command = 0;
} // end of interrupt service routine (ISR) ss_falling
//PINS
const uint8_t RPMsense = 2; //RPM sense input pin
const uint8_t FPpin = 9; //Fuel Pump Run pin
const uint8_t IGpin = 6; //Glow plug / ignition pin enable / disable
const uint8_t FVpin = 8; //Fuel Valve enable / disable
//Global Variables
volatile int RPMcmdin = 0; //Command input from ECU, used in Start/Run functions
volatile uint8_t RUNStatus = 0; // Global volatile system run status. 0 = OFF, 1 = START, 2 = RUN, 3 = SHUTDOWN
volatile uint8_t rpm = 0;
//const uint8_t modeT2 = 0x02;
const uint8_t modeT1 = 0x02; //PWM Freq Scale 16B P
//const uint8_t modeT0 = 0x02; //PWM Freq Scale 8B P87 T2 BASE = PS(1, 8, 64, 256, 1024)
int value = 0; // servo program value for ESC. 1000 SD, 1200 Stop, 2000 MAX
Servo StarterCON; // Brushless motor instance
void setup() {
//SPI setup
pinMode(MISO, OUTPUT); // have to send on master in, *slave out*
SPCR |= _BV(SPE); // turn on SPI in slave mode
SPCR |= _BV(SPIE); // turn on interrupts
attachInterrupt (0, ss_falling, FALLING); // interrupt for SS falling edge
//Pins
pinMode(FPpin, OUTPUT);
pinMode(RPMsense, INPUT_PULLUP);
pinMode(FVpin, OUTPUT);
pinMode(IGpin, OUTPUT);
//PWM Change Frequency
StarterCON.attach(5); // Pin 5 ESC control for Brushless Motor
//TCCR2B = TCCR2B & 0b11111000 | modeT2;//Pin 3 and 11 PWM freq
TCCR1B = TCCR1B & 0b11111000 | modeT1;//Pin 9 and 10 PWM freq
//TCCR0B = TCCR0B & 0b11111000 | modeT0; //Pin 5 and 6 PWM Freq
Serial.begin(115200);
}
void loop() {
//Starter(int); FUELvalve(int); FuelPump(int); Ignition(int)
//StartSEQ(); ShutdownSEQ();
GetRPM();
Serial.println(RPMcmdin);
delay(100);
}
// Rough start sequence, needs work with fuel pump and handoff to RUN function
void StartSEQ(){
return;
}
void ShutdownSEQ(){
return;
}
void EngineRUN(){
return;
}
// RPM Sense
int GetRPM(){
unsigned long PWH = pulseIn(RPMsense,HIGH);
rpm = 24928/PWH; // rpm:24928570 kRPM 24928
return(rpm);
}//END RPM Sense
//Starter Speed Control
int Starter(int STRin){
StarterCON.write(STRin);
Serial.println(STRin);
return;
}//END Starter Speed Control
//Fuel Pump Control
int FuelPump(int FP){
analogWrite(FPpin, FP);
return;
} //END Fuel Pump Control
//Fuel Valve Control function 1 opens valve, 0 closes valve.
int FUELvalve(int pos){
if (pos == 1){
digitalWrite(FVpin, HIGH);
}else{
digitalWrite(FVpin, LOW);
}
return;
}//END Fuel Valve Control
//Igniter Control function 1 on, 0 off.
int Ignition(int i){
if (i == 1){
analogWrite(IGpin, 35);
}else{
analogWrite(IGpin, 0);
}
return;
}//END Igniter Control
// SPI ISR
ISR (SPI_STC_vect){
int c = SPDR;
switch (command){
// no command? then this is the command
case 0:
command = c;
SPDR = 0;
RPMcmdin = 0;
break;
case 'a': // Get RPM value and return
SPDR = c + rpm; // add 15
break;
case 'd':
RPMcmdin = c;
break;
} // end of switch
} //END(ISR) SPI_STC_vect
The other issue that it could be is the way that I send the write request from the Master. I did the same thing that I did for reading the value, and in this case it reads back the cmd value and I print it out but for some reason it subtracts 1 and I do not know why. This is the code from the Master (Arduino MEGA):
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <SparkFunMAX31855k.h> // Using the max31855k driver
LiquidCrystal_I2C lcd(0x3F,16,2); //LCD address to 0x3f for a 16 char 2 line display
int Vpin = A8;
const uint8_t TEMPSS = 24;
const uint8_t VCC = 2; // NOT USED, Function Place Holder
const uint8_t GND = 4; // NOT USED, Function Place Holder
volatile uint8_t cmd = 0;
//Subinitialazation Funcitons
SparkFunMAX31855k probe(TEMPSS, VCC, GND);
void setup(){
digitalWrite(SS, HIGH); // ECM Slave Select Pin
digitalWrite(TEMPSS, HIGH); // TEMP Slave Select Pin
Wire.begin(); // join i2c bus (address optional for master)
lcd.init(); // initialize the lcd
lcd.backlight();
pinMode(Vpin, INPUT);
Serial.begin(115200);
SPI.begin ();
SPI.setClockDivider(SPI_CLOCK_DIV8);
}
void loop(){
if (Serial.available()>0){
cmd = Serial.parseInt();
WriteDATA(cmd);
}
ReadDATA();
delay(200);
}
byte WriteDATA(byte cmdin){
cmdin++;
digitalWrite(SS, LOW); // enable Slave Select
SPITransfer ('d');
SPITransfer (cmdin);
cmd = SPITransfer (0);
digitalWrite(SS, HIGH); // disable Slave Select
Serial.println(cmd);
}
//Requests parameter data from the ECU. Min 20ms response time a normal I2C freq.
void ReadDATA(){
digitalWrite(SS, LOW); // enable Slave Select
SPITransfer ('a'); // add command
SPITransfer (1);
byte rpm = SPITransfer (1);
digitalWrite(SS, HIGH); // disable Slave Select
int RS = 1;
int egt = GetEGT();
int Vbat = Volt();
LCD(rpm,egt,cmd,Vbat,RS);
}
//SPI transfer byte
byte SPITransfer (const byte dat){
byte a = SPI.transfer (dat);
delayMicroseconds (20);
return a;
} //END SPITransfer
// Read Thermocouple
int GetEGT(){
float temperature = probe.readCJT();
temperature = probe.readTempC();
return (temperature);
return;
}//END Reads Thermocouple
//Read Voltage Value
int Volt(){
//This needs to be worked on Cell Value, implemented for testing
int Vin = analogRead(Vpin);
int Vout = map(Vin, 0,1023,0,100);
return(Vout);
}//END Read Voltage Value
// Write data to LCD in fomat for 16 x 2 LCD
void LCD(int rpm, int egt, int cmd, int vlt, byte RS){
lcd.setCursor(0,0);
lcd.print("RPM: CMD: ");
lcd.setCursor(0,1);
lcd.print("EGT: BAT: ");
lcd.setCursor(4,0);
lcd.print(rpm);
lcd.setCursor(13,0);
lcd.print(cmd);
lcd.setCursor(4,1);
lcd.print(egt);
lcd.setCursor(8,1);
lcd.print(RS);
lcd.setCursor(13,1);
lcd.print(vlt);
}//END Write LCD