Hello, hope you're all having a good day! I need to fall here because I'm working on a final project for school (the last year kinds!) and I'm met with problems in between simulation and coding; maybe the problem is from the simulator, but better to be safe than sorry! The simulation program is SimulIDE-1.1.0-SR1.
So, inside my spaghetti of code for this machine, I have a function (bool type) that returns either 1 or 0 if a process is done (1) or not (0). "Which one?" I hear you ask; it is as simple as a "slow start" with motors (maybe you know it by other name).
Long story short: it's a section of the function that does the job of timing (I used millis() to try and avoid the for() function) and every a couple of milliseconds it increments the duty cycle on a PWM output pin (the one connected to the motor).
The problem lies within the usage of "millis()" instead of "for()". I included comments of how I implemented the for() section (that works), but the section I want is with "millis()" and I can't get it working. It prints correctly the PWM value, but it fails at slow-starting the motor (in simulation, it stays in 0 for the whole cycle until it jumps to 1). Happens the same either with the "slow-start"/"slow-rise" and the "slow-fall" sections. Also, I declared the slowTime variable as unsigned long, and fuerzaPWM as unsigned int (registerPWM is just a bool one that has similar purpose as the switch()).
And here's the section of that spaghetti (sorry for Spanish/English combo):
bool slowMotion(bool mode){
switch(mode){
// Parada suave: 1 -> 0.
case 0:
if(!registerPWM){
fuerzaPWM = 255;
registerPWM = 1;
Serial.print("\nParada Suave.");
}
// t = 10s.
analogWrite(pinMotor, fuerzaPWM); // -> ### VPROBLEM HERE ###
if(fuerzaPWM == 0){
registerPWM = 0;
return 1;
}
if(millis() >= slowTime + 40){
fuerzaPWM--;
slowTime = millis();
Serial.print('\n');
Serial.print(fuerzaPWM); // Prints correct PWM value (0~255).
}
break;
// Arranque suave: 0 -> 1.
case 1:
if(!registerPWM){
fuerzaPWM = 0;
registerPWM = 1;
Serial.print("\nArranque Suave.");
}
// t = 5s.
// ### W/ MILLIS() ###
analogWrite(pinMotor, fuerzaPWM); // -> ### VPROBLEM HERE ###
if(fuerzaPWM == 255){
registerPWM = 0;
return 1;
}
if(millis() >= slowTime + 20){
fuerzaPWM++;
slowTime = millis();
Serial.print('\n');
Serial.print(fuerzaPWM); // Prints correct PWM value (0~255).
}
// ### W/ FOR() ###
// for(unsigned int k = 0; k <= 255; k++){
// analogWrite(pinMotor, k);
// delay(20);
// }
// registerPWM = 0;
// return 1;
break;
}
return 0;
}
Now, if you want to see EVERYTHING (UPDATED), this is what I got so far, but some parts are yet to be completed. I follow the state machine logic and use switch() a lot, but the empty cases are not called and the machine won't fall on those yet:
// ####### VARIABLES STATE MACHINE #######
byte stateMachine;
#define Stop 0
#define Run 1
#define NoFreeze 2
byte subStateMachine;
// Stop:
#define SetOff 0
#define SlowFallOFF 1
#define WaitSetOn 2
// Run:
#define MaxTemp 0
#define SlowRise 1
#define Running 2
#define SlowFallON 3
#define MinTemp 4
// NoFreeze:
#define SetInv 0
#define WaitTimer1 1
// #define X 2
// FAIL VARIABLES:
word failState;
#define ReadFail 0
#define SetFailState 1
#define MuteAlarm 2
#define WaitSystemReset 3
// #define X 4
// ####### PINS #######
#define pinPP 2 // Pulsador parada.
#define pinPM 3 // Pulsador marcha.
#define pinP_Mute 4 // Pulsador silenciar alarma.
#define pinFan 7 // Ventilador.
#define pinValInv 8 // Valvula inversora.
#define pinMotor 9 // Motor + inverter (PWM OUTPUT).
#define pinAlarm 10 // Alarma/buzzer/parlante.
#define pinLED_ON 11 // LED de encendido.
#define pinLED_OFF 12 // LED de apagado.
#define pinLED_FG 13 // LED de falla general.
#define pinTerm A2 // Termometro (4mA=1v=204 ; 20mA=5v=1023).
// ####### SPECIALS #######
bool alarm = 0;
bool apagado = 0;
unsigned long timer1 = 0;
unsigned long slowTime = 0;
int fuerzaPWM = 0;
bool registerPWM = 0;
// bool slowMEnable = 0;
void setup() {
pinMode(pinPP, INPUT);
pinMode(pinPM, INPUT);
pinMode(pinTerm, INPUT);
pinMode(pinP_Mute, INPUT);
pinMode(pinLED_ON, OUTPUT);
pinMode(pinLED_OFF, OUTPUT);
pinMode(pinLED_FG, OUTPUT);
pinMode(pinAlarm, OUTPUT);
pinMode(pinMotor, OUTPUT);
pinMode(pinValInv, OUTPUT);
pinMode(pinFan, OUTPUT);
stateMachine = Stop;
subStateMachine = SetOff;
Serial.begin(9600);
}
void loop() {
if(!alarm){
// States: Run - Stop - NoFreeze.
switch(stateMachine){
case Stop:
// Substates: SetOff - WaitSetOn.
switch(subStateMachine){
case SetOff:
digitalWrite(pinLED_ON, 0);
digitalWrite(pinLED_OFF, 1);
digitalWrite(pinFan, 0);
apagado = 0;
subStateMachine = WaitSetOn;
Serial.print("\nStop -> SET OFF");
break;
// 10 -> 0V (10s).
case SlowFallOFF:
// slowMotion(0);
// if(slowMotion(0)){
if(slowMotion2(0)){
subStateMachine = SetOff;
Serial.print("\nStop -> WAIT SET ON");
}
break;
case WaitSetOn:
if(digitalRead(pinPM)){
stateMachine = Run;
subStateMachine = MaxTemp;
Serial.print("\nRun -> Min Temp");
}
break;
}
break;
case Run:
if(digitalRead(pinMotor)){
digitalWrite(pinFan, 1);
}else{
digitalWrite(pinFan, 0);
}
// Substates: MaxTemp - SlowRise - MinTemp - SlowFallON.
switch(subStateMachine){
// Functioning range: (-21 ~ -17)°C = (2.16 ~ 2.32)mV = (441 ~ 474)AIu
case MaxTemp:
if(analogRead(pinTerm) >= 474){
subStateMachine = SlowRise;
Serial.print("\npinTerm = ");
Serial.print(analogRead(pinTerm));
Serial.print('\n');
}
break;
// 0 -> 10V (5s).
case SlowRise:
// slowMEnable = slowMotion(1);
// if(slowMEnable){
if(slowMotion2(1)){
subStateMachine = MinTemp;
Serial.print("\nRun -> MinTemp.");
}
break;
case MinTemp:
digitalWrite(pinMotor, 1);
if(digitalRead(pinPP)){
apagado = 1;
subStateMachine = SlowFallON;
digitalWrite(pinFan, 0);
break;
}
if(analogRead(pinTerm) <= 441){
subStateMachine = SlowFallON;
}
break;
case SlowFallON:
// slowMEnable = slowMotion(0);
// if(slowMEnable){
if(slowMotion2(0)){
if(apagado){
stateMachine = Stop;
subStateMachine = SetOff;
}else{
subStateMachine = MaxTemp;
}
}
break;
}
break;
// To complete.
case NoFreeze:
// Substates: SetInv - WaitTimer1.
switch(subStateMachine){
case SetInv:
break;
case WaitTimer1:
break;
}
break;
}
}
// To complete.
// States: ReadFail - SetFailState - MuteAlarm - WaitSystemReset.
switch(failState){
case ReadFail:
break;
case SetFailState:
break;
case MuteAlarm:
break;
case WaitSystemReset:
break;
}
}
bool slowMotion2(bool mode){
switch(mode){
// Parada suave: 1 -> 0.
case 0:
switch(registerPWM){
case 0:
fuerzaPWM = 255;
analogWrite(pinMotor, fuerzaPWM);
Serial.print("\nParada Suave.");
slowTime = millis();
registerPWM = 1; // Cycle started.
break;
case 1:
// t = 10s.
if((fuerzaPWM > 0) && ((millis() - slowTime) >= 40)){
fuerzaPWM--;
analogWrite(pinMotor, fuerzaPWM);
slowTime = millis();
Serial.print('\n');
Serial.print(fuerzaPWM);
// analogWrite(pinMotor, fuerzaPWM);
}
if(fuerzaPWM == 0){
digitalWrite(fuerzaPWM, 0);
registerPWM = 0;
return 1; // Cycle ended.
}
break;
}
break;
// Arranque suave: 0 -> 1.
case 1:
switch(registerPWM){
case 0:
fuerzaPWM = 0;
analogWrite(pinMotor, fuerzaPWM);
Serial.print("\nArranque Suave.");
slowTime = millis();
registerPWM = 1; // Cycle started.
break;
case 1:
// t = 5s.
if((fuerzaPWM < 255) && ((millis() - slowTime) >= 20)){
fuerzaPWM++;
analogWrite(pinMotor, fuerzaPWM);
slowTime = millis();
Serial.print('\n');
Serial.print(fuerzaPWM);
}
if(fuerzaPWM == 255){
digitalWrite(fuerzaPWM, 1);
registerPWM = 0;
return 1; // Cycle ended.
}
break;
}
break;
}
return 0;
}
/*
bool slowMotion(bool mode){
switch(mode){
// Parada suave: 1 -> 0.
case 0:
if(!registerPWM){
fuerzaPWM = 255;
registerPWM = 1;
Serial.print("\nParada Suave.");
}
// t = 10s.
analogWrite(pinMotor, fuerzaPWM);
if(fuerzaPWM == 0){
registerPWM = 0;
return 1;
}
if(millis() - slowTime >= 40){
fuerzaPWM--;
slowTime = millis();
Serial.print('\n');
Serial.print(fuerzaPWM);
}
break;
// Arranque suave: 0 -> 1.
case 1:
if(!registerPWM){
fuerzaPWM = 0;
registerPWM = 1;
Serial.print("\nArranque Suave.");
}
// t = 5s.
// ### W/ MILLIS() ###
analogWrite(pinMotor, fuerzaPWM);
if(fuerzaPWM == 255){
registerPWM = 0;
return 1;
}
if(millis() - slowTime >= 20){
fuerzaPWM++;
slowTime = millis();
Serial.print('\n');
Serial.print(fuerzaPWM);
}
// ### W/ FOR() ###
// for(unsigned int k = 0; k <= 255; k++){
// analogWrite(pinMotor, k);
// delay(20);
// }
// registerPWM = 0;
// return 1;
break;
}
return 0;
}
*/
// To complete
bool failCheck(){
return 0;
}
