I have recently written a program which is supposed to change the duty-cycle to keep the feedback voltage measured on A0, A1 constant. The problem is that the Arduino will start crashing at pretty constant intervals if it approaches it's target current. Once it crashes I have confirmed that it restarts the program (but crashes again in a moment).
Here's a sample of the serial output during the crash:
Current A: 65 Current B: 67 PWM A: 174.98 PWM B: 236.00
Current A: 65 Current B: 67 PWM A: 174.98 PWM B: 235.96
Current A: 65 Current B: 67 PWM A: 174.98 PWM B: 235.92
Current A: 64 Current B: 67 PWM A: 175.00 PWM B: 235.88
Current A: 64 Current B: 66 PWM A: 250.00 PWM B: 285114740000000000000000000.00
Current A: 0 Current B: 0 PWM A: 1.30 PWM B: 0.00
Current A: 0 Current B: 0 PWM A: 2.60 PWM B: 1.30
Current A: 0 Current B: 0 PWM A: 3.90 PWM B: 2.60
Current A: 0 Current B: 0 PWM A: 5.20 PWM B: 3.90
And here is all of my code:
#include <MemoryFree.h>
//Program to run on the Vegetarium
//Written by Leon Teichroeb on 12/6/2016
//Hardware description:
//-Oscillator 2A and 2B for the two onboard driver circuits
//-Pin 13 is attached to the "heartbeat" LED
//-Channel A (3) and B (11) current measurements on A0 and A1
//Functionality:
//-Drive Channels at set current
float PWMA = 0;
float PWMB = 0;
int TARGETA = 65;
int TARGETB = 65;
void setup() {
Serial.begin(115200);
pinMode(3, OUTPUT);
pinMode(11, OUTPUT);
TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(CS20);
OCR2A = (int)PWMA;
OCR2B = (int)PWMB;
digitalWrite(3, LOW);
digitalWrite(11, LOW);
delay(5000);
}
void loop() {
int CURRENTA = analogRead(A0) / 4;
if(CURRENTA < TARGETA) {
PWMA += (TARGETA - CURRENTA) * 0.020f;
if(PWMA > 250) {
PWMA = 250;
}
}
if(CURRENTA > TARGETA) {
PWMA += (TARGETA - CURRENTA) * 0.020f;
if(PWMA < 5) {
PWMA = 5;
}
}
int CURRENTB = analogRead(A1) / 4;
Serial.println("Current A: " + (String)CURRENTA + "\t" + "Current B: " + (String)CURRENTB + "\t" + "PWM A: " + (String)PWMA + "\t" + "PWM B: " + (String)PWMB);
//Serial.println("PWM A: " + (String)PWMA + "\t" + "PWM B: " + (String)PWMB);
//Serial.print("freeMemory()=");
//Serial.println(freeMemory());
if(CURRENTB < TARGETB) {
PWMB += (TARGETB - CURRENTB) * 0.020f;
if(PWMB > 250) {
PWMB = 250;
}
}
if(CURRENTB > TARGETB) {
PWMB += (TARGETB - CURRENTB) * 0.020f;
if(PWMB < 5) {
PWMB = 5;
}
}
if(PWMA < 10) {
digitalWrite(3, LOW);
} else {
analogWrite(3, (int)PWMA);
}
if(PWMB < 10) {
digitalWrite(11, LOW);
} else {
analogWrite(11, (int)PWMB);
}
delay(40);
}
My circuit also provides power for the Arduino through a simple 7815 voltage regulator. The analog input does not exceed a few volts, and the PWM outputs are driving two logic level MOSFETs. If more information on the circuit is necessary please let me know!
EDIT: I have found out that it isn't a bug in the two feedback loops, because both work on their own. It crashes as soon as I use both feedback loops together. As far as I'm aware, there are no shared variables or data between them
String
s? Like:Serial.print("Current A: "); Serial.print(CURRENTA); ...
. It's cumbersome but memory friendly.285114740000000000000000000
is kind of odd. Also,PWM B: 0.00
seems to be impossible with the code above. Very odd. (Did you add some capacitors to the output of the 7805?)