Ciao a tutti,
per il progetto che vi illustrerò sto utilizzando dei cloni di arduino Pro Micro with ATMEGA32U4, 5 V, 16 MHz.
Sto cercando di scrivere un protocollo per far comunicare 2 arduino (ma poi diventranno X) con dei moduli a 433 Mhz, la comunicazione sarà half-duplex e uno degli arduino sarà master mentre gli altri saranno tutti slave.
Il protocollo è abbastanza semplice e lo trovate in allegato.
Un esempio è questo:
- Arduino master segnalala sua presenza trasmettendo il suo id M2.
- Arduino slave sente l'id del Master e si presenta inviando contenente il proprio id(S2): M2IS2
- Il master invia un ACK a S2
- Periodicamente il master interroga gli slaves per vedere se sono ancora raggiungibili.
Ora, il problema è che nel momento in cui lo slave riceve l'id del master lo memorizza nella variabile char* masterId che verrà poi passata alle varie funzioni per costruire i pacchetti, ma poi ad un certo punto lo perde come se venisse sovrascritto o cancellato in memoria.
Questo si può vedere chiaramente dal log dello slave:
Looking for master...
Master found: M2
SizeofTosend:6
[1]IndexofTosend:
[1]IndexofTosend:
[2]IndexofTosend:I
[2]IndexofTosend:S
[2]IndexofTosend:2
dovrebbe essere:
Looking for master...
Master found: M2
SizeofTosend:6
[1]IndexofTosend:M
[1]IndexofTosend:2
[2]IndexofTosend:I
[2]IndexofTosend:S
[2]IndexofTosend:2
ma quell'M2 si è perso durante il tragitto ma non capisco dove.
Qui il codice del ricevitore:
//Receiver Code (Leonardo)
#include <VirtualWire.h>
uint8_t buflen = VW_MAX_MESSAGE_LEN;
char ACK = 'K';
char INIT_SLAVE = 'I';
char SLAVE_PREF = 'S';
char SLAVE_NEW_ID = 'N';
char* EMPTY = "ER";
char* slaveIdentifier = "S2";
char* masterId ="M2";
void setup() {
delay(2000);
Serial.begin(9600);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
vw_setup(2000);
vw_set_tx_pin(8);
vw_set_rx_pin(7);
vw_rx_start();
randomSeed(42);
}
void loop() {
//Cerco un master
masterId = lookForMaster();
//Chiedo al master di darmi un id
requestNewSlaveID(masterId);
return;
//Aspetto che mi venga assegnato un id
slaveIdentifier = getNewIDFromMaster(masterId);
delay(99999);
}
char* lookForMaster() {
Serial.println(F("Looking for master..."));
boolean masterFound = false;
do {
uint8_t buf[buflen];
vw_wait_rx();
if (vw_get_message(buf, &buflen)) {
char masterId[buflen + 1];
int i = 0;
for (i = 0; i < buflen; i++) {
masterId[i] = (char) buf[i];
}
masterId[i] = '\0';
if (masterId[0] == 'M' && sizeof(masterId) == 3) {
Serial.print(F("Master found: "));Serial.println(masterId);
return masterId;
}
}
} while (true);
return slaveIdentifier;
}
void requestNewSlaveID(char* masterId) {
//char *masterId1 = "M2";
send(slaveIdentifier, masterId, INIT_SLAVE);
}
char* getNewIDFromMaster(char* masterId) {
Serial.println(F("Waiting new slaveID from master..."));
char* message;
do {
message = listenMessagesForMe();
} while (sizeof(message) == 0 || message == EMPTY);
Serial.print(F("New slaveIdentifier: "));
Serial.println(message);
Serial.println(F("Confirming to master my new id..."));
return message;
}
char* listenMessagesForMe() {
//delay(25);
uint8_t buf[VW_MAX_MESSAGE_LEN];
vw_wait_rx_max(300);
if (vw_get_message(buf, &buflen)) { // Non-blocking
char sender[3];
char command;
char recipient[3];
char message[buflen + 1 ];
int i;
// Message with a good checksum received, dump it.
for (i = 0; i < buflen; i++) {
message[i] = (char) buf[i];
}
for (i = 0; i < buflen; i++) {
if ( (message[i] >= '0' && message[i] <= '9') || (message[i] >= 'A' && message[i] <= 'Z')) {
//Controllo se il messaggio è per me, altrimenti esco
if (i < sizeof(slaveIdentifier) && message[i] != slaveIdentifier[i]) {
Serial.println(F("Messaggio per altri: ")); Serial.println(message);
return EMPTY;
}
if (i == sizeof(slaveIdentifier)) {
command = message[i];
}
else if (i > sizeof(slaveIdentifier)) {
recipient[i - sizeof(slaveIdentifier) - 1] = message[i];
recipient[i - sizeof(slaveIdentifier)] = '\0';
}
} else {
Serial.println(F("Carattere non valido: "));
return EMPTY;
}
}
message[i] = '\0';
Serial.println(message);
Serial.print(F("Command: ")); Serial.println(command);
Serial.print(F("Recipient: ")); Serial.println(recipient);
if (command != ACK) {
received(slaveIdentifier, recipient);
}
return message;
}
Serial.println(F("Messaggio vuoto "));
return EMPTY;
}
void send(char* sender, char* receiver, char command) {
char tosend[(sizeof(sender) ) + (sizeof(receiver) ) + 1 + 1];
Serial.print(F("SizeofTosend:")); Serial.println(sizeof(tosend));
int i = 0;
for (int r = 0; r < sizeof(receiver) ; ++r, ++i) {
tosend[i] = receiver[r];
Serial.print(F("[1]IndexofTosend:")); Serial.println(tosend[i]);
}
tosend[i] = command;
Serial.print(F("[2]IndexofTosend:")); Serial.println(tosend[i]);
i++;
for (int r = 0; r < sizeof(sender); ++r, ++i) {
tosend[i] = sender[r];
Serial.print(F("[2]IndexofTosend:")); Serial.println(tosend[i]);
}
tosend[i] = '\0';
Serial.print(F("ToSend: ")); Serial.println(tosend);
do {
send(tosend);
delay(random(50, 500));
} while (!isReceived(sender, receiver) );
free(tosend);
}
boolean isReceived(char* sender, char* receiver) {
char ackMessage[sizeof(sender) + sizeof(receiver) + 1 + 1];
Serial.print(F("SizeofackMessage:")); Serial.println(sizeof(ackMessage));
int i = 0;
for (int r = 0; r < sizeof(receiver) ; ++r, ++i) {
ackMessage[i] = receiver[r];
Serial.print(F("[1]IndexofackMessage:")); Serial.println(ackMessage[i]);
}
ackMessage[i] = ACK;
Serial.print(F("[2]IndexofackMessage:")); Serial.println(ackMessage[i]);
i++;
for (int r = 0; r < sizeof(sender); ++r, ++i) {
ackMessage[i] = sender[r];
Serial.print(F("[2]IndexofackMessage:")); Serial.println(ackMessage[i]);
}
ackMessage[i] = '\0';
Serial.print(F("ackMessage: ")); Serial.println(ackMessage);
char* message = "M2KS2";//listenMessagesForMe();
Serial.print(F("ackMessage: ")); Serial.println(message);
if (message == EMPTY) {
return false;
}
if (sizeof(ackMessage) - 1 != strlen(message)) {
Serial.print(F("Different size ")); Serial.print(strlen(message) -1); Serial.println(sizeof(ackMessage));
//free(ackMessage);
//free(message);
return false;
}
for (int i = 0; i < sizeof(ackMessage) && i < sizeof(message); ++i) {
if (ackMessage[i] != message[i]) {
Serial.println(F("Caratteri diversi"));
//free(ackMessage);
// free(message);
return false;
}
}
Serial.println(F("RECEIVED!"));
//free(ackMessage);
//free(message);
return true;
}
void extractElements(char srcArray[], char subArray[], int n)
{
for (char i = 0; i < n; i++)
{
subArray[i] = srcArray[i];
}
}
void received(char* sender, char* receiver) {
send(sender, receiver, ACK);
}
void send(char* message) {
waitChannelFree();
vw_send((uint8_t *)message, strlen(message));
vw_wait_tx(); // Wait until the whole message is gone
}
void waitChannelFree() {
uint8_t buf[buflen];
do {
delay(random(150, 800));
} while (vw_get_message(buf, &buflen)) ;
}
Grazie a chi cercherà di aiutarmi e a chi mi darà qualche consiglio utile per migliorare il codice