I2C between 2 teensies only works after restart

Status
Not open for further replies.

khoadley

Member
Greetings,

I am trying to transfer a large int array from a slave device (teensy3.6) to the master device (teensy4.1) using I2C communication. In the protocol, the slave provide a digital HIGH reading to the slave which then records data. Once data collection has ceased (master device sends digital LOW reading), the master then requests the data using the request.forTransfer code. I am running into two problems here. First, the transfer of data appears to only work if the master device has just been reset. Subsequent calls for data transfer do not appear to work. Second problem is that the transfer only requests up to 36bytes (in practice, I will want to transfer far more than that at a time). I have attached the full slave code, as well as the relevant Master code below. If there are any questions/additional information that may be of help, please let me know. Thanks in advance for your help!!

Kind Regards,

Kenneth D. Hoadley

Master Code:

#include <ADC.h>
#include <ADC_Module.h>
#include <ADC_util.h>
#include <SD.h>
#include <SPI.h>
#include <TimeLib.h>
#include <string.h>
#include <Wire.h>

int AUTO = 1
const int Slave = 8; //Turns slave data aquisition on

int j =0;
byte x;
int y;

void setup()
{
Serial.begin(9600);
pinMode(Slave, OUTPUT);
Wire.begin();
}

void loop()
{
if (AUTO == 0)
{ serialInput(); //search for AUTO input of new variables
delay(1000);
}
if (AUTO == 1)
{ digitalWrite(Slave, HIGH);
serialInput(); //search for AUTO input of new variables
// I have omitted a fair bit of working code from this section as it does not relate to the I2C issue
digitalWrite(Slave, LOW);
SlaveReader();
AUTO = 0;
}
}

void SlaveReader()
{ Serial.print("read: ");
Wire.requestFrom(8,60000);
int avail = Wire.available();
for (int i = 0; i < avail/2; i++)
{
x = Wire.read();
j++;
if(j==1)
{
y=(x<<8) | Wire.read();
Serial.print(y, DEC);
Serial.print(' ');
j=0;
}
}
Serial.println();
delay(1000);
}


Slave Code:

#include <ADC.h>
#include <ADC_Module.h>
#include <ADC_util.h>
#include <SPI.h>
#include <string.h>
#include <Wire.h>

const int SIG = A0; //Analog channel used for reading fluorescence signal
ADC *adc = new ADC(); // adc object
int STARTER;

//FOR Channel 0 LED EXCITATION READINGS
int COL0Sig; // variable to store the value coming from Fluoresence Channel
int COL1Sig; // variable to store the value coming from Fluoresence Channel
int DatNorm[60000]; // Average Fluorecence readings based in each REP

int i=0;
int g=0;

const int input1 = 5;
const int Col0 = 1; //digitalWrite pin for UV LED excitation -blue-label-in-code-
const int Col1 = 2; //digitalWrite pin for BLUE LED excitation -red-label-in-code
int led = LED_BUILTIN;

void setup()
{
Serial.begin(9600);
pinMode(Col0, OUTPUT);
pinMode(Col1, OUTPUT);
pinMode(led, OUTPUT);
pinMode(input1, INPUT);
pinMode(SIG, INPUT);
analogWriteResolution(12);

adc->adc0->setAveraging(12);
adc->adc0->setResolution(12);
adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED); // change the conversion speed
adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::HIGH_SPEED); // change the sampling speed

adc->adc0->enableInterrupts(adc0_isr);
adc->adc0->startContinuous(SIG);

////// ADC1 /////
#ifdef ADC_DUAL_ADCS
adc->adc1->enableInterrupts(adc1_isr);
adc->adc1->setAveraging(12); // set number of averages
adc->adc1->setResolution(12); // set bits of resolution
adc->adc1->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED); // change the conversion speed
adc->adc1->setSamplingSpeed(ADC_SAMPLING_SPEED::HIGH_SPEED); // change the sampling speed
#endif

Wire.begin(8);
Wire.onRequest(requestEvent);
}


void loop()
{
STARTER = digitalRead(input1);
if (STARTER == HIGH)
{ //Channel 0
digitalWrite(led, HIGH);
digitalWriteFast(Col0, HIGH);
delayMicroseconds(14);
adc->adc0->isConverting();
adc->adc1->isConverting();
adc->adc0->isComplete();
adc->adc1->isComplete();
COL0Sig=(uint16_t)adc->adc0->analogReadContinuous();

digitalWriteFast(Col0, LOW);

//Channel 1
digitalWriteFast(Col1, HIGH);
delayMicroseconds(14);
adc->adc0->isConverting();
adc->adc1->isConverting();
adc->adc0->isComplete();
adc->adc1->isComplete();
COL1Sig=(uint16_t)adc->adc0->analogReadContinuous();
digitalWriteFast(Col1, LOW);

DatNorm[g] = (COL0Sig-COL1Sig);
g += 1;
COL0Sig = 0;
COL1Sig = 0;
delay(9);
digitalWrite(led, LOW);
}
}




void requestEvent()
{
for (i=0;i<g;i++)
{
Wire.write(highByte(DatNorm));
Wire.write(lowByte(DatNorm));
}
DatNorm[g] = 0;
g = 0;
}


void adc0_isr(void)
{
adc->adc0->analogReadContinuous();
}
#ifdef ADC_DUAL_ADCS
void adc1_isr(void)
{
adc->adc1->analogReadContinuous();
}
#endif
 
The Wire library restricts the type of the quantity in a requestFrom to be uint8_t which therefore has a maximum of 255. BUT the library further restricts this quantity to be no larger than the size of the internal buffer, which by default is 32 bytes. Asking for 60000 is going to be a problem.

Pete
 
Thanks jonr and el_supremo for your input. On your suggestions, I switched communication to serial (using examples from online), which appears to be working. However, I am still having two issues. A: The Master device only takes up part of the array before moving on. Basically, it seems like it does not wait long enough for it to receive all the data (to be fair, it is a long array). B: the array that is being transferred from the slave device is called DatNorm, which is the difference between two analog signals. If I just 'manually' put the integer 100 into the array, it transfers correctly and I see 100 come out on the Master device. However, if I let it use the difference between the two analog inputs, it comes out wrong (a very different number) on the master device. Attached are my slave and relevant master code. Thanks again for your help!!!

Kind Regards,

Kenneth D. Hoadley

Slave Code

#include <ADC.h>
#include <ADC_Module.h>
#include <ADC_util.h>
#include <SPI.h>
#include <string.h>
#include <SoftwareSerial.h>

const int SIG = A0; //Analog channel used for reading fluorescence signal
ADC *adc = new ADC(); // adc object
int STARTER;

//FOR Channel 0 LED EXCITATION READINGS
SoftwareSerial mySerial(9,10); //rx pin,tx pin
int COL0Sig; // variable to store the value coming from Fluoresence Channel
int COL1Sig; // variable to store the value coming from Fluoresence Channel
int DatNorm[60000]; // Average Fluorecence readings based in each REP

int i=0;
int g=0;

const int input1 = 5;
const int Col0 = 1; //digitalWrite pin for UV LED excitation -blue-label-in-code-
const int Col1 = 2; //digitalWrite pin for BLUE LED excitation -red-label-in-code

int otp=0;

void setup()
{ Serial.begin(9600);
mySerial.begin(9600);
pinMode(Col0, OUTPUT);
pinMode(Col1, OUTPUT);
pinMode(input1, INPUT);
pinMode(SIG, INPUT);
analogWriteResolution(12);

adc->adc0->setAveraging(12);
adc->adc0->setResolution(12);
adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED); // change the conversion speed
adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::HIGH_SPEED); // change the sampling speed

adc->adc0->enableInterrupts(adc0_isr);
adc->adc0->startContinuous(SIG);

////// ADC1 /////
#ifdef ADC_DUAL_ADCS
adc->adc1->enableInterrupts(adc1_isr);
adc->adc1->setAveraging(12); // set number of averages
adc->adc1->setResolution(12); // set bits of resolution
adc->adc1->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED); // change the conversion speed
adc->adc1->setSamplingSpeed(ADC_SAMPLING_SPEED::HIGH_SPEED); // change the sampling speed
#endif
}


void loop()
{
STARTER = digitalRead(input1);
if (STARTER == HIGH)
{ //Channel 0
digitalWriteFast(Col0, HIGH);
delayMicroseconds(14);
adc->adc0->isConverting();
adc->adc1->isConverting();
adc->adc0->isComplete();
adc->adc1->isComplete();
COL0Sig=(uint16_t)adc->adc0->analogReadContinuous();

digitalWriteFast(Col0, LOW);

//Channel 1
digitalWriteFast(Col1, HIGH);
delayMicroseconds(14);
adc->adc0->isConverting();
adc->adc1->isConverting();
adc->adc0->isComplete();
adc->adc1->isComplete();
COL1Sig=(uint16_t)adc->adc0->analogReadContinuous();
digitalWriteFast(Col1, LOW);

//DatNorm[g] = (COL0Sig-COL1Sig);
DatNorm[g] = 100;
Serial.print(DatNorm[g]);
Serial.print(' ');
Serial.println(g);

g += 1;
COL0Sig = 0;
COL1Sig = 0;
delay(9);
otp=1;
}
if(STARTER==LOW && otp ==1)
//if(otp==1)
{
requestEvent();
delay(1000);
DatNorm[g] = 0;
g = 0;
otp=0;
}
}




void requestEvent()
{ //int DatNorm[] = {1001,1002,1003,1004};
mySerial.print("<");
//for(int i=0;i<sizeof(DatNorm)/sizeof(DatNorm[0]);i++)
for(int i=0;i<g;i++)
{
mySerial.print(DatNorm,1);
mySerial.print(",");

}
mySerial.print(">");
delay(2000);
}


void adc0_isr(void)
{
adc->adc0->analogReadContinuous();
}
#ifdef ADC_DUAL_ADCS
void adc1_isr(void)
{
adc->adc1->analogReadContinuous();
}
#endif




Master Code

#include <ADC.h>
#include <ADC_Module.h>
#include <ADC_util.h>
#include <SD.h>
#include <SPI.h>
#include <TimeLib.h>
#include <string.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(16,17); //rx pin,tx pin

int AUTO = 1
const int Slave = 8; //Turns slave data aquisition on

String recvchars[10000];
boolean newdata=false;

void setup()
{
Serial.begin(9600);
mySerial.begin(9600);
pinMode(Slave, OUTPUT);
Wire.begin();
}

void loop()
{
if (AUTO == 0)
{ serialInput(); //search for AUTO input of new variables
newdata=false; //reset PSI serial intake pipe
delay(1000);
}
if (AUTO == 1)
{ digitalWrite(Slave, HIGH);
serialInput(); //search for AUTO input of new variables
// I have omitted a fair bit of working code from this section as it does not relate to the I2C issue
digitalWrite(Slave, LOW);
SlaveReader();
AUTO = 0;
}
}

void SlaveReader()
{ Serial.print("read ");
static boolean recvinprogress=false;
static byte ndx=0;
char startmarker='<';
char comma=',';
char endmarker='>';
String c;

while(mySerial.available()>0 && newdata==false)
{ c=mySerial.read();
if(c==startmarker)recvinprogress=true;
else if(c==endmarker)
{
recvinprogress=false;
ndx=0;
newdata=true;
}
if(recvinprogress==true)
{
if(c==comma)
{ for(int i =0;i<ndx;i++)
{ Serial.print(recvchars);
}
ndx=0;
Serial.println();
}
if(c!=comma)
{ recvchars[ndx]=c;
ndx++;
}
}
}
delay(2000);
}
 
Your Master code doesn't even compile. Probably better not to use SoftwareSerial. And think through timing issues.
 
Thanks Jonr. When you mention timing issues, what do you mean exactly? Also, why would you avoid Software Serial? Thanks!
 
On Teensy 3.x and 4.x we just barely support SoftwareSerial. If you configure SoftwareSerial to use the RX & TX pins of a real serial port, it will just use that real serial port hardware. So on Teensy 4.x, you might as well just use Serial4 rather than SoftwareSerial on pins 16 & 17, since internally SoftwareSerial will just be using Serial4 anyway. Then again, Teensy 4 is very fast, so the tiny extra overhead really isn't very substantial.

The main reason we have SoftwareSerial at all is for compatibility. Especially if you are using a library someone wrote with a hard-coded dependency on using SoftwareSerial (like the begin function or C++ constructor will only take a SoftwareSerial name as its input), this lets you create a SoftwareSerial instance that you can give to such libraries to make then "just work".

If you choose 2 pins which aren't a real serial port, SoftwareSerial on Teensy 4.x will not be able to receive at all, and the transmit code will usually work, but it hogs the CPU to do so. Not great. And realistically, with 7 real serial ports on Teensy 4.0 and 8 on Teensy 4.1, improving SoftwareSerial isn't much of a priority. Its main purpose is to give you a way to be compatible with just a few ancient Arduino libraries that only work with SoftwareSerial.

If you're writing your own code, or using a library like MIDI which can take either SoftwareSerial or real hardware serial instances, you might as well just use Serial4.

Then again, if you're writing a program which you intend to share with people using old / traditional Arduino boards which have only a single serial port which is normally in use for communication to a PC, then you might want to use SoftwareSerial. That makes it easier to adapt your program to run on such very limited hardware where you don't get 8 real serial ports.
 
Thanks PaulStoffregen. I switched to Serial4 and works just the same. I am still having issues with collecting all my array data. The slave device sends 26 integers, but only the first 20 or so appear on the master (In the future, I would like it to send 1000s of integers at a time). This time I have attached the full Master code. I have no doubt the rest of the Master code can be done more efficiently but 'void SlaveReader' is the portion I am having trouble getting to work. Thanks again for taking a look!

Kind Regards,

Kenneth D. Hoadley

SLAVE
#include <ADC.h>
#include <ADC_Module.h>
#include <ADC_util.h>
#include <SPI.h>
#include <string.h>

const int SIG = A0; //Analog channel used for reading fluorescence signal
ADC *adc = new ADC(); // adc object
int STARTER;

//FOR Channel 0 LED EXCITATION READINGS
int COL0Sig; // variable to store the value coming from Fluoresence Channel
int COL1Sig; // variable to store the value coming from Fluoresence Channel
byte DatNorm[60000]; // Average Fluorecence readings based in each REP

int i=0;
int g=0;

const int input1 = 5;
const int Col0 = 1; //digitalWrite pin for UV LED excitation -blue-label-in-code-
const int Col1 = 2; //digitalWrite pin for BLUE LED excitation -red-label-in-code

int otp=0;

void setup()
{ Serial.begin(9600);
Serial4.begin(9600);
Serial4.setTimeout(5000);
pinMode(Col0, OUTPUT);
pinMode(Col1, OUTPUT);
pinMode(input1, INPUT);
pinMode(SIG, INPUT);
analogWriteResolution(12);

adc->adc0->setAveraging(12);
adc->adc0->setResolution(12);
adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED); // change the conversion speed
adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::HIGH_SPEED); // change the sampling speed

adc->adc0->enableInterrupts(adc0_isr);
adc->adc0->startContinuous(SIG);

////// ADC1 /////
#ifdef ADC_DUAL_ADCS
adc->adc1->enableInterrupts(adc1_isr);
adc->adc1->setAveraging(12); // set number of averages
adc->adc1->setResolution(12); // set bits of resolution
adc->adc1->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED); // change the conversion speed
adc->adc1->setSamplingSpeed(ADC_SAMPLING_SPEED::HIGH_SPEED); // change the sampling speed
#endif
}


void loop()
{
STARTER = digitalRead(input1);
if(STARTER==LOW && otp ==1)
{
requestEvent();
delay(1000);
otp=0;
}
if (STARTER == HIGH)
{ //Channel 0
digitalWriteFast(Col0, HIGH);
delayMicroseconds(14);
adc->adc0->isConverting();
adc->adc1->isConverting();
adc->adc0->isComplete();
adc->adc1->isComplete();
COL0Sig=(uint16_t)adc->adc0->analogReadContinuous();

digitalWriteFast(Col0, LOW);

//Channel 1
digitalWriteFast(Col1, HIGH);
delayMicroseconds(14);
adc->adc0->isConverting();
adc->adc1->isConverting();
adc->adc0->isComplete();
adc->adc1->isComplete();
COL1Sig=(uint16_t)adc->adc0->analogReadContinuous();
digitalWriteFast(Col1, LOW);

DatNorm[g] = (COL0Sig-COL1Sig);
g += 1;
COL0Sig = 0;
COL1Sig = 0;
delay(9);
otp=1;
}
}




void requestEvent()
{
Serial4.print("<");
for(int i=0;i<g;i++)
{
Serial4.print(DatNorm,1);
Serial4.print(",");
Serial.print(DatNorm,1);
Serial.print(' ');
Serial.println(i);

}
Serial4.print(">");
DatNorm[g] = 0;
g = 0;
//delay(2000);
}


void adc0_isr(void)
{
adc->adc0->analogReadContinuous();
}
#ifdef ADC_DUAL_ADCS
void adc1_isr(void)
{
adc->adc1->analogReadContinuous();
}
#endif



MASTER
#include <ADC.h>
#include <ADC_Module.h>
#include <ADC_util.h>
#include <SD.h>
#include <SPI.h>
#include <TimeLib.h>
#include <string.h>

File myFile;
File myFile2;
File myFile3;
const int chipSelect = BUILTIN_SDCARD;
int AUTO = 1; //0 sets single aquisitions, 1 sets auto aquistion.
const int BEEFY = 1000; //Size of arrays to be used to collect samples.
int REP = 5; //Number of repetitions of the full protocol
int DELAYED = 2000;
int del = 200; //Delay between flashes in protocol
const int SIG = A0; //Analog channel used for reading fluorescence signal
ADC *adc = new ADC(); // adc object
int sample0 = 150; //Size of array dictates number of samples taken/ length of flash. Each sample is 1.18 useconds
int sample1 = 150; //Size of array dictates number of samples taken/ length of flash. Each sample is 1.18 useconds
int sample2 = 150; //Size of array dictates number of samples taken/ length of flash. Each sample is 1.18 useconds
int sample3 = 150; //Size of array dictates number of samples taken/ length of flash. Each sample is 1.18 useconds
int initial = 50; //Number of samples to be recorded prior to flash protocol. this is used to normalize F0.
String fourthy = "Dat";
String curvesFile = "DatRaw.csv";
String dataFile = "DatCalc.txt";
String PSIFile = "DatPSI.csv";
int time[BEEFY]; //Time constant. Adjusts automatically to size of array/number of samples.
float TIMEX0[BEEFY]; //Time constant. Adjusts automatically to size of array/number of samples.
float TIMEX1[BEEFY]; //Time constant. Adjusts automatically to size of array/number of samples.
float TIMEX2[BEEFY]; //Time constant. Adjusts automatically to size of array/number of samples.
float TIMEX3[BEEFY]; //Time constant. Adjusts automatically to size of array/number of samples.
float timepersample0; //Time constant. Adjusts automatically to size of array/number of samples.
float timepersample1; //Time constant. Adjusts automatically to size of array/number of samples.
float timepersample2; //Time constant. Adjusts automatically to size of array/number of samples.
float timepersample3; //Time constant. Adjusts automatically to size of array/number of samples.
float sampletimey0;
float sampletimey1;
float sampletimey2;
float sampletimey3;

int PARcol0 = 20200;
int PARcol1 = 30620;
int PARcol2 = 17050;
int PARcol3 = 19500;

float valpar;
int increment = 5; //increment in the curvefit routine. The higher the number, the less data is used. Saves considerable time.

//FOR Channel 0 LED EXCITATION READINGS
float COL0Ref[BEEFY]; // variable to store the value coming from Reference Channel
float COL0Sig[BEEFY]; // variable to store the value coming from Fluoresence Channel
float COL0AveRef[BEEFY]; // Average Reference readings based on each REP
float COL0AveSig[BEEFY]; // Average Fluorecence readings based in each REP
float COL0Norm[BEEFY]; // Normalize Fluorescence readings by Reference.
float COL0PreS; //Average Fluorsence reading prior to excitation
float COL0PreR; //Average Reference reading prior to excitation
float COL0LINREG[5]={0,0,0,0,0}; //Array to store initial Lin Regression values and readings from average and normalized data.
float COL0fit[BEEFY]; //variable to store fit curve

//FOR Channel 1 LED EXCITATION READINGS
float COL1Ref[BEEFY]; // variable to store the value coming from Reference Channel
float COL1Sig[BEEFY]; // variable to store the value coming from Fluoresence Channel
float COL1AveRef[BEEFY]; // Average Reference readings based on each REP
float COL1AveSig[BEEFY]; // Average Fluorecence readings based in each REP
float COL1Norm[BEEFY]; // Normalize Fluorescence readings by Reference.
float COL1PreS; //Average Fluorsence reading prior to excitation
float COL1PreR; //Average Reference reading prior to excitation
float COL1LINREG[5]={0,0,0,0,0}; //Array to store initial Lin Regression values and readings from average and normalized data.
float COL1fit[BEEFY]; //variable to store fit curve

//FOR Channel 2 LED EXCITATION READINGS
float COL2Ref[BEEFY]; // variable to store the value coming from Reference Channel
float COL2Sig[BEEFY]; // variable to store the value coming from Fluoresence Channel
float COL2AveRef[BEEFY]; // Average Reference readings based on each REP
float COL2AveSig[BEEFY]; // Average Fluorecence readings based in each REP
float COL2Norm[BEEFY]; // Normalize Fluorescence readings by Reference.
float COL2PreS; //Average Fluorsence reading prior to excitation
float COL2PreR; //Average Reference reading prior to excitation
float COL2LINREG[5]={0,0,0,0,0}; //Array to store initial Lin Regression values and readings from average and normalized data.
float COL2fit[BEEFY]; //variable to store fit curve

//FOR Channel 3 LED EXCITATION READINGS
float COL3Ref[BEEFY]; // variable to store the value coming from Reference Channel
float COL3Sig[BEEFY]; // variable to store the value coming from Fluoresence Channel
float COL3AveRef[BEEFY]; // Average Reference readings based on each REP
float COL3AveSig[BEEFY]; // Average Fluorecence readings based in each REP
float COL3Norm[BEEFY]; // Normalize Fluorescence readings by Reference.
float COL3PreS; //Average Fluorsence reading prior to excitation
float COL3PreR; //Average Reference reading prior to excitation
float COL3LINREG[5]={0,0,0,0,0}; //Array to store initial Lin Regression values and readings from average and normalized data.
float COL3fit[BEEFY]; //variable to store fit curve

int result[BEEFY]; //SET up for simulatneous ADC reading
int i=0;
int t=0;
int g=0;

const int Col0 = 0; //digitalWrite pin for UV LED excitation -blue-label-in-code-
const int Col1 = 1; //digitalWrite pin for BLUE LED excitation -red-label-in-code
const int Col2 = 2; //digitalWrite pin for GREEN LED excitation -green-label-in-code
const int Col3 = 3; //digitalWrite pin for CYAN LED excitation -orange-label-in-code
const int Actinic = 7; //digitalWrite pin for GREEN LED excitation -green-label-in-code
const int Slave = 8; //Turns slave microcontroller on

char recvchars[6000];
boolean newdata=false;


void setup()
{
Serial.begin(9600);
Serial4.begin(9600);
Serial4.setTimeout(5000);
pinMode(Col0, OUTPUT);
pinMode(Col1, OUTPUT);
pinMode(Col2, OUTPUT);
pinMode(Col3, OUTPUT);
pinMode(Slave, OUTPUT);
pinMode(Actinic, OUTPUT);
pinMode(SIG, INPUT);
analogWriteResolution(12);

adc->adc0->setAveraging(6);
adc->adc0->setResolution(12);
adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_HIGH_SPEED); // change the conversion speed
adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::VERY_HIGH_SPEED); // change the sampling speed

adc->adc0->enableInterrupts(adc0_isr);
adc->adc0->startContinuous(SIG);

////// ADC1 /////
#ifdef ADC_DUAL_ADCS
adc->adc1->enableInterrupts(adc1_isr);
adc->adc1->setAveraging(6); // set number of averages
adc->adc1->setResolution(12); // set bits of resolution
adc->adc1->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_HIGH_SPEED); // change the conversion speed
adc->adc1->setSamplingSpeed(ADC_SAMPLING_SPEED::VERY_HIGH_SPEED); // change the sampling speed
#endif
}


void loop()
{
if (AUTO == 0)
{ serialInput(); //search for serial input of new variables
timeSave();
feedback();
analogWrite(Actinic, 0);
digitalWrite(Slave, LOW);
newdata=false; //reset PSI serial intake pipe
delay(1000);
}
if (AUTO == 1)
{ analogWrite(Actinic, 0);
digitalWrite(Slave, HIGH);
data(); //data aqcuisition
curvefitter(); //runs curve fit protocol
CURVEdataPrint(); //print normalized induction curves to serial
PHOTOdataPrint(); //print calculated photochemical values to serial
valpar = 0;
dataSav(); //write to SD card
serialInput(); //search for serial input of new variables
AUTO = 0;
digitalWrite(Slave, LOW);
SlaveReader();
delay(2000);
}
if (AUTO == 2)
{ serialInput(); //search for serial input of new variables
float LightCurve[14]= {0, 482, 487, 502, 515, 518, 521, 526, 531, 543, 568, 750, 950, 0};
//float LightCurve[17]= {0, 490, 510, 522, 526, 530, 534, 567, 770, 840, 910, 1100, 1300, 2000, 0, 0};
float LightCurveSteps[14] ={0, 10, 20, 45, 65, 90, 127, 218, 316, 520, 765, 1020, 2005, 0};
//float LightCurveSteps[17] ={0, 10, 20, 45, 65, 90, 118, 211, 310, 406, 504, 754, 1015, 1915, 0, 0};
digitalWrite(Slave, HIGH);
int STEPS = 14;
for (int W = 0; W < STEPS; W++)
{ float valued = (LightCurve[W]);
valpar = (LightCurveSteps[W]);
delay(DELAYED);
data(); //data aqcuisition
analogWrite(Actinic, valued);
curvefitter(); //runs curve fit protocol
CURVEdataPrint(); //print normalized induction curves to serial
PHOTOdataPrint(); //print calculated photochemical values to serial
dataSav(); //write to SD card
}
digitalWrite(Slave, LOW);
SlaveReader();
AUTO = 0;
}
if (AUTO == 3)
{ serialInput(); //search for serial input of new variables
//float LightCurve[8]={0, 300, 400, 2000, 3000, 3500, 3900, 4000};
float LightCurve[32]= {0, 0, 0, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 518, 518, 518, 518, 518, 518, 518, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
float LightCurveSteps[32] ={0, 0, 0, 520, 520, 520, 520, 520, 520, 520, 520, 520, 520, 520, 520, 90, 90, 90, 90, 90, 90, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
digitalWrite(Slave, HIGH);
int STEPS = 32;
for (int W = 0; W < STEPS; W++)
{ float valued = (LightCurve[W]);
valpar = (LightCurveSteps[W]);
delay(DELAYED);
data(); //data aqcuisition
analogWrite(Actinic, valued);
curvefitter(); //runs curve fit protocol
CURVEdataPrint(); //print normalized induction curves to serial
PHOTOdataPrint(); //print calculated photochemical values to serial
dataSav(); //write to SD card
}
digitalWrite(Slave, LOW);
SlaveReader();
AUTO = 0;
}
if (AUTO == 4)
{ serialInput(); //search for serial input of new variables
//float LightCurve[8]={0, 300, 400, 2000, 3000, 3500, 3900, 4000};
float LightCurve[36]= {0, 0, 0, 543, 543, 543, 543, 543, 543, 543, 543, 518, 518, 518, 518, 518, 518, 518, 568, 568, 568, 568, 568, 568, 568, 568, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
float LightCurveSteps[36] ={0, 0, 0, 520, 520, 520, 520, 520, 520, 520, 520, 90, 90, 90, 90, 90, 90, 90, 765, 765, 765, 765, 765, 765, 765, 765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
digitalWrite(Slave, HIGH);
int STEPS = 36;
for (int W = 0; W < STEPS; W++)
{ float valued = (LightCurve[W]);
valpar = (LightCurveSteps[W]);
delay(DELAYED);
data(); //data aqcuisition
analogWrite(Actinic, valued);
curvefitter(); //runs curve fit protocol
CURVEdataPrint(); //print normalized induction curves to serial
PHOTOdataPrint(); //print calculated photochemical values to serial
dataSav(); //write to SD card
}
digitalWrite(Slave, LOW);
SlaveReader();
AUTO = 0;
}
}


void data()
{ //Serial.println(dataFile);
for (int R = 0; R < REP; R++)
{
//Channel 0
i=0;
while (i<initial)
{ adc->adc0->isConverting();
adc->adc1->isConverting();
adc->adc0->isComplete();
adc->adc1->isComplete();
result=(uint16_t)adc->adc0->analogReadContinuous();
COL0PreS += result;
COL0PreR += 1;
i += 1;
delayMicroseconds(1);
}
digitalWriteFast(Col0, HIGH);
delayMicroseconds(5);
i=0;
while (i<sample0)
{ adc->adc0->isConverting();
adc->adc1->isConverting();
adc->adc0->isComplete();
adc->adc1->isComplete();
time=micros();
result=(uint16_t)adc->adc0->analogReadContinuous();
COL0Sig += result;
COL0Ref += 4095;
i += 1;
delayMicroseconds(1);
}
digitalWriteFast(Col0, LOW);
timepersample0 += (time[sample0-1]-time[0]);
delay(del);

//Channel 1
i=0;
while (i<initial)
{ adc->adc0->isConverting();
adc->adc1->isConverting();
adc->adc0->isComplete();
adc->adc1->isComplete();
result=(uint16_t)adc->adc0->analogReadContinuous();
COL1PreS += result;
COL1PreR += 1;
i += 1;
delayMicroseconds(1);
}
digitalWriteFast(Col1, HIGH);
delayMicroseconds(3);
i=0;
while (i<sample1)
{ adc->adc0->isConverting();
adc->adc1->isConverting();
adc->adc0->isComplete();
adc->adc1->isComplete();
time=micros();
result=(uint16_t)adc->adc0->analogReadContinuous();
COL1Sig += result;
COL1Ref += 4095;
i += 1;
delayMicroseconds(1);
}
digitalWriteFast(Col1, LOW);
timepersample1 += (time[sample1-1]-time[0]);
delay(del);

//Channel 2
i=0;
while (i<initial)
{ adc->adc0->isConverting();
adc->adc1->isConverting();
adc->adc0->isComplete();
adc->adc1->isComplete();
result=(uint16_t)adc->adc0->analogReadContinuous();
COL2PreS += result;
COL2PreR += 1;
i += 1;
delayMicroseconds(1);
}
digitalWriteFast(Col2, HIGH);
delayMicroseconds(3);
i=0;
while (i<sample2)
{ adc->adc0->isConverting();
adc->adc1->isConverting();
adc->adc0->isComplete();
adc->adc1->isComplete();
time=micros();
result=(uint16_t)adc->adc0->analogReadContinuous();
COL2Sig += result;
COL2Ref += 4095;
i += 1;
delayMicroseconds(1);
}
digitalWriteFast(Col2, LOW);
timepersample2 += (time[sample2-1]-time[0]);
delay(del);

//Channel 3
i=0;
while (i<initial)
{ adc->adc0->isConverting();
adc->adc1->isConverting();
adc->adc0->isComplete();
adc->adc1->isComplete();
result=(uint16_t)adc->adc0->analogReadContinuous();
COL3PreS += result;
COL3PreR += 1;
i += 1;
delayMicroseconds(1);
}
digitalWriteFast(Col3, HIGH);
delayMicroseconds(3);
i=0;
while (i<sample3)
{ adc->adc0->isConverting();
adc->adc1->isConverting();
adc->adc0->isComplete();
adc->adc1->isComplete();
time=micros();
result=(uint16_t)adc->adc0->analogReadContinuous();
COL3Sig += result;
COL3Ref += 4095;
i += 1;
delayMicroseconds(1);
}
digitalWriteFast(Col3, LOW);
timepersample3 += (time[sample3-1]-time[0]);
delay(del);
}

//Builds timing array based on Col0 excitation.
TIMEX0 = 0;
float perSample0 = (timepersample0/REP)/sample0;
sampletimey0 = perSample0;
//Serial.println(perSample0);
for (i=1;i<sample0;i++)
{
TIMEX0 = TIMEX0[i-1]+perSample0;
//Serial.println(TIMEX0);
}
timepersample0 = 0;

//Builds timing array based on Col1 excitation.
TIMEX1 = 0;
float perSample1 = (timepersample1/REP)/sample1;
sampletimey1 = perSample1;
//Serial.println(perSample);
for (i=1;i<sample1;i++)
{
TIMEX1 = TIMEX1[i-1]+perSample1;
}
timepersample1 = 0;

//Builds timing array based on Col2 excitation.
TIMEX2 = 0;
float perSample2 = (timepersample2/REP)/sample2;
sampletimey2 = perSample2;
//Serial.println(perSample);
for (i=1;i<sample2;i++)
{
TIMEX2 = TIMEX2[i-1]+perSample2;
}
timepersample2 = 0;

//Builds timing array based on Col3 excitation.
TIMEX3 = 0;
float perSample3 = (timepersample3/REP)/sample3;
sampletimey3 = perSample3;
//Serial.println(perSample);
for (i=1;i<sample3;i++)
{
TIMEX3 = TIMEX3[i-1]+perSample3;
}
timepersample3 = 0;

//INITIAL OFFSET REMOVES ambient stray light from Fo readings
float SCOL0Pre = COL0PreS/initial;
float RCOL0Pre = COL0PreR/initial;

float SCOL1Pre = COL1PreS/initial;
float RCOL1Pre = COL1PreR/initial;

float SCOL2Pre = COL2PreS/initial;
float RCOL2Pre = COL2PreR/initial;

float SCOL3Pre = COL3PreS/initial;
float RCOL3Pre = COL3PreR/initial;

//RESULTS-AVERAGING
for (i=0;i<sample0;i++)
{
COL0AveSig = ((COL0Sig-SCOL0Pre)/REP);
COL0AveRef = ((COL0Ref-RCOL0Pre)/REP);
COL0Norm = COL0AveSig; //test
COL0Sig = 0;
COL0Ref = 0;
COL0PreS = 0;
COL0PreR = 0;
}

for (i=0;i<sample1;i++)
{
COL1AveSig = ((COL1Sig-SCOL1Pre)/REP);
COL1AveRef = ((COL1Ref-RCOL1Pre)/REP);
COL1Norm = COL1AveSig; //test
COL1Sig = 0;
COL1Ref = 0;
COL1PreS = 0;
COL1PreR = 0;
}

for (i=0;i<sample2;i++)
{
COL2AveSig = ((COL2Sig-SCOL2Pre)/REP);
COL2AveRef = ((COL2Ref-RCOL2Pre)/REP);
COL2Norm = COL2AveSig; //test
COL2Sig = 0;
COL2Ref = 0;
COL2PreS = 0;
COL2PreR = 0;
}

for (i=0;i<sample3;i++)
{
COL3AveSig = ((COL3Sig-SCOL3Pre)/REP);
COL3AveRef = ((COL3Ref-RCOL3Pre)/REP);
COL3Norm = COL3AveSig; //test
COL3Sig = 0;
COL3Ref = 0;
COL3PreS = 0;
COL3PreR = 0;
}
}

void curvefitter()
{
COL0fit= 0;
COL0LINREG= 0;
LREGdataAnalysis(COL0Norm, COL0LINREG, COL0fit, TIMEX0, sample0, PARcol0);

COL1fit= 0;
COL1LINREG= 0;
LREGdataAnalysis(COL1Norm, COL1LINREG, COL1fit, TIMEX1, sample1, PARcol1);

COL2fit= 0;
COL2LINREG= 0;
LREGdataAnalysis(COL2Norm, COL2LINREG, COL2fit, TIMEX2, sample2, PARcol2);

COL3fit= 0;
COL3LINREG= 0;
LREGdataAnalysis(COL3Norm, COL3LINREG, COL3fit, TIMEX3, sample3, PARcol3);
}


void LREGdataAnalysis(float*Fluor, float*LINREGG, float*curvefit1, float*TIMEX, int sample, int SIGer)
{
float sum_x=0.000;
float sum_y=0.000;
float sum_xy=0.000;
float sum_xx=0.000;
float sum_yy=0.000;
int lineA = 2;
int lineB = 14;
int lineC = lineB-lineA;
int MAXinit = sample-5;
int maxAve = 0;
int Residual =0;
float FoX1 = 1.000;
float FmX1 = 2.000;
float SigX1 = 0.0200;
float FmX2 = 0.2000;
float SigX2 = 0.0020;
float FmX3 = 0.0200;
float SigX3 = 0.0002;
float Fo = 0.0000;
float Fm = 0.0000;
float Sig = 0.0000;
float LINREG[4]={0.000,0.000,0.000,0.000};
float curvefit2[BEEFY];
float minimumFo = 0.0000;
float minimumFm = 0.0000;
float minimumSig = 0.0000;
float minimumRES = 10000000;

for (int i=lineA; i<lineB;i++)
{
sum_x = sum_x+TIMEX;
sum_y = sum_y+Fluor;
sum_xy = sum_xy+TIMEX*Fluor;
sum_xx = sum_xx+TIMEX*TIMEX;
sum_yy = sum_yy+Fluor*Fluor;
}

LINREG[0]=(lineC*sum_xy-sum_x*sum_y)/(lineC*sum_xx-sum_x*sum_x);
LINREG[1]=(sum_y/lineC)-((LINREG[0]*sum_x)/lineC);

for (int i=MAXinit; i<sample;i++)
{
maxAve += Fluor;
}

LINREG[2]= maxAve/(sample-MAXinit);
LINREG[3]= (LINREG[2]-LINREG[1])/LINREG[2];

for (i=1;i<12;i++)
{
Fm = ((LINREG[2]-(FmX1*5)) + (FmX1*i));
for (t=1;t<20;t++)
{
Sig = ((0.1-(SigX1*5)) + (SigX1*t));
for (g=3;g<sample+1;g=g+increment)
{
curvefit2[g] = LINREG[1] + (Fm-LINREG[1])*(1-exp(-(Sig*g)));
Residual += (Fluor[g]-curvefit2[g])*(Fluor[g]-curvefit2[g]);
}
if (Residual < minimumRES)
{
minimumFo = LINREG[1];
minimumFm = Fm;
minimumSig = Sig;
minimumRES = Residual;
//Serial.print(minimumRES);
//Serial.print(' ');
}
Residual = 0;
}
}

for (i=1;i<12;i++)
{
Fm = ((minimumFm-(FmX2*5)) + (FmX2*i));
for (t=1;t<12;t++)
{
Sig = ((minimumSig-(SigX2*5)) + (SigX2*t));
for (g=3;g<sample+1;g=g+increment)
{
curvefit2[g] = LINREG[1] + (Fm-LINREG[1])*(1-exp(-(Sig*g)));
Residual += (Fluor[g]-curvefit2[g])*(Fluor[g]-curvefit2[g]);
}
if (Residual < minimumRES)
{
minimumFo = LINREG[1];
minimumFm = Fm;
minimumSig = Sig;
minimumRES = Residual;
//Serial.print(minimumRES);
//Serial.print(' ');
}
Residual = 0;
}
}

for (i=1;i<12;i++)
{
Fm = ((minimumFm-(FmX3*5)) + (FmX3*i));
for (t=1;t<12;t++)
{
Sig = ((minimumSig-(SigX3*5)) + (SigX3*t));
for (g=3;g<sample+1;g=g+increment)
{
curvefit2[g] = LINREG[1] + (Fm-LINREG[1])*(1-exp(-(Sig*g)));
Residual += (Fluor[g]-curvefit2[g])*(Fluor[g]-curvefit2[g]);
}
if (Residual < minimumRES)
{
minimumFo = LINREG[1];
minimumFm = Fm;
minimumSig = Sig;
minimumRES = Residual;
//Serial.print(minimumRES);
//Serial.print(' ');
}
Residual = 0;
}
}

for (i=1;i<22;i++)
{
Fm = minimumFm;
Sig = minimumSig;
Fo = ((minimumFo-(FoX1*10)) + (FoX1*i));
for (g=3;g<sample+1;g=g+increment)
{
curvefit2[g] = Fo + (Fm-Fo)*(1-exp(-(Sig*g)));
Residual += (Fluor[g]-curvefit2[g])*(Fluor[g]-curvefit2[g]);
}
if (Residual < minimumRES)
{
minimumFo = Fo;
minimumFm = Fm;
minimumSig = Sig;
minimumRES = Residual;
//Serial.println(minimumRES);
}
Residual = 0;

}

for (g=1;g<sample+1;g++)
{
curvefit1[g] = minimumFo + (minimumFm-minimumFo)*(1-exp(-(minimumSig*g)));
}
LINREGG[0] = curvefit1[1];
LINREGG[1] = curvefit1[sample];
LINREGG[2] = minimumSig/SIGer*1000000;
LINREGG[3] = ((curvefit1[sample]-curvefit1[1])/curvefit1[sample]);
LINREGG[4] = minimumRES;
}


void CURVEdataPrint()
{
for (i=1;i<sample0;i++)
{
Serial.print(TIMEX0,4);
Serial.print(' ');
Serial.print(COL0Norm,4);
Serial.print(' ');
Serial.print(COL0fit,4);
Serial.print(' ');
Serial.println("CURVES0");
}

for (i=1;i<sample1;i++)
{
Serial.print(TIMEX1,4);
Serial.print(' ');
Serial.print(COL1Norm,4);
Serial.print(' ');
Serial.print(COL1fit,4);
Serial.print(' ');
Serial.println("CURVES1");
}

for (i=1;i<sample2;i++)
{
Serial.print(TIMEX2,4);
Serial.print(' ');
Serial.print(COL2Norm,4);
Serial.print(' ');
Serial.print(COL2fit,4);
Serial.print(' ');
Serial.println("CURVES2");
}

for (i=1;i<sample3;i++)
{
Serial.print(TIMEX3,4);
Serial.print(' ');
Serial.print(COL3Norm,4);
Serial.print(' ');
Serial.print(COL3fit,4);
Serial.print(' ');
Serial.println("CURVES3");
}
Serial.print("END");
Serial.print(' ');
Serial.print("END");
Serial.print(' ');
Serial.print("END");
Serial.print(' ');
Serial.println("END");
Serial.flush();
}


void PHOTOdataPrint()
{
Serial.print(COL0LINREG[1],4);
Serial.print(' ');
Serial.print(COL1LINREG[1],4);
Serial.print(' ');
Serial.print(COL2LINREG[1],4);
Serial.print(' ');
Serial.print(COL3LINREG[1],4);
Serial.print(' ');
Serial.print(COL0LINREG[2],4);
Serial.print(' ');
Serial.print(COL1LINREG[2],4);
Serial.print(' ');
Serial.print(COL2LINREG[2],4);
Serial.print(' ');
Serial.print(COL3LINREG[2],4);
Serial.print(' ');
Serial.print(COL0LINREG[3],4);
Serial.print(' ');
Serial.print(COL1LINREG[3],4);
Serial.print(' ');
Serial.print(COL2LINREG[3],4);
Serial.print(' ');
Serial.print(COL3LINREG[3],4);
Serial.print(' ');
Serial.print(now());
Serial.print(' ');
Serial.println("PHOTOCHEM");
Serial.flush();
}

void dataSav()
{
if (SD.exists(curvesFile.c_str()))
{ myFile = SD.open(curvesFile.c_str(), FILE_WRITE);
myFile.print("Time");
myFile.print(',');
myFile.print(year());
myFile.print(',');
myFile.print(month());
myFile.print(',');
myFile.print(day());
myFile.print(',');
myFile.print(hour());
myFile.print(',');
myFile.print(minute());
myFile.print(',');
myFile.print(second());
myFile.print(',');
myFile.print(now());
myFile.print(',');
myFile.print(valpar);
myFile.println();
//Col0
myFile.print("Col0norm");
for (i=1;i<sample0;i++)
{
myFile.print(',');
myFile.print(COL0Norm,4);
}
myFile.println();
//Col1
myFile.print("Col1norm");
for (i=1;i<sample1;i++)
{
myFile.print(',');
myFile.print(COL1Norm,4);
}
myFile.println();
//Col2
myFile.print("Col2norm");
for (i=1;i<sample2;i++)
{
myFile.print(',');
myFile.print(COL2Norm,4);
}
myFile.println();
//Col3
myFile.print("Col3norm");
for (i=1;i<sample3;i++)
{
myFile.print(',');
myFile.print(COL3Norm,4);
}
myFile.println();
myFile.close();
}
else
{ File myFile = SD.open(curvesFile.c_str(), FILE_WRITE);
myFile.print("Time");
myFile.print(',');
myFile.print(year());
myFile.print(',');
myFile.print(month());
myFile.print(',');
myFile.print(day());
myFile.print(',');
myFile.print(hour());
myFile.print(',');
myFile.print(minute());
myFile.print(',');
myFile.print(second());
myFile.print(',');
myFile.print(now());
myFile.print(',');
myFile.print(valpar);
myFile.println();
//Col0
myFile.print("Col0norm");
for (i=1;i<sample0;i++)
{
myFile.print(',');
myFile.print(COL0Norm,4);
}
myFile.println();
//Col1
myFile.print("Col1norm");
for (i=1;i<sample1;i++)
{
myFile.print(',');
myFile.print(COL1Norm,4);
}
myFile.println();
//Col2
myFile.print("Col2norm");
for (i=1;i<sample2;i++)
{
myFile.print(',');
myFile.print(COL2Norm,4);
}
myFile.println();
//Col3
myFile.print("Col3norm");
for (i=1;i<sample3;i++)
{
myFile.print(',');
myFile.print(COL3Norm,4);
}
myFile.println();
myFile.close();
}

if (SD.exists(dataFile.c_str()))
{ myFile2 = SD.open(dataFile.c_str(), FILE_WRITE);
myFile2.print("Time");
myFile2.print(',');
myFile2.print(year());
myFile2.print(',');
myFile2.print(month());
myFile2.print(',');
myFile2.print(day());
myFile2.print(',');
myFile2.print(hour());
myFile2.print(',');
myFile2.print(minute());
myFile2.print(',');
myFile2.print(second());
myFile2.print(',');
myFile2.print(now());
myFile2.print(',');
myFile2.print(valpar);
myFile2.print(',');
myFile2.print(COL0LINREG[0],4);
myFile2.print(',');
myFile2.print(COL0LINREG[1],4);
myFile2.print(',');
myFile2.print(COL0LINREG[2],4);
myFile2.print(',');
myFile2.print(COL0LINREG[3],4);
myFile2.print(',');
myFile2.print(COL0LINREG[4],4);
myFile2.print(',');
myFile2.print(COL1LINREG[0],4);
myFile2.print(',');
myFile2.print(COL1LINREG[1],4);
myFile2.print(',');
myFile2.print(COL1LINREG[2],4);
myFile2.print(',');
myFile2.print(COL1LINREG[3],4);
myFile2.print(',');
myFile2.print(COL1LINREG[4],4);
myFile2.print(',');
myFile2.print(COL2LINREG[0],4);
myFile2.print(',');
myFile2.print(COL2LINREG[1],4);
myFile2.print(',');
myFile2.print(COL2LINREG[2],4);
myFile2.print(',');
myFile2.print(COL2LINREG[3],4);
myFile2.print(',');
myFile2.print(COL2LINREG[4],4);
myFile2.print(',');
myFile2.print(COL3LINREG[0],4);
myFile2.print(',');
myFile2.print(COL3LINREG[1],4);
myFile2.print(',');
myFile2.print(COL3LINREG[2],4);
myFile2.print(',');
myFile2.print(COL3LINREG[3],4);
myFile2.print(',');
myFile2.print(COL3LINREG[4],4);
myFile2.println();
myFile2.close();
}
else
{ File myFile2 = SD.open(dataFile.c_str(), FILE_WRITE);
myFile2.print("Time");
myFile2.print(',');
myFile2.print("year");
myFile2.print(',');
myFile2.print("month");
myFile2.print(',');
myFile2.print("day");
myFile2.print(',');
myFile2.print("hour");
myFile2.print(',');
myFile2.print("minute");
myFile2.print(',');
myFile2.print("second");
myFile2.print(',');
myFile2.print("compTime");
myFile2.print(',');
myFile2.print("PAR");
myFile2.print(',');
myFile2.print("COL0-Fo");
myFile2.print(',');
myFile2.print("COL0-Fm");
myFile2.print(',');
myFile2.print("COL0-Sig");
myFile2.print(',');
myFile2.print("COL0-fvfm");
myFile2.print(',');
myFile2.print("COL0-resid");
myFile2.print(',');
myFile2.print("COL1-Fo");
myFile2.print(',');
myFile2.print("COL1-Fm");
myFile2.print(',');
myFile2.print("COL1-Sig");
myFile2.print(',');
myFile2.print("COL1-fvfm");
myFile2.print(',');
myFile2.print("COL1-resid");
myFile2.print(',');
myFile2.print("COL2-Fo");
myFile2.print(',');
myFile2.print("COL2-Fm");
myFile2.print(',');
myFile2.print("COL2-Sig");
myFile2.print(',');
myFile2.print("COL2-fvfm");
myFile2.print(',');
myFile2.print("COL2-resid");
myFile2.print(',');
myFile2.print("COL3-Fo");
myFile2.print(',');
myFile2.print("COL3-Fm");
myFile2.print(',');
myFile2.print("COL3-Sig");
myFile2.print(',');
myFile2.print("COL3-fvfm");
myFile2.print(',');
myFile2.print("COL3-resid");
myFile2.println();

myFile2.print("Time");
myFile2.print(',');
myFile2.print(year());
myFile2.print(',');
myFile2.print(month());
myFile2.print(',');
myFile2.print(day());
myFile2.print(',');
myFile2.print(hour());
myFile2.print(',');
myFile2.print(minute());
myFile2.print(',');
myFile2.print(second());
myFile2.print(',');
myFile2.print(now());
myFile2.print(',');
myFile2.print(valpar);
myFile2.print(',');
myFile2.print(COL0LINREG[0],4);
myFile2.print(',');
myFile2.print(COL0LINREG[1],4);
myFile2.print(',');
myFile2.print(COL0LINREG[2],4);
myFile2.print(',');
myFile2.print(COL0LINREG[3],4);
myFile2.print(',');
myFile2.print(COL0LINREG[4],4);
myFile2.print(',');
myFile2.print(COL1LINREG[0],4);
myFile2.print(',');
myFile2.print(COL1LINREG[1],4);
myFile2.print(',');
myFile2.print(COL1LINREG[2],4);
myFile2.print(',');
myFile2.print(COL1LINREG[3],4);
myFile2.print(',');
myFile2.print(COL1LINREG[4],4);
myFile2.print(',');
myFile2.print(COL2LINREG[0],4);
myFile2.print(',');
myFile2.print(COL2LINREG[1],4);
myFile2.print(',');
myFile2.print(COL2LINREG[2],4);
myFile2.print(',');
myFile2.print(COL2LINREG[3],4);
myFile2.print(',');
myFile2.print(COL2LINREG[4],4);
myFile2.print(',');
myFile2.print(COL3LINREG[0],4);
myFile2.print(',');
myFile2.print(COL3LINREG[1],4);
myFile2.print(',');
myFile2.print(COL3LINREG[2],4);
myFile2.print(',');
myFile2.print(COL3LINREG[3],4);
myFile2.print(',');
myFile2.print(COL3LINREG[4],4);
myFile2.println();
myFile2.close();
}
}

void SlaveReader()
{ Serial.print("read ");
static boolean recvinprogress=false;
static byte ndx=0;
char startmarker='<';
char comma=',';
char endmarker='>';
char c;

while(Serial4.available()>0 && newdata==false)
{
c=Serial4.read();
if(c==startmarker)recvinprogress=true;
else if(c==endmarker)
{
recvinprogress=false;
ndx=0;
newdata=true;
}
if(recvinprogress==true)
{
if(c==comma)
{ for(int i =0;i<ndx;i++)
{ Serial.print(recvchars);
}
ndx=0;
Serial.println();
}
if(c!=comma)
{ recvchars[ndx]=c;
ndx++;
}
}
}
}






// if (SD.exists(PSIFile.c_str()))
// { myFile3 = SD.open(PSIFile.c_str(), FILE_WRITE);
// myFile3.print("Time");
// myFile3.print(',');
// myFile3.print(year());
// myFile3.print(',');
// myFile3.print(month());
// myFile3.print(',');
// myFile3.print(day());
// myFile3.print(',');
// myFile3.print(hour());
// myFile3.print(',');
// myFile3.print(minute());
// myFile3.print(',');
// myFile3.print(second());
// myFile3.print(',');
// myFile3.print(now());
// myFile3.print(',');
// myFile3.print(valpar);
// myFile3.println();
// //Col0
// //myFile3.print("PSI");
// Serial.print("PSI");
// int a = Wire.available();
// Wire.requestFrom(2,a);
// for (int i = 0; i < a; i++)
// {
// //myFile3.print(',');
// //myFile3.print(Wire.read());
// Serial.print(',');
// Serial.print(Wire.read());
// }
// myFile3.println();
// myFile3.close();
// }
// else
// { File myFile3 = SD.open(PSIFile.c_str(), FILE_WRITE);
// myFile3.print("Time");
// myFile3.print(',');
// myFile3.print(year());
// myFile3.print(',');
// myFile3.print(month());
// myFile3.print(',');
// myFile3.print(day());
// myFile3.print(',');
// myFile3.print(hour());
// myFile3.print(',');
// myFile3.print(minute());
// myFile3.print(',');
// myFile3.print(second());
// myFile3.print(',');
// myFile3.print(now());
// myFile3.print(',');
// myFile3.print(valpar);
// myFile3.println();
// //Col0
// myFile3.print("PSI");
// Serial.print("PSI");
// int a = Wire.available();
// Wire.requestFrom(2,a);
// for (int i = 0; i < a; i++)
// {
// //myFile3.print(',');
// //myFile3.print(Wire.read());
// Serial.print(',');
// Serial.print(Wire.read());
// }
// myFile3.println();
// myFile3.close();
// }
//}


void serialInput()
{
while (Serial.available() > 0)
{ String dats = Serial.readStringUntil('STOP');
int first = dats.indexOf(',');
String firsty = dats.substring(0,first);
int seconds = dats.indexOf(',', first+1);
String secondy = dats.substring(first+1,seconds);
int thirds = dats.indexOf(',', seconds+1);
String thirdy = dats.substring(seconds+1,thirds);
int fourths = dats.indexOf(',', thirds+1);
String fourthy = dats.substring(thirds+1,fourths);
int fifths = dats.indexOf(',', fourths+1);
String fifthy = dats.substring(fourths+1,fifths);
int six = dats.indexOf(',', fifths+1);
String sixth = dats.substring(fifths+1,six);
int seven = dats.indexOf(',', six+1);
String seventh = dats.substring(six+1,seven);
int eight = dats.indexOf(',', seven+1);
String eighth = dats.substring(seven+1,eight);
int nine = dats.indexOf(',', eight+1);
String ninth = dats.substring(eight+1,nine);

DELAYED = firsty.toFloat()*1000;
REP = secondy.toFloat();
del = thirdy.toFloat();
AUTO = fifthy.toFloat();
sample0 = sixth.toFloat()/sampletimey0;
sample1 = seventh.toFloat()/sampletimey1;
sample2 = eighth.toFloat()/sampletimey2;
sample3 = ninth.toFloat()/sampletimey3;
String namer1 = fourthy + "PSII.csv";
String namer2 = fourthy + ".txt";
String namer3 = fourthy + "PSI.csv";
curvesFile.replace(curvesFile, namer1);
dataFile.replace(dataFile, namer2);
PSIFile.replace(PSIFile, namer3);
}
}


void timeSave()
{
//Initialize the SD card
Serial.println("Initializing SD card...");
if (!SD.begin(chipSelect))
{ Serial.println("initialization failed!");
}
else
{ Serial.println("initialization done.");
}

//Synchronize Time
setSyncProvider(getTeensy3Time);
if (!Serial);
if (timeStatus() != timeSet)
{ Serial.println("Unable to sync with the RTC");
}
else
{ Serial.println("RTC has set the system time");
}
}

void feedback()
{
float valued = 3000;
analogWrite(Actinic, valued);
}

time_t getTeensy3Time()
{
return Teensy3Clock.get();
}

void adc0_isr(void)
{
adc->adc0->analogReadContinuous();
}
#ifdef ADC_DUAL_ADCS
void adc1_isr(void)
{
adc->adc1->analogReadContinuous();
}
#endif
 
Internally the Wire library uses relatively small buffers. You might need to edit the library code to increase the buffer size.
 
Oh, opps, sorry - seeing a mix of Serial and I2C as I quickly go through pending forum questions.

Serial also has buffers which are of course completely separate from the Wire library for I2C. Usually you would want to design your code to read data from the hardware serial port as soon as possible and put it into your own buffer, so it can't be overwritten if more data arrives. I didn't have time to read that lengthy code, but it did see only 9600 baud. Usually that's slow enough that the buffer size isn't an issue unless you code does something like intentionally not reading until available() returns a larger number.

For really high baud rates, either very careful design of timing of your program or larger buffers or use of RTS/CTS flow control is often needed.
 
Status
Not open for further replies.
Back
Top