Hi ,
i've arduino Uno 3 and 4 shield relay , i create a code and it works nice on IDE BUT , i want SimHub trigger my code in custom protocol
i've create a formula ( same formula in my custom protocol ) for that
in Simhub debug window , i see Simhub send info , but my relay are still off like an error in void read
i'm too novice in coding and i don't understant why it's not work
Please post your full sketch, using code tags when you do
In my experience the easiest way to tidy up the code and add the code tags is as follows
Start by tidying up your code by using Tools/Auto Format in the IDE to make it easier to read. Then use Edit/Copy for Forum and paste what was copied in a new reply. Code tags will have been added to the code to make it easy to read in the forum thus making it easier to provide help.
A bool is a single byte whose value will be either 0 for false or 1 for true, What value or values are you expecting in VariableABS, especially as you seem to be expecting a String rather than a single byte ?
#ifndef SHCUSTOMPROTOCOL_H
#define SHCUSTOMPROTOCOL_H
#include <Arduino.h>
class SHCustomProtocol {
private:
public:
/*
CUSTOM PROTOCOL CLASS
SEE https://github.com/zegreatclan/SimHub/wiki/Custom-Arduino-hardware-support
GENERAL RULES :
- ALWAYS BACKUP THIS FILE, reinstalling/updating SimHub would overwrite it with the default version.
- Read data AS FAST AS POSSIBLE in the read function
- NEVER block the arduino (using delay for instance)
- Make sure the data read in "read()" function READS ALL THE DATA from the serial port matching the custom protocol definition
- Idle function is called hundreds of times per second, never use it for slow code, arduino performances would fall
- If you use library suspending interrupts make sure to use it only in the "read" function when ALL data has been read from the serial port.
It is the only interrupt safe place
COMMON FUNCTIONS :
- FlowSerialReadStringUntil('\n')
Read the incoming data up to the end (\n) won't be included
- FlowSerialReadStringUntil(';')
Read the incoming data up to the separator (😉 separator won't be included
- FlowSerialDebugPrintLn(string)
Send a debug message to simhub which will display in the log panel and log file (only use it when debugging, it would slow down arduino in run conditions)
*/
// Called when starting the arduino (setup method in main sketch)
// Called when new data is coming from computer
const int solenoid1Pin = 8; // Relais pour solénoïde 1 sur la pin 8
const int solenoid2Pin = 12; // Relais pour solénoïde 2 sur la pin 12
const int motorPin = 7; // Relais pour moteur sur la pin 7
const int solenoidFrequency = 10; // Fréquence des solénoïdes en Hz
const int solenoidInterval = 1000 / (2 * solenoidFrequency); // Intervalle pour la fréquence de 10 Hz (en millisecondes)
const int minActivationTime = 500; // Temps minimum d'activation en millisecondes (0,5 sec)
unsigned long previousMillisSolenoid = 0; // Stocke le dernier temps de changement pour les solénoïdes
unsigned long activationStartMillis = 0; // Stocke le temps de début de l'activation
unsigned long previousMillisABS = 0; // Stocke le temps de début de l'activation
unsigned long absToggleInterval = 2000; // Stocke le temps de début de l'activation
bool solenoid1State = false; // État actuel du solénoïde 1
bool solenoid2State = false; // État actuel du solénoïde 2
bool VariableABS = false; // Variable qui indique si l'ABS est actif ou non
bool absActive = false; // Indique si les relais sont en train d'être activés
unsigned long currentMillis = millis();
void read() {
bool VariableABS = FlowSerialReadStringUntil('\n');
FlowSerialDebugPrintLn("SpeedProut : " + String(VariableABS));
}
void setup() {
pinMode(solenoid1Pin, OUTPUT);
pinMode(solenoid2Pin, OUTPUT);
pinMode(motorPin, OUTPUT);
// Initialisation des relais à l'état bas (éteint)
digitalWrite(solenoid1Pin, LOW);
digitalWrite(solenoid2Pin, LOW);
digitalWrite(motorPin, LOW);
}
void loop() {
FlowSerialDebugPrintLn("SpeedProut2 : " + String(VariableABS));
unsigned long currentMillis = millis();
// Gérer l'alternance de la variable VariableABS toutes les 2 secondes
if (VariableABS) {
// Si l'ABS devient actif, enregistrer le temps de début d'activation
activationStartMillis = currentMillis;
absActive = true;
}
// Détection de l'activation de l'ABS
if (VariableABS && !absActive) {
// Si l'ABS devient actif, enregistrer le temps de début d'activation
activationStartMillis = currentMillis;
absActive = true;
}
// Si VariableABS est 1 (ABS activé) ou si le temps minimum d'activation n'est pas écoulé
if (VariableABS || (absActive && (currentMillis - activationStartMillis < minActivationTime))) {
// Activer le moteur en continu
digitalWrite(motorPin, HIGH);
// Gérer l'alternance des solénoïdes à 10 Hz
if (currentMillis - previousMillisSolenoid >= solenoidInterval) {
previousMillisSolenoid = currentMillis;
// Inverser l'état des solénoïdes
solenoid1State = !solenoid1State;
solenoid2State = !solenoid2State;
digitalWrite(solenoid1Pin, solenoid1State ? HIGH : LOW);
digitalWrite(solenoid2Pin, solenoid2State ? HIGH : LOW);
}
} else {
// Si le temps minimum d'activation est écoulé, désactiver les relais
digitalWrite(solenoid1Pin, LOW);
digitalWrite(solenoid2Pin, LOW);
digitalWrite(motorPin, LOW);
// Réinitialiser les états
solenoid1State = false;
solenoid2State = false;
absActive = false; // Réinitialiser l'état d'activation
}
}
void idle() {
};
};
#endif
This will print received bytes in hex. If you only see 0x00 or 0x01, simhub does not send a '\n'.
Notes:
You seem to be missing a Serial.begin().
You seem to be missing the FlowSerialDebugPrintLn function.
Why are loop() and setup() part of your class?
Does simhub send a '\n'?
I'm not familiar with simhub. If simhub does not provide a monitor to see what is received, you can toggle the L-LED (if available on your board) based on the received value.
#ifndef SHCUSTOMPROTOCOL_H
#define SHCUSTOMPROTOCOL_H
#include <Arduino.h>
class SHCustomProtocol {
private:
public:
/*
CUSTOM PROTOCOL CLASS
SEE https://github.com/zegreatclan/SimHub/wiki/Custom-Arduino-hardware-support
GENERAL RULES :
- ALWAYS BACKUP THIS FILE, reinstalling/updating SimHub would overwrite it with the default version.
- Read data AS FAST AS POSSIBLE in the read function
- NEVER block the arduino (using delay for instance)
- Make sure the data read in "read()" function READS ALL THE DATA from the serial port matching the custom protocol definition
- Idle function is called hundreds of times per second, never use it for slow code, arduino performances would fall
- If you use library suspending interrupts make sure to use it only in the "read" function when ALL data has been read from the serial port.
It is the only interrupt safe place
COMMON FUNCTIONS :
- FlowSerialReadStringUntil('\n')
Read the incoming data up to the end (\n) won't be included
- FlowSerialReadStringUntil(';')
Read the incoming data up to the separator (😉 separator won't be included
- FlowSerialDebugPrintLn(string)
Send a debug message to simhub which will display in the log panel and log file (only use it when debugging, it would slow down arduino in run conditions)
*/
const int solenoid1Pin = 8; // Relais pour solénoïde 1 sur la pin 8
const int solenoid2Pin = 12; // Relais pour solénoïde 2 sur la pin 12
const int motorPin = 7; // Relais pour moteur sur la pin 7
const int solenoidFrequency = 10; // Fréquence des solénoïdes en Hz
const int solenoidInterval = 1000 / (2 * solenoidFrequency); // Intervalle pour la fréquence de 10 Hz (en millisecondes)
const int minActivationTime = 500; // Temps minimum d'activation en millisecondes (0,5 sec)
unsigned long previousMillisSolenoid = 0; // Stocke le dernier temps de changement pour les solénoïdes
unsigned long activationStartMillis = 0; // Stocke le temps de début de l'activation
unsigned long previousMillisABS = 0; // Stocke le temps de début de l'activation
unsigned long absToggleInterval = 1000; // Stocke le temps de début de l'activation
int solenoid1State = 0; // État actuel du solénoïde 1
int solenoid2State = 0; // État actuel du solénoïde 2
int VariableABS = 0; // Variable qui indique si l'ABS est actif ou non
int absActive = 0; // Indique si les relais sont en train d'être activés
unsigned long currentMillis = millis();
// Called when starting the arduino (setup method in main sketch)
void setup() {
// put your setup code here
pinMode(solenoid1Pin, OUTPUT);
pinMode(solenoid2Pin, OUTPUT);
pinMode(motorPin, OUTPUT);
// Initialisation des relais à l'état bas (éteint)
digitalWrite(solenoid1Pin, LOW);
digitalWrite(solenoid2Pin, LOW);
digitalWrite(motorPin, LOW);
}
// Called when new data is coming from computer
void read() {
bool VariableABS =FlowSerialReadStringUntil('0').toInt();
FlowSerialDebugPrintLn("ABS : " + String(VariableABS) );
}
void loop() {
unsigned long currentMillis = millis();
// Gérer l'alternance de la variable VariableABS toutes les 2 secondes
if (VariableABS) {
// Si l'ABS devient actif, enregistrer le temps de début d'activation
activationStartMillis = currentMillis;
absActive = 1;
}
// Détection de l'activation de l'ABS
if (VariableABS && !absActive) {
// Si l'ABS devient actif, enregistrer le temps de début d'activation
activationStartMillis = currentMillis;
absActive = 1;
}
// Si VariableABS est 1 (ABS activé) ou si le temps minimum d'activation n'est pas écoulé
if (VariableABS || (absActive && (currentMillis - activationStartMillis < minActivationTime))) {
// Activer le moteur en continu
digitalWrite(motorPin, HIGH);
// Gérer l'alternance des solénoïdes à 10 Hz
if (currentMillis - previousMillisSolenoid >= solenoidInterval) {
previousMillisSolenoid = currentMillis;
// Inverser l'état des solénoïdes
solenoid1State = !solenoid1State;
solenoid2State = !solenoid2State;
digitalWrite(solenoid1Pin, solenoid1State ? HIGH : LOW);
digitalWrite(solenoid2Pin, solenoid2State ? HIGH : LOW);
}
} else {
// Si le temps minimum d'activation est écoulé, désactiver les relais
digitalWrite(solenoid1Pin, LOW);
digitalWrite(solenoid2Pin, LOW);
digitalWrite(motorPin, LOW);
// Réinitialiser les états
solenoid1State = 0;
solenoid2State = 0;
absActive = 0; // Réinitialiser l'état d'activation
}
}
void idle() {
};
};
#endif