At no point in your code do you actually read the CHANNELx & FAULT_x pins so the DIAGNOSTIC data is meaningless.
If the Arduino is expected to do nothing else but generate the diagnostics data then there is probably no need to change it to make it more efficient but if your wanting to do other things as well then on initial inspection I would probably use a timer interrupt set to a 50ms interval to push out the data.
Riva:
At no point in your code do you actually read the CHANNELx & FAULT_x pins so the DIAGNOSTIC data is meaningless.
If the Arduino is expected to do nothing else but generate the diagnostics data then there is probably no need to change it to make it more efficient but if your wanting to do other things as well then on initial inspection I would probably use a timer interrupt set to a 50ms interval to push out the data.
The code will do other tasks, it would need that while it was sending this diagnostic signal to carry out the other tasks. I changed the code, because really he was not reading any signal.
Robin2:
Without a description of what you are trying to diagnose I can't make sense of your diagram.
Your program has several IF tests but seems to have no code to collect the data for those tests.
...R
The program should read the 4 digital inputs that will inform if the CHANNELX signals are active or not. It will also read 2 digital inputs(FAULT_1 or FAULT_2) that will tell you if there is a fault in the system or not. It should generate a continuous signal as described in the post image. The program will also perform other tasks, such as generating pwm signal, reading analog ports, calculating temperature, etc. The difficulty at the moment is to generate this DIAGNOSTIC signal interruptly while performing the other tasks.
JonasSilva:
The program should read the 4 digital inputs that will inform if the CHANNELX signals are active or not. It will also read 2 digital inputs(FAULT_1 or FAULT_2) that will tell you if there is a fault in the system or not.
That's not going to happen unless you have the appropriate digitalRead()s in your program.
It should generate a continuous signal as described in the post image.
Your image probably makes sense to you but I don't understand how it should be created. Start by describing the sequence of events that should happen for a single input.
JonasSilva:
It should generate a continuous signal as described in the post image. The program will also perform other tasks, such as generating pwm signal, reading analog ports, calculating temperature, etc. The difficulty at the moment is to generate this DIAGNOSTIC signal interruptly while performing the other tasks.
Have a look at the attached code. It will hopefully do the required continual diagnostics using interrupts and all you need to do in loop is to construct the next set of diagnostic data to send else the ISR will just send the last values again and again.
I will leave it to you to determine how it works but if you get stuck in figuring it out then please ask.
Riva:
Have a look at the attached code. It will hopefully do the required continual diagnostics using interrupts and all you need to do in loop is to construct the next set of diagnostic data to send else the ISR will just send the last values again and again.
I will leave it to you to determine how it works but if you get stuck in figuring it out then please ask.
Thank you Riva, that's almost what I need. What should I change in the code to define how often the diagnostic signal is sent? I need it sent every 2 seconds.
What is the function "void dec2bin32 (uint32_t myNum, NumberOfBits byte)" ?
JonasSilva:
What should I change in the code to define how often the diagnostic signal is sent? I need it sent every 2 seconds.
Ha, you just moved the goalposts. Your original post says "I need help to generate a constant diagnostic signal with the arduino.", you mentioned nothing about every two seconds.
I'm at work this weekend but will hopefully get time to change the code to suit your needs. The simple way would be to use a uint64_t data type and just add 20 zero bits on to generate 1 second silence and then the diagnostic data.
JonasSilva:
What is the function "void dec2bin32 (uint32_t myNum, NumberOfBits byte)" ?
It is just a bit of code to display the constructed diag data during testing. Just delete it or remove the call to it from loop.
EDIT: In a slack moment I changed to code to send diag data every 2 seconds instead of continually.
To save confusion I have commented out all code I used for testing
Riva:
Ha, you just moved the goalposts. Your original post says "I need help to generate a constant diagnostic signal with the arduino.", you mentioned nothing about every two seconds.
I'm at work this weekend but will hopefully get time to change the code to suit your needs. The simple way would be to use a uint64_t data type and just add 20 zero bits on to generate 1 second silence and then the diagnostic data.
It is just a bit of code to display the constructed diag data during testing. Just delete it or remove the call to it from loop.
EDIT: In a slack moment I changed to code to send diag data every 2 seconds instead of continually.
To save confusion I have commented out all code I used for testing
I'm sorry I did not talk about the 2 seconds earlier. I have a question, while the program is not sending the signal can I perform other tasks? Or will he be interrupted for these 2 seconds?
I need to put what's in the code below with what you did. Basically it reads 3 NTCs and generates a pwm signal on 2 different ports.
I've attached the two codes together, could you see if it works that way?
const int NTC_Pin = 8;
const int NTC_Pin2 = 9;
const int NTC_Pin3 = 10;
const int Vout = 11;
const int Vout2 = 12;
const int SAMPLES = 5;
const int RESISTOR_SERIE_LB = 9710.0;
const int RESISTOR_SERIE_HB = 9710.0;
const float RCS = 0.15;
const int RESISTOR_SERIE_LDD = 9710.0;
const float RCS2 = 0.15;
const int MAX_ADC = 1023.0;
const float BETA = 3974.0;
const float BETA_HB = 3974.0;
const float BETA_LDD = 3974.0;
const int TEMP_AMB = 298.15;
const int NTC_TEMP_LB = 10000.0;
const int NTC_TEMP_HB = 10000.0;
const int NTC_TEMP_LDD = 10000.0;
int tempAtual = 0;
int tempAtual_HB = 0;
int tempAtual_LDD = 0;
float I = 0;
float Viadj = 0;
int pwmvalor = 0;
float I2 = 0;
float Viadj2 = 0;
int pwmvalor2 = 0;
int aux = 0;
void setup() {
pinMode(NTC_Pin,INPUT);
pinMode(Vout,OUTPUT);
pinMode(NTC_Pin2,INPUT);
pinMode(Vout2,OUTPUT);
pinMode(NTC_Pin3,INPUT);
}
void loop() {
//---------------------------- NTC ---------------------------------//
if(digitalRead(CHANNEL3==HIGH))
{
tempAtual = readThermistor();
if (tempAtual <= 25)
{
I=1;
}
if (tempAtual > 25 && tempAtual <= 125)
{
I=(-5.26*(tempAtual-25)+1000)/1000;
}
if (tempAtual > 125)
{
I=0.5;
}
if(digitalRead(CHANNEL4==HIGH))
{
tempAtual_HB = readThermistor3();
aux = tempAtual_HB - tempAtual;
if (aux >= 10)
{
if (tempAtual_HB <= 25)
{
I=1;
}
if (tempAtual_HB > 25 && tempAtual_HB <= 125)
{
I=(-5.26*(tempAtual_HB-25)+1000)/1000;
}
if (tempAtual_HB > 125)
{
I=0.5;
}
}
}
Viadj=14*I*RCS;
pwmvalor=50.5*(Viadj-1.05)+54;
analogWrite(Vout, pwmvalor);
}
if(digitalRead(CHANNEL2==HIGH))
{
tempAtual_LDD = readThermistor2();
if (tempAtual_LDD <= 25)
{
I2=1;
}
if (tempAtual_LDD > 25 && tempAtual_LDD <= 125)
{
I2=(-5.26*(tempAtual_LDD-25)+1000)/1000;
}
if (tempAtual_LDD > 125)
{
I2=0.5;
}
Viadj2=14*I2*RCS2;
pwmvalor2=50.5*(Viadj2-1.05)+54;
analogWrite(Vout2, pwmvalor2);
}
}
//--------------Functions NTC--------------------//
int readThermistor()
{
int rThermistor = 0; // Holds thermistor resistance value
int tKelvin = 0; // Holds calculated temperature
int tCelsius = 0; // Hold temperature in celsius
int adcAverage = 0; // Holds the average voltage measurement
int adcSamples[SAMPLES]; // Array to hold each voltage measurement
for (int i = 0; i < SAMPLES; i++)
{
adcSamples[i] = analogRead(NTC_Pin); // read from pin and store
delay(10); // wait 10 milliseconds
}
for (int i = 0; i < SAMPLES; i++)
{
adcAverage += adcSamples[i]; // add all samples up . . .
}
adcAverage /= SAMPLES; // . . . average it w/ divide
rThermistor = RESISTOR_SERIE_LB * ( (MAX_ADC / adcAverage) - 1);
tKelvin = (BETA * TEMP_AMB) /
(BETA + (TEMP_AMB * log(rThermistor / NTC_TEMP_LB)));
tCelsius = tKelvin - 273.15; // convert kelvin to celsius
return tCelsius; // Return the temperature in Celsius
}
int readThermistor3()
{
int rThermistor3 = 0; // Holds thermistor resistance value
int tKelvin3 = 0; // Holds calculated temperature
int tCelsius3 = 0; // Hold temperature in celsius
int adcAverage3 = 0; // Holds the average voltage measurement
int adcSamples3[SAMPLES]; // Array to hold each voltage measurement
for (int j = 0; j < SAMPLES; j++)
{
adcSamples3[j] = analogRead(NTC_Pin3); // read from pin and store
delay(10); // wait 10 milliseconds
}
for (int j = 0; j < SAMPLES; j++)
{
adcAverage3 += adcSamples3[j]; // add all samples up . . .
}
adcAverage3 /= SAMPLES; // . . . average it w/ divide
rThermistor3 = RESISTOR_SERIE_HB * ( (MAX_ADC / adcAverage3) - 1);
tKelvin3 = (BETA_HB * TEMP_AMB) /
(BETA_HB + (TEMP_AMB * log(rThermistor3 / NTC_TEMP_HB)));
tCelsius3 = tKelvin3 - 273.15; // convert kelvin to celsius
return tCelsius3; // Return the temperature in Celsius
}
int readThermistor2()
{
int rThermistor2 = 0; // Holds thermistor resistance value
int tKelvin2 = 0; // Holds calculated temperature
int tCelsius2 = 0; // Hold temperature in celsius
int adcAverage2 = 0; // Holds the average voltage measurement
int adcSamples2[SAMPLES]; // Array to hold each voltage measurement
for (int k = 0; k < SAMPLES; k++)
{
adcSamples2[k] = analogRead(NTC_Pin2); // read from pin and store
delay(10); // wait 10 milliseconds
}
for (int k = 0; k < SAMPLES; k++)
{
adcAverage2 += adcSamples2[k]; // add all samples up . . .
}
adcAverage2 /= SAMPLES; // . . . average it w/ divide
rThermistor2 = RESISTOR_SERIE_LDD * ( (MAX_ADC / adcAverage2) - 1);
tKelvin2 = (BETA_LDD * TEMP_AMB) /
(BETA_LDD + (TEMP_AMB * log(rThermistor2 / NTC_TEMP_LDD)));
tCelsius2 = tKelvin2 - 273.15; // convert kelvin to celsius
return tCelsius2; // Return the temperature in Celsius
}
JonasSilva:
I have a question, while the program is not sending the signal can I perform other tasks? Or will he be interrupted for these 2 seconds?
The diagnostic output is totally interrupt drive so wont stall loop for 2 seconds while sending. All you need to do in loop is construct the diag data to send and store it so the interrupt code can pick it up for output. If you don't update the diag data then the interrupt just keeps sending the last diag values.
uint32_t constructedData = construct(); // Contruct data to send
cacheData = constructedData << 1; // Cache it after rotating to ensure double bits are not split across 8 bit boundries
Riva:
The diagnostic output is totally interrupt drive so wont stall loop for 2 seconds while sending. All you need to do in loop is construct the diag data to send and store it so the interrupt code can pick it up for output. If you don't update the diag data then the interrupt just keeps sending the last diag values.
uint32_t constructedData = construct(); // Contruct data to send
cacheData = constructedData << 1; // Cache it after rotating to ensure double bits are not split across 8 bit boundries
I dont understand. How is the loop what happens when the new input pins are read? Will it always send the same signal, even when the input signals change?
JonasSilva:
I dont understand. How is the loop what happens when the new input pins are read? Will it always send the same signal, even when the input signals change?
I have simplified the code a bit so that as long as you call the construct() procedure in loop the interrupt code will pick up the new data and send it (once it has finished sending the last set of data). If you don't call construct then the interrupt code will just keep sending the last value.
Riva:
I have simplified the code a bit so that as long as you call the construct() procedure in loop the interrupt code will pick up the new data and send it (once it has finished sending the last set of data). If you don't call construct then the interrupt code will just keep sending the last value.
Thank you. In this new modification does he still send the signal every 2 seconds? I noticed that it goes into interruption every 50 ms, is that correct?
JonasSilva:
Thank you. In this new modification does he still send the signal every 2 seconds? I noticed that it goes into interruption every 50 ms, is that correct?
Yes every 2 seconds. The timer1ISR is called every 50ms and sends 1 bit of data per call and it send 40 bits of data per message.