Buongiorno
Sto sviluppando una app in VisualStudio2022 per la gestione di:
Blocchi, Scambi, Semafori
del trenino elettrico di un amico.
https://drive.google.com/file/d/1W4thtqgGl7UzVy5OWa3NP91Vwn2YYyYb/view?usp=drive_link
Col bottone”Livello Superiore” si visualizza il mimico del livello superiore
https://drive.google.com/file/d/1LfioUOA3O7zBUj8bOgn7ZYkbfB2MvoaF/view?usp=drive_link
Ci sono, per ora, due arduino: il Master che dialoga col PC e lo Slave cui sono passati i comandi per scambi e (in futuro) i segnali
i comandi sono dek tipo:
<0,0> ….. <15,1> per gly scambi
<100,0> ,,,, <150,1> per i LED semafoti
<900,0> ,,,, <931,1> per i blocchi,
I comandi sono passati via 3 PCA9685 a 3 Moduli da 16 relays
Inviando il comando <3000> vengono energizzati/deenergizzati i singoli blocchi uno dopo l’altro, co sen un for, mentre se invio un comando per un solo relay (<9nn,1> o <9nn,0) il relay si comporta in modo erratico
MASTER.ino
</>
/* USATO IL 28/03/04 29/03/04 30/03/04 (PASQUA 2024)
QUANDO FIALMENTE SCOPRIAMO CHE NON FUNZIONAVA PERCHE' Arduino ERA POSIZIONATO TROPPO LONTANO
DAL PCA 9586 !!!!!!!!!!!!!
MASTER SU COM6 copy_20241113153614.ino
File: 20241102_Master_
*/
#include <Adafruit_PWMServoDriver.h>
#include <ShiftRegister74HC595.h>
Adafruit_PWMServoDriver pwm0 = Adafruit_PWMServoDriver(0x40); //Blocchi Stazione
Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x42); //Blocchi Stazione
Adafruit_PWMServoDriver pwm3 = Adafruit_PWMServoDriver(0x43); //Rimanentuìi blocchi livello
ShiftRegister74HC595<1> sr1(0, 1, 2);
int i = 0;
int var = 0;
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
String dataout ; // passa i dati ad arduino slave <nnn,n,n>
String dataoutStr = "";
String dataoutStrPC = "";
int Pin = 1000;
int Status1 = 0;
int Status2 = 0;
int Status3 = 0;
boolean newData = false;
// =======================================================================================================
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
} else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//======================== PARSE DATA ==============================
void parseData() { // split the data into its parts
char* strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars, ","); // get the first part -
Pin = atoi(strtokIndx); //
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
Status1 = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
Status2 = atoi(strtokIndx); // convert this part to a float
strtokIndx = strtok(NULL, ",");
Status3 = atoi(strtokIndx); // convert this part to a float
}
// ======================================= SHOW PARSED DATA =============================
void showParsedData() {
/* Serial.print("Pin n° = ");
Serial.println(Pin);
Serial.print("Status1 = ");
Serial.println(Status1);
Serial.print("Status2 = ");
Serial.println(Status2);
Serial.print("Status3 = ");
Serial.println(Status3);
Serial.println("==================");
*/
}
void setup() { // ****************************************** SETUP INIZIO *****************************************
Serial.begin(9600); //Seriale di comunicazione PC / ArduinoMaster
Serial1.begin(9600); //Seriale di comunicazione ArduinoMaster / Arduino Slave
pwm0.begin();
pwm0.setPWMFreq(1600);
pwm2.begin();
pwm2.setPWMFreq(1600);
pwm3.begin();
pwm3.setPWMFreq(1600);
pinMode(8,OUTPUT);
digitalWrite(8,LOW);
for (i = 0; i <= 15; i++) { // INIZIALIZZA LO STATO BLOCCHI STAZIONE (Relays diseccitati)
pwm2.setPWM(i, 4096, 0);
delay(200);
}
/* delay(5000);
//for (i = 0; i <= 15; i++) { // INIZIALIZZA LO STATO BLOCCHI VAPORE ED ELE (Relays diseccitati)
// pwm3.setPWM(i, 4096, 0);
// delay(200);
}
*/
Serial.println("Per test 16 relays blocchi:<3000>");
Serial.println("Per spegnere tutti 16 relays:<2000>");
Serial.println("Per test singoli blocchi:<90n,1> oppure <90n,0> ");
Serial.println("Arduino è pronto .... ");
delay(200);
Pin = 1000;
}
// ********************************************** SETUP FINE ****************************************************
void loop() { // Legge i dati dal PC
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
showParsedData();
newData = false;
// 000000000000000000000000000000000000000000000000000000000000
}
if (Pin == 3000) {
for (i = 0; i <= 15; i++) {
Serial.print("Blocco n° = ");
Serial.println(i);
pwm2.setPWM(i, 0, 4096);
delay(200);
Serial.print("Blocco Alimentato n° = ");
Serial.println(i);
pwm2.setPWM(i, 4096, 0);
delay(200);
}
for (i = 0; i <= 15; i++) { //
Serial.print("Blocco Alimentato n° = ");
Serial.println(i);
pwm3.setPWM(i, 0, 4096);
delay(200);
pwm3.setPWM(i, 4096, 0);
delay(200);
}
Pin =1000;
}
if (Pin == 2000) {
for (i = 0; i <= 15; i++) {
pwm2.setPWM(i, 0, 4096);
delay(500);
pwm3.setPWM(i, 0, 4096);
delay(500);
// Serial.Print("Pin n° ");
// Serial.Println(i);
}
Pin = 1000;
}
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° Gestione BLOCCHI LIV SUP °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
if (Pin >= 900 && Pin <= 915) { // blocchi stazione
Pin = Pin - 900;
if (Status1 == 0) {
pwm2.setPWM(Pin, 0, 4096);
digitalWrite(Pin,HIGH);
}
if (Status1 == 1) {
pwm2.setPWM(Pin, 4096, 0);
digitalWrite(Pin,HIGH);
}
}
Pin = 1000;
if (Pin >= 916 && Pin <= 931) { // blocchi anello elettrificato ed anello vapore
Pin = Pin - 916;
if (Status1 == 0) {
pwm3.setPWM(Pin, 0, 4096);
}
if (Status1 == 1) {
pwm3.setPWM(Pin, 4096, 0);
}
Pin = 1000;
}
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° Gestione SCAMBI LIV SUP °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
// Pin =12;
// Status1=1 ;
if (Pin >= 0 && Pin <= 15) {
if (Status1 == 0) {
dataout = String('<') + String(Pin) + String(',') + String(Status1) + String('>'); // + ('\0');
Serial.print(dataout);
Serial1.print(dataout);
}
if (Status1 == 1) {
dataout = String('<') + String(Pin) + String(',') + String(Status1) + String('>'); //+ ('\0');
Serial.print(dataout);
Serial1.print(dataout);
}
Pin = 1000;
}
if (Pin >= 0 && Pin <= 15) {
if (Status1 == 1) {
pwm0.setPWM(Pin, 4096, 0);
digitalWrite(8,HIGH);
}
if (Status1 == 0) {
pwm0.setPWM(Pin, 0, 4096);
digitalWrite(8,LOW);
}
Pin=1000;
}
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° Gestione SEMAFORI °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
if (Pin >= 100 && Pin <= 147) {
i = Pin - 100;
if (Status1 == 0) {
sr1.set(i, LOW);
Serial.print("Pin = ");
Serial.print(i);
Serial.println(" Status1 = 0 ");
}
if (Status1 == 1) {
sr1.set(i, HIGH);
Serial.print("Pin = ");
Serial.print(i);
Serial.println("Status1 = 1 ");
}
//°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° FINE SEMAFORI °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
Pin = 1000;
}
for (i = 0; i <= 15; i++) { // INIZIALIZZA LO STATO scambi (Relays diseccitati)
pwm0.setPWM(i, 4096, 0);
delay(200);
}*testo in corsivo*
// Test funzionamento Serial1
if (Pin == 4000) {
dataout = String('<') + String(Pin) + String(',') + String(Status1) + String('>');
Serial1.print (dataout);
Serial.print (dataout);
Pin = 1000;
}
} // ***************************************** usando un “for”
Ora, mentre il modulo 16 relays degli scambi funziona bene, i due mohuli dei blocchi funzionano solo se faccio il test <3000>, **mentre se li comando singolarmente sono erratici**.
Cosa c'è di sbagliato ????
<img>https://drive.google.com/file/d/1__xbJmmRiESwknTB0qItKndSM6Nbhk-v/view?usp=drive_link</img>
` ` `
`digita o incolla il codice qu********************************************
/* USATO IL 28/03/04 29/03/04 30/03/04 (PASQUA 2024)
QUANDO FIALMENTE SCOPRIAMO CHE NON FUNZIONAVA PERCHE' Arduino ERA POSIZIONATO TROPPO LONTANO
DAL PCA 9586 !!!!!!!!!!!!!
MASTER SU COM6 copy_20241113153614.ino
File: 20241102_Master_
*/
#include <Adafruit_PWMServoDriver.h>
#include <ShiftRegister74HC595.h>
Adafruit_PWMServoDriver pwm0 = Adafruit_PWMServoDriver(0x40); //Blocchi Stazione
Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x42); //Blocchi Stazione
Adafruit_PWMServoDriver pwm3 = Adafruit_PWMServoDriver(0x43); //Rimanentuìi blocchi livello
ShiftRegister74HC595<1> sr1(0, 1, 2);
int i = 0;
int var = 0;
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
String dataout ; // passa i dati ad arduino slave <nnn,n,n>
String dataoutStr = "";
String dataoutStrPC = "";
int Pin = 1000;
int Status1 = 0;
int Status2 = 0;
int Status3 = 0;
boolean newData = false;
// =======================================================================================================
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
} else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//======================== PARSE DATA ==============================
void parseData() { // split the data into its parts
char* strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars, ","); // get the first part -
Pin = atoi(strtokIndx); //
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
Status1 = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
Status2 = atoi(strtokIndx); // convert this part to a float
strtokIndx = strtok(NULL, ",");
Status3 = atoi(strtokIndx); // convert this part to a float
}
// ======================================= SHOW PARSED DATA =============================
void showParsedData() {
/* Serial.print("Pin n° = ");
Serial.println(Pin);
Serial.print("Status1 = ");
Serial.println(Status1);
Serial.print("Status2 = ");
Serial.println(Status2);
Serial.print("Status3 = ");
Serial.println(Status3);
Serial.println("==================");
*/
}
void setup() { // ****************************************** SETUP INIZIO *****************************************
Serial.begin(9600); //Seriale di comunicazione PC / ArduinoMaster
Serial1.begin(9600); //Seriale di comunicazione ArduinoMaster / Arduino Slave
pwm0.begin();
pwm0.setPWMFreq(1600);
pwm2.begin();
pwm2.setPWMFreq(1600);
pwm3.begin();
pwm3.setPWMFreq(1600);
pinMode(8,OUTPUT);
digitalWrite(8,LOW);
for (i = 0; i <= 15; i++) { // INIZIALIZZA LO STATO BLOCCHI STAZIONE (Relays diseccitati)
pwm2.setPWM(i, 4096, 0);
delay(200);
}
/* delay(5000);
//for (i = 0; i <= 15; i++) { // INIZIALIZZA LO STATO BLOCCHI VAPORE ED ELE (Relays diseccitati)
// pwm3.setPWM(i, 4096, 0);
// delay(200);
}
*/
Serial.println("Per test 16 relays blocchi:<3000>");
Serial.println("Per spegnere tutti 16 relays:<2000>");
Serial.println("Per test singoli blocchi:<90n,1> oppure <90n,0> ");
Serial.println("Arduino è pronto .... ");
delay(200);
Pin = 1000;
}
// ********************************************** SETUP FINE ****************************************************
void loop() { // Legge i dati dal PC
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
showParsedData();
newData = false;
// 000000000000000000000000000000000000000000000000000000000000
}
if (Pin == 3000) {
for (i = 0; i <= 15; i++) {
Serial.print("Blocco n° = ");
Serial.println(i);
pwm2.setPWM(i, 0, 4096);
delay(200);
Serial.print("Blocco Alimentato n° = ");
Serial.println(i);
pwm2.setPWM(i, 4096, 0);
delay(200);
}
for (i = 0; i <= 15; i++) { //
Serial.print("Blocco Alimentato n° = ");
Serial.println(i);
pwm3.setPWM(i, 0, 4096);
delay(200);
pwm3.setPWM(i, 4096, 0);
delay(200);
}
Pin =1000;
}
if (Pin == 2000) {
for (i = 0; i <= 15; i++) {
pwm2.setPWM(i, 0, 4096);
delay(500);
pwm3.setPWM(i, 0, 4096);
delay(500);
// Serial.Print("Pin n° ");
// Serial.Println(i);
}
Pin = 1000;
}
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° Gestione BLOCCHI LIV SUP °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
if (Pin >= 900 && Pin <= 915) { // blocchi stazione
Pin = Pin - 900;
if (Status1 == 0) {
pwm2.setPWM(Pin, 0, 4096);
digitalWrite(Pin,HIGH);
}
if (Status1 == 1) {
pwm2.setPWM(Pin, 4096, 0);
digitalWrite(Pin,HIGH);
}
}
Pin = 1000;
if (Pin >= 916 && Pin <= 931) { // blocchi anello elettrificato ed anello vapore
Pin = Pin - 916;
if (Status1 == 0) {
pwm3.setPWM(Pin, 0, 4096);
}
if (Status1 == 1) {
pwm3.setPWM(Pin, 4096, 0);
}
Pin = 1000;
}
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° Gestione SCAMBI LIV SUP °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
// Pin =12;
// Status1=1 ;
if (Pin >= 0 && Pin <= 15) {
if (Status1 == 0) {
dataout = String('<') + String(Pin) + String(',') + String(Status1) + String('>'); // + ('\0');
Serial.print(dataout);
Serial1.print(dataout);
}
if (Status1 == 1) {
dataout = String('<') + String(Pin) + String(',') + String(Status1) + String('>'); //+ ('\0');
Serial.print(dataout);
Serial1.print(dataout);
}
Pin = 1000;
}
if (Pin >= 0 && Pin <= 15) {
if (Status1 == 1) {
pwm0.setPWM(Pin, 4096, 0);
digitalWrite(8,HIGH);
}
if (Status1 == 0) {
pwm0.setPWM(Pin, 0, 4096);
digitalWrite(8,LOW);
}
Pin=1000;
}
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° Gestione SEMAFORI °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
if (Pin >= 100 && Pin <= 147) {
i = Pin - 100;
if (Status1 == 0) {
sr1.set(i, LOW);
Serial.print("Pin = ");
Serial.print(i);
Serial.println(" Status1 = 0 ");
}
if (Status1 == 1) {
sr1.set(i, HIGH);
Serial.print("Pin = ");
Serial.print(i);
Serial.println("Status1 = 1 ");
}
//°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° FINE SEMAFORI °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
Pin = 1000;
}
for (i = 0; i <= 15; i++) { // INIZIALIZZA LO STATO scambi (Relays diseccitati)
pwm0.setPWM(i, 4096, 0);
delay(200);
}
// Test funzionamento Serial1
if (Pin == 4000) {
dataout = String('<') + String(Pin) + String(',') + String(Status1) + String('>');
Serial1.print (dataout);
Serial.print (dataout);
Pin = 1000;
}
} // *****************************************i`FINE LOOP
``Usa i tags code per formattare il codice per il
SLAVE.ino
/* SLAVE SU COM4
*/
#include <Adafruit_PWMServoDriver.h>
#include <ShiftRegister74HC595.h>
/* USATO IL 28/03/04 29/03/04 30/03/04 (PASQUA 2024)
QUANDO FIALMENTE SCOPRIAMO CHE NON FUNZIONAVA PERCHE' Arduino ERA POSIZIONATO TROPPO LONTANO
DAL PCA 9586 !!!!!!!!!!!!!
*/
#include <Adafruit_PWMServoDriver.h>
#include <ShiftRegister74HC595.h>
Adafruit_PWMServoDriver pwm0 = Adafruit_PWMServoDriver(0x40); //Blocchi Stazione
Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x42); //Blocchi Stazione
Adafruit_PWMServoDriver pwm3 = Adafruit_PWMServoDriver(0x43); //Rimanentuìi blocchi livello
ShiftRegister74HC595<1> sr1(0, 1, 2);
int i = 0;
int var = 0;
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
String dataout = ""; // passa i dati ad arduino slave <nnn,n,n>
String dataoutStr = "";
String dataoutStrPC = "";
int Pin = 1000;
int Status1 = 0;
int Status2 = 0;
int Status3 = 0;
boolean newData = false;
// =======================================================================================================
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial1.available() > 0 && newData == false) {
rc = Serial1.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
} else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//======================== PARSE DATA ==============================
void parseData() { // split the data into its parts
char* strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars, ","); // get the first part -
Pin = atoi(strtokIndx); //
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
Status1 = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
Status2 = atoi(strtokIndx); // convert this part to a float
strtokIndx = strtok(NULL, ",");
Status3 = atoi(strtokIndx); // convert this part to a float
}
//================================================================0
void setup() {
Serial1.begin(9600);
pwm0.begin();
pwm0.setPWMFreq(1600);
pinMode(8,OUTPUT);
// Pin=12;
//Status1=1;
}
//=================================================================
void loop() {
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the or // because strtok() used in parseData() replaces the commas with \0
parseData();
newData = false;
// 000000000000000000000000000000000000000000000000000000000000
}
// °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° Gestione SCAMBI LIV SUP °°°°°°°°
//digitalWrite(8,HIGH);
//Pin = 12;
//Status1 = 0;
if (Pin >= 0 && Pin <= 15) {
if (Status1 == 1) {
pwm0.setPWM(Pin, 4096, 0);
digitalWrite(8,HIGH);
}
if (Status1 == 0) {
pwm0.setPWM(Pin, 0, 4096);
digitalWrite(8,LOW);
}
Pin=1000;
}
if (Pin == 4000) {
if(Status2 == 3) {
for (i = 0; i <= 15; i++) { //
pwm0.setPWM(i, 0, 4096);
delay(200);
pwm0.setPWM(i, 4096, 0);
delay(200);
}
}
if (Status1 == 0) {
digitalWrite(8,LOW);
}
if (Status1 == 1) {
digitalWrite(8,HIGH);
}
}
Pin = 1000;
} // FINE LOOP