Sorry for omitting code, rookie mistake.
Here is the code for the master:
//The following code illustrates how to define initial OC1 pin state for the
//output compare toggle mode of operation in 32-bit mode
#include <plib.h>
#include <SPI.h>
int count = 0;
int curr_pos;
float CPG_setpoint;
int zero_pos, max_pos, min_pos;
float CPG_ang, min_ang, max_ang, curr_ang;
float torque;
int pwm_a = 3; // PWM control for motor outputs 1 and 2 is on digital pin 3
int dir_a = 12; // dir control for motor outputs 1 and 2 is on digital pin 12
void setup()
{
Serial.begin(9600);
pinMode(dir_a, OUTPUT);
// slave select (SS) pin for SPI communications
pinMode(53,OUTPUT);
// configure module for OC1 pin low, toggle high
OC1CON = 0x0001;
// enable OC1 module
OC1CONSET = 0x8000;
// configure timer2 for prescaler of 2
T2CON = 0x0018;
// turn off OC1 while doing setup
OC1CON = 0x0000;
// configure for compare toggle mode
OC1CON = 0x0023;
// initialize compare register 1
// compare register and period must be equal
// 1 Hz = 2625a00
// 2000 Hz = 4e20
OC1R = 0x4e20;
// set period
PR2 = 0x4e20;
// configure interrupt
// clear the OC1 interrupt flag
IFS0CLR = 0x00000040;
// enable OC1 interrupt
IEC0SET =0x00000040;
// set OC1 interrupt priority to 7, the highest level
IPC1SET = 0x001C0000;
// set subpriority to 3, maximum
IPC1SET = 0x00030000;
// enable timer2
T2CONSET = 0x8000;
// enable OC1
OC1CONSET = 0x8000;
// initialize SPI
// takes care of pin assignment MOSI, MISO, SCK
SPI.begin();
SPI.setBitOrder(MSBFIRST);
zero_pos = analogRead(A0);
min_pos = zero_pos - 40;
max_pos = zero_pos + 40;
min_ang = (6.28318)*((min_pos - zero_pos)/1024.0);
max_ang = (6.28318)*((max_pos - zero_pos)/1024.0);
// slight delay avoids false trigger at start.
delay(1);
}
void loop()
{
}
extern "C"
{
void __ISR(_OUTPUT_COMPARE_1_VECTOR,ipl7) OC1_IntHandler(void)
{
// clear interrupt flag
IFS0CLR = 0x0040;
// read current position
curr_pos = analogRead(A0);
curr_ang = (100.0)*(6.28318)*((curr_pos - zero_pos)/1024.0);
// send current position to CPG at 50 Hz
// receive CPG setpoint from ArduinoMEGA at 50 Hz
if(count%40 == 0){
// direct write pin 53 (SS) LOW
LATGCLR = 1000000000;
CPG_setpoint = SPI.transfer(curr_pos);
// direct write pin 53 (SS) HIGH
LATGSET = 1000000000;
//CPG_ang = map(CPG_setpoint,0.0,122.0,100.0*min_ang,100.0*max_ang);
Serial.println(CPG_setpoint);
}
// calculate torque to be sent to motor
torque = (CPG_ang - curr_ang);
//Serial.println(CPG_ang);
//Serial.println(curr_pos);
//Serial.println(torque);
// set direction pin of h-bridge
// PIN1 LO PIN2 HI - CW
// if (torque > 0)
// //{digitalWrite(dir_a, LOW);}
// {LATACLR = 100;}
// if (torque < 0)
// //{digitalWrite(dir_a, HIGH);}
// {LATASET = 100;}
//
//torque = round(torque);
//torque = abs(torque);
//Serial.println(torque);
// map torque value to PWM
//torque = map(torque,0,24,0,100);
// apply PWM signal to h-bridge to drive motor
//analogWrite(pwm_a, torque);
++count;
}//ISR
}//extern "C"
and here is the code for the slave:
#include <stdio.h>
#include <avr/io.h>
#include <SPI.h>
// define the pin outs
int pwm_a = 3; //PWM control for motor outputs 1 and 2 is on digital pin 3
int dir_a = 12; //dir control for motor outputs 1 and 2 is on digital pin 12
float c = 1.0, tau1 = 0.10, tau2 = 2.0*tau1;
float CPG;
float CPG_pos;
float h;
float I1 = 1.0, I2 = 1.0, I3 = 1.0, I4 = 1.0;
float IC[] = {0.01,0.01,0.01,0}, K[] = {0,0,0,0};
float CPG_mapped;
byte CPG_byte;
int zero_pos, max_pos, min_pos;
float CPG_ang, min_ang, max_ang;
int count = 0;
float B = 2.5, Y = 2.5, timestep = 0.020, M = 0.5*timestep;
// SPI data recieved, current CPG position
float curr_pos;
void setup()
{
Serial.begin(9600);
// initialize Timer1
cli(); // disable global interrupts
TCCR5A = 0; // set entire TCCR1A register to 0
TCCR5B = 0; // same for TCCR1B
// set compare match register to desired timer count:
//313 = 50 Hz
//156 = 100 Hz
//80 = 200 Hz
OCR5A = 313;
// turn on CTC mode:
TCCR5B |= (1 << WGM52);
// Set CS50, CS51, CS52 bits for prescaler value: 1024
TCCR5B |= (1 << CS50);
TCCR5B |= (0 << CS51);
TCCR5B |= (1 << CS52);
// enable timer compare interrupt:
TIMSK5 |= (1 << OCIE5A);
sei(); // enable global interrupts
//send data on master in, slave out (MISO)
pinMode(MISO,OUTPUT);
pinMode(53,INPUT);
Serial.println("Enabling SPI in slave mode");
Serial.println("SPI Slave, at your service.");
// enable SPI in slave mode
SPCR = 0x40;
SPI.setBitOrder(MSBFIRST);
delay(500);
min_ang = (6.28318)*((min_pos - zero_pos)/1024.0);
max_ang = (6.28318)*((max_pos - zero_pos)/1024.0);
}
void loop()
{
curr_pos = SPI.transfer(CPG);
//if(SS == LOW){
//Serial.println("High");}
}
ISR(TIMER5_COMPA_vect)
{
CPG = CPG_function();
//Serial.println(CPG_byte);
}
float CPG_function()
{
//solves Matsuoka equations for neuron1
rungeKutta1(tau1,c,h,CPG_pos,I1,I2,I3,K);
IC[0] = IC[0] + (1.0/6.0)*(K[0] + 2.0*(K[1] + K[2]) + K[3])*timestep;
rungeKutta2(tau2,I1,I2,K);
IC[1] = IC[1] + (1.0/6.0)*(K[0] + 2.0*(K[1] + K[2]) + K[3])*timestep;
//solves Matsuoka equations for neuron2
rungeKutta1(tau1,c,h,-(CPG_pos),I3,I4,I1,K);
IC[2] = IC[2] + (1.0/6.0)*(K[0] + 2.0*(K[1] + K[2]) + K[3])*timestep;
rungeKutta2(tau2,I3,I4,K);
IC[3] = IC[3] + (1.0/6.0)*(K[0] + 2.0*(K[1] + K[2]) + K[3])*timestep;
I1 = IC[0]; I2 = IC[1]; I3 = IC[2]; I4 = IC[3];
CPG = IC[0] - IC[2];
CPG = CPG*100.0;
//CPG_byte = (byte) CPG;
//CPG_mapped = map(CPG,-61.0,61.0,0.0,122.0);
}
//neuron1
float rungeKutta1(float tau1, float c, float h, float g, float IC0, float IC1, float IC2, float *K)
{
K[0] = (1.0/tau1)*(c - IC0 - B*IC1 - Y*max(IC2,0) - h*max(g,0));
K[1] = (1.0/tau1)*(c - (IC0 + M*K[0]) - B*(IC1 + M*K[0]) - Y*max(IC2 + M*K[0],0) - h*max((g),0));
K[2] = (1.0/tau1)*(c - (IC0 + M*K[1]) - B*(IC1 + M*K[1]) - Y*max(IC2 + M*K[1],0) - h*max((g),0));
K[3] = (1.0/tau1)*(c - (IC0 + timestep*K[2]) - B*(IC1 + timestep*K[2]) - Y*max(IC2 + timestep*K[2],0) - h*max((g),0));
}//end of rungeKutta1 function
//neuron2
float rungeKutta2(float tau2, float IC0, float IC1, float *K)
{
K[0] = (1.0/tau2)*(max(IC0,0) - IC1);
K[1] = (1.0/tau2)*(max(IC0 + M*K[0],0) - IC1 + M*K[0]);
K[2] = (1.0/tau2)*(max(IC0 + M*K[1],0) - IC1 + M*K[1]);
K[3] = (1.0/tau2)*(max(IC0 + timestep*K[2],0) - IC1 + timestep*K[2]);
}//end of rungeKutta2 function