Hello, I am working with an Arduino Uno that is master and its job is to do calculation and output to an android app, while the Arduino Micro is a PID heater and acts as a slave. My issue is that the Micro seems to give data successfully everything, while the UNO will receive the data for random periods of time, and while just freeze and will not recover unless I reset the UNO. I want to know what the issue is and some solutions.
Master
#include <Wire.h> /////////ADDED 10-21-2021
//#include <I2C.h>
//Define Slave I2C Address /////////ADDED 10-21-2021
#define SLAVE_ADDR 9
//Define Slave Answer Size
#define ANSWERSIZE 6 /////////ADDED 10-21-2021
void setup() {
Serial.begin(38400);
Wire.begin();
void loop() {
Wire.requestFrom(SLAVE_ADDR,ANSWERSIZE);
// I2c.requestFrom(SLAVE_ADDR,ANSWERSIZE);
// Add Characters to string
String response = "";
while (Wire.available()) {
char b = Wire.read();
response += b;
Serial.print("Reading Data ");
Serial.println(response);
}
Serial.println("Temp Received");
Serial.println(response);
String Thermal =response;
}
SLAVE CODE
//SLAVE
#include <Wire.h>
#include <SPI.h>
#define MAX6675_CS 10
#define MAX6675_SO 12
#define MAX6675_SCK 9
// Define Slave I2C Address
#define SLAVE_ADDR 9
//Define Slave Answer Size
#define ANSWERSIZE 6
String answer = "0";
int PD0_pin = 11;
//Variables
float temperature_read1 = 0;
float set_temperature1 =295;
float PID_error1 = 0;
float previous_error1 = 0;
float elapsedTime1, Time1, timePrev1;
int PID_value1 = 0;
//PID constants
int kp1 = 7; double ki1 = .1; int kd1 = 0;
int PID_p1 = 0; double PID_i1 =0; int PID_d1 = 0;
void setup(){
//Start serial connection
Serial.begin(38400);
pinMode(PD0_pin,OUTPUT);
/////////////////////////////////TCCR0B = TCCR0B & B11111000 | 0x03; // pin 3 and 11 PMW frequency of 980.39 Hz
Time1 = millis();
//Initialize I2C Communications as Slave
Wire.begin(SLAVE_ADDR);
//Function to Run when Data request from master
Wire.onRequest(requestEvent);
//Function to run when data received from master
Wire.onReceive(receiveEvent);
Serial.println("Start");
}
////////////////////FOR I2CCOMMUNICATION RECEIVING DATA//////////////////////////////////////
void receiveEvent() {
// Read while data received
while (0 < Wire.available()) {
byte x = Wire.read();
//Serial.print("Receive event ");
// Serial.println(x);
}
// Print to Serial Monitor
////Serial.print("Receive event");
//Serial.println(x);
}
////////////////////FOR I2CCOMMUNICATION RECEIVING DATA END///////////////////////////////////////////////////////////
////////////////////FOR I2CCOMMUNICATION SENDING DATA//////////////////////////////////////
void requestEvent() {
// Setup byte variable in the correct size
byte response[ANSWERSIZE];
// Format answer as array
for (byte i=0;i<ANSWERSIZE;i++) {
response[i] = (byte)answer.charAt(i);
}
// Send response back to Master
Wire.write(response,sizeof(response));
//delay(300);
// Print to Serial Monitor
// Serial.print("Request event value sent is ");
// Serial.println(answer);
}
///////////////////////////////FOR I2CCOMMUNICATION SENDING DATA END///////////////////////////////////////////////////////////////
//////////////////////PID CONTROL/////////////////////////////////////////////////////////////
void loop() {
// First we read the real value of temperature
float temperature_read1 = readThermocouple();
//Defube String with Resposne to Master
answer = String(temperature_read1);
Serial.print("Test Value was ");
Serial.println(answer);
requestEvent();
//Next we calculate the error between the setpoint and the real value
PID_error1 = set_temperature1 - temperature_read1;
//Calculate the P value
PID_p1 = kp1 * PID_error1;
//Calculate the I value in a range on +/-20
if(PID_error1 > -20 && PID_error1 <20) //removed because was not useful
{
//if (temperature_read1 > 330)
//{PID_i1=0;}
PID_i1 = PID_i1 + (ki1 * PID_error1);
}
//For derivative we need real time to calculate speed change rate
timePrev1 = Time1; // the previous time is stored before the actual time read
Time1 = millis(); // actual time read
elapsedTime1 = (Time1 - timePrev1) / 1000;
//Now we can calculate the D calue
PID_d1 = kd1*((PID_error1 - previous_error1)/elapsedTime1);
//Final total PID value is the sum of P + I + D
PID_value1 = PID_p1 + PID_i1 + PID_d1;
Serial.print("PID Value ");
//PID_value1 =125;
Serial.println(PID_value1);
Serial.print("P Value ");
Serial.println(PID_p1);
Serial.print("I Value ");
//int PID_Value_True= 255 - PID_value1;
Serial.println(PID_i1);
Serial.print("Error ");
Serial.println(PID_error1);
//We define PWM range between 0 and 325 (cannot be 325 as the highest value is 255, changed)
if(PID_value1 < 0)
{ PID_value1 = 0; }
if(PID_value1 > 255)
{ PID_value1 = 255; }
//Now we can write the PWM signal to the mosfet on digital pin D3
analogWrite(PD0_pin,PID_value1);
previous_error1 = PID_error1; //Remember to store the previous error for next loop.
delay(1000);
// while (!SD.begin(chipSelect)) {
//digitalWrite(7, HIGH);
// wait for SD card
//delay(500);
//digitalWrite(7,LOW);
//delay(50); }
//if (!SD.exists("Data")) {
// SD.mkdir("Data");}
Serial.print("PID TEMP control ");
Serial.print("S:");
Serial.println(set_temperature1);
Serial.print("R:");
Serial.println(temperature_read1);
//Serial.print("DATA,TIME,");
//Serial.println(temperature_read1);
}
//////////////////////PID CONTROL END/////////////////////////////////////////////////////////////
/////////////////////SPI TEMP CONVERSION FUNCTION/////////////////////////////////////////////
double readThermocouple() {
uint16_t v;
pinMode(MAX6675_CS, OUTPUT);
pinMode(MAX6675_SO, INPUT);
pinMode(MAX6675_SCK, OUTPUT);
digitalWrite(MAX6675_CS, LOW);
delay(1);
// Read in 16 bits,
// 15 = 0 always
// 14..2 = 0.25 degree counts MSB First
// 2 = 1 if thermocouple is open circuit
// 1..0 = uninteresting status
v = shiftIn(MAX6675_SO, MAX6675_SCK, MSBFIRST);
v <<= 8;
v |= shiftIn(MAX6675_SO, MAX6675_SCK, MSBFIRST);
digitalWrite(MAX6675_CS, HIGH);
if (v & 0x4)
{
// Bit 2 indicates if the thermocouple is disconnected
return NAN;
}
// The lower three bits (0,1,2) are discarded status bits
v >>= 3;
// The remaining bits are the number of 0.25 degree (C) counts
return v*0.25;
}
/////////////////////SPI TEMP CONVERSION FUNCTION END////////////////////////////////////////////