Hello everyone,
I am trying to send data from an master Arduino Uno board to a slave Arduino Uno board. I found a great SPI_template header file online that should allow me to send any kind of template struct that I want to send. Here is the code for the header file:
Template
#include <Arduino.h>
template unsigned int SPI_writeAnything (const T& value)
{
const byte p = (const byte) &value;
unsigned int i;
for(i = 0; i < sizeof value; i++)
SPI.transfer(*p++);
return i;
}
template unsigned int SPI_readAnything(T& value)
{
byte p = (byte) &value;
unsigned int i;
for(i = 0; i < sizeof value; i++)
*p++ = SPI.transfer(0);
return i;
}
template unsigned int SPI_readAnything_ISR(T& value)
{
byte p = (byte) &value;
unsigned int i;
*p++ = SPDR;
for(i = 1; i < sizeof value; i++)
*p++ = SPI.transfer(0);
return i;
}
My goal is to be able to send the struct using SPI but I would like to determine when to send the data using a simple push-button. In order to test my code, I included several Serial.println statements in the slave code. But the Serial.println statements are not working, nothing appears on the Serial Monitor before or after I press the push-button. I am using an interrupt for the push-button. Any ideas or recommendations on how to implement an external push-button that start an SPI communication?
Here is my master code:
// Information: This program is being used to test a push button, the action
// of pressing the push button should enable the SPI transfer of data.
#include <SPI.h>
#include "SPI_Template.h"
typedef struct myStruct {
int a;
float b;
long c;
};
// This struct object is used to store and transfer the data values
// that the programmer wishes to use with SPI for the 'on' button.
myStruct structComm;
// This int variable will be used for the push button, Button1
// corresponds to 'send' button.
int Button1 = 2;
// The button press will switch the state.
int toggle_on;
void setup() {
Serial.begin(115200);
pinMode(10, OUTPUT);
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV8);
structComm.a = 44;
structComm.b = 30.0;
structComm.c = 12;
// This code initializes the push-button pin as an input.
pinMode(Button1, INPUT);
attachInterrupt(digitalPinToInterrupt(Button1), pin_ISR1, RISING);
}
void loop() {
if (toggle_on == 1) {
digitalWrite(SS, LOW);
SPI_writeAnything(structComm);
digitalWrite(SS, HIGH);
}
}
// This interrupt function is for the push button.
void pin_ISR1()
{
static unsigned long last_interrupt_time1 = 0;
unsigned long interrupt_time1 = millis();
// After a certain amount of time, it will toggle on.
if (interrupt_time1 - last_interrupt_time1 > 200)
{
toggle_on = 1;
}
last_interrupt_time1 = interrupt_time1;
}
Here is the slave code:
// Information: This program is being used to test a push button, the action
// of pressing the push button should enable the SPI transfer of data.
#include <SPI.h>
#include "SPI_Template.h"
typedef struct myStruct
{
int a;
float b;
long c;
};
volatile myStruct structComm;
volatile bool haveData = false;
void setup()
{
Serial.begin(115200);
pinMode(MISO, OUTPUT);
// This code turns on the SPI in slave mode.
SPCR |= _BV(SPE);
SPI.attachInterrupt();
}
// This void function acts just like the main function.
void loop() {
if (haveData) {
Serial.println();
Serial.println("SPI test");
Serial.println(structComm.a);
Serial.println(structComm.b);
Serial.println(structComm.c);
Serial.println();
delay(2500);
haveData = false;
}
}
// This is a SPI interrupt routine function for the green go button.
ISR(SPI_STC_vect) {
SPI_readAnything_ISR(structComm);
haveData = true;
}