I have already tested the function of receiving an address from a subscriber and it works. it remains to comb the code and call functions in those places where it needs to be done:
// Variable declaration lastMessageNickname
String lastMessageNickname = "";
int ADDH; //to generate address values when addressing data transfer
int ADDL; //to generate address values when addressing data transfer
//incomingADDH and incomingADDL for assigning my addresses to the address of the interlocutor
//extern byte incomingADDH = 0;
//extern byte incomingADDL = 0;
char nickname[17] = {'\0'};
char address[8]; // = {'\0'}; //to generate ADDH, ADDL addresses
//byte address[2] = {0, 0}; //to generate just two addresses ADDH, ADDL
byte incomingADDH=0;
byte incomingADDL=0;
void sendNickname(String nickname);
void sendAddress(unsigned char* address);
void sendData(const char*data);
////void handleIncomingMessages();
void sendFixedData(const char* data);
void setDefaultConfiguration();
void setMyConfigurationLora(); //new add 28052023
void setAddrConfiguration();
void getConfigurationLora();
void printParameters(struct Configuration configuration);
//void printModuleInformation(struct ModuleInformation moduleInformation);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//function for restoring the initial configuration of the modes of transmission/reception of messages over a common channel//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setDefaultConfiguration() {
/*
//PORT &= ~(1 << 5); // Reset bit 5
//PORT WINE |= (1 << 5); // tightening tip 5
//RDRB &= ~(1 << 5); // Set the PB5
//PORT WINE input |= (1 << 5); // Turn on the pull-up resistor
// DDRB &=~PB5_MASK; //open collector pb5 pinAUX
// DDRB |= PB5_MASK; //open-drain
// DDRD |= PD2_MASK; //open-merge
// DDRD &= ~PD2_MASK; //pinTX with open collector
//Lora.resetModule();
*/
//setting the pin state M0 M1 to the HIGH - MODE3 state
RDRB &= ~(1 << 5); // Set the PB5 input
pinsLoraHAIG();
/*
//Digital recording(10, MAXIMUM);
//Digital recording(11, HIGH);
//Serial1.flush(); // clearing the buffer
//while ( !digitalRead(pinAUX)); // permission to add 19052023
//delay(2000);
*/
//while ( !digitalRead(pinAUX));
//delay(1000);
// Use the commands to configure the LoRa module
for (int i = 0; i < 6; i++) {
Serial1.write(0xC2); //HEADER: C2 without saving after disabling C0 with saving
Serial1.write(0x0); //ADDH recipient address
Serial1.write(0x0); //Adding the recipient address
Serial1.write(0x1A); //0x18 parameters speed rx/tx 9600 0.3k bod airspeed
Serial1.write(0x17); //Receiver channel =0x17=23 (410 M+23=433MHz) 1f-441mhz
Serial1.write(0x44); //0xC4 transparent transmission 20 dbm
delay(50); // adding a delay to prevent data loss
}
/*
ResponseStructContainer c;
c = Lora.getConfiguration();
Configuration configuration = *(Configuration*) c.data;
Serial1.println(c.status.getResponseDescription()); //if the user has entered a user password in Serail
Serial1.println(c.status.code);
configuration.ADDH = 0x0; //setting an additional address value //1st byte
configuration.ADDL = 0x1; //setting an additional address value //2nd byte
configuration.CHAN = 0x17; //0x00-0x1f+410=441 MHz Maximum frequency//0x17// frequency=23+410=433MHz //3rd byte
//data transmission will be carried out in fixed transmission mode, in which the master device
transmits commands and data to the slave device, and the slave device simply listens and transmits data in response.
//4th byte
configuration.PARAMETER.fec = FEC_1_ON; //FEC_0_OFF;
configuration.PARAMETER.Fixed transmission = FT_TRANSPARENT_TRANSMISSION; //FT_FIXED_TRANSMISSION;
configuration.PARAMETER.ioDriveMode = IO_D_MODE_PUSH_PULLS_PULL_UPS;
configuration.PARAMETER.Transmission power = POWER_20; //POWER_17;
configuration.PARAMETER.wirelessWakeupTime = WAKE_UP_250; //WAKE_UP_1250;
//5th byte
configuration.SPED.uartParity = MODE_00_8N1;
configuration.SPED.uartBaudRate = UART_BPS_9600; //UART_BPS_115200;
configuration.SPED.airDataRate = AIR_DATA_RATE_011_48; //AIR_DATA_RATE_000_03; //AIR_DATA_RATE_011_48;
//6th byte
//ResponseStatus rs = Lora.SetConfiguration(configuration, WRITE_CFG_PWR_DWN_SAVE); //important, the settings are disabled when the power is turned on!!!
ResponseStatus rs = Lora.SetConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE); //when the power is turned off, the settings are lost
Serial1.println(rs.getResponseDescription());
Serial1.println(rs.code);
//printParameters(configuration);
c.close();
delay(500);
//while ( !digitalRead(pinAUX)); //we expect Laura to be ready after the decision
is made //Lora.resetModule();
//while ( !digitalRead(pinAUX)); // permission to add 19052023
//we establish the connection of pins M0 M1 in connection mode 0
*/
pinsLoraLOW();
/*
//Lora.resetModule(); //restart Lora
//Digital recording(10, LOW level);
//Digital recording(11, LOW level);
//Serial1.flush(); // clearing the buffer
//handleButtonsHoldExit();
*/
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///Setting parameters from your generated device ADDH ADDL//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setMyConfigurationLora(uint8_t ADDH, uint8_t ADDL) {
/*
//PORT &= ~(1 << 5); // Reset bit 5
//PORT WINE |= (1 << 5); // tightening tip 5
//RDRB &= ~(1 << 5); // Set the PB5
//PORT WINE input |= (1 << 5); // Turn on the pull-up resistor
// DDRB &=~PB5_MASK; //open collector pb5 pinAUX
// DDRB |= PB5_MASK; //open-drain
// DDRD |= PD2_MASK; //open-merge
// DDRD &= ~PD2_MASK; //pinTX with open collector
//Lora.resetModule();
*/
//setting the pin state M0 M1 to the HIGH - MODE3 state
RDRB &= ~(1 << 5); // Set the PB5 input
pinsLoraHAIG();
/*
//Digital recording(10, MAXIMUM);
//Digital recording(11, HIGH);
//Serial1.flush(); // clearing the buffer
//while ( !digitalRead(pinAUX)); // permission to add 19052023
//delay(2000);
*/
//while ( !digitalRead(pinAUX));
//delay(1000);
// Use the commands to configure the LoRa module
for (int i = 0; i < 6; i++) {
Serial1.write(0xC2); //HEADER: C2 without saving after disabling C0 with saving
Serial1.write(ADDH); //ADDH recipient address
Serial1.write(ADDL); //ADDL recipient address
Serial1.write(0x1A); //0x18 parameters speed rx/tx 9600 0.3k bod airspeed
Serial1.write(0x17); //Receiver channel =0x17=23 (410 M+23=433MHz) 1f-441mhz
Serial1.write(0xC4); //Transparent transmission 0xC4 20 dbm
delay(50); // adding a delay to prevent data loss
}
/*
ResponseStructContainer c;
c = Lora.getConfiguration();
Configuration configuration = *(Configuration*) c.data;
Serial1.println(c.status.getResponseDescription()); //if the user has entered a user password in Serail
Serial1.println(c.status.code);
configuration.ADDH = 0x0; //setting an additional address value //1st byte
configuration.ADDL = 0x1; //setting an additional address value //2nd byte
configuration.CHAN = 0x17; //0x00-0x1f+410=441 MHz Maximum frequency//0x17// frequency=23+410=433MHz //3rd byte
//data transmission will be carried out in fixed transmission mode, in which the master device
transmits commands and data to the slave device, and the slave device simply listens and transmits data in response.
//4th byte
configuration.PARAMETER.fec = FEC_1_ON; //FEC_0_OFF;
configuration.PARAMETER.Fixed transmission = FT_TRANSPARENT_TRANSMISSION; //FT_FIXED_TRANSMISSION;
configuration.PARAMETER.ioDriveMode = IO_D_MODE_PUSH_PULLS_PULL_UPS;
configuration.PARAMETER.Transmission power = POWER_20; //POWER_17;
configuration.PARAMETER.wirelessWakeupTime = WAKE_UP_250; //WAKE_UP_1250;
//5th byte
configuration.SPED.uartParity = MODE_00_8N1;
configuration.SPED.uartBaudRate = UART_BPS_9600; //UART_BPS_115200;
configuration.SPED.airDataRate = AIR_DATA_RATE_011_48; //AIR_DATA_RATE_000_03; //AIR_DATA_RATE_011_48;
//6th byte
//ResponseStatus rs = Lora.SetConfiguration(configuration, WRITE_CFG_PWR_DWN_SAVE); //important, when the power is turned on, the settings are disabled!!!
ResponseStatus rs = Lora.SetConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE); //when the power is turned off, the settings are lost
Serial1.println(rs.getResponseDescription());
Serial1.println(rs.code);
//printParameters(configuration);
c.close();
delay(500);
//while ( !digitalRead(pinAUX)); //we expect Laura to be ready after the decision
is made //Lora.resetModule();
//while ( !digitalRead(pinAUX)); // permission to add 19052023
//we establish the connection of pins M0 M1 in connection mode 0
*/
pinsLoraLOW();
/*
//Lora.resetModule(); //restart Lora
//Digital recording(10, LOW level);
//Digital recording(11, LOW level);
//Serial1.flush(); // clearing the buffer
//handleButtonsHoldExit();
*/
}
///////////////////////////////////////////////////////////////////////////////////////
// to display the configuration of the Lora parameters //
//////////////////////////////////////////////////////////////////////////////////////
void getConfigurationLora() {
pinsLoraHIGH(); //to get the settings information from the lora module, set the pins M0 M1 to HIGH according to the manual
// Get the parameters of the LoRa module and display them on the Arduboy screen
arduboy.clear(); // Clearing the Arduboy screen
arduboy.setCursor(0, 0);
arduboy.println("LoRa config: ");
/*
arduboy.setCursor(40, 10);
arduboy.println(":HEAD");
arduboy.setCursor(40, 18);
arduboy.println(":ADDH");
arduboy.setCursor(40, 26);
arduboy.println(":ADDL");
arduboy.setCursor(40, 34);
arduboy.println(":SPED");
arduboy.setCursor(40, 42);
arduboy.println(":CHAN");
arduboy.setCursor(40, 50);
arduboy.println(":OPTION");
*/
arduboy.setCursor(1, 10);
uint8_t loraData[6] = {0}; // Creating an array to store parameters
delay(1000); // Giving the module time to return the parameters
Serial1.write(0xC1); // We pass 3 bytes so that the module returns the current parameters
Serial1.write(0xC1);
Serial1.write(0xC1);
if (Serial1.available() >= 6) { // Check that enough bytes are available
for (int i = 0; i < 6; i++) { // Reading bytes into an array
loraData[i] = Serial1.read();
//Serial.print(loraData[i], HEX);
//Serial.print(" ");
}
Serial.println();
}
for (int i = 0; i < 6; i++) { // Output parameter values to the screen
arduboy.println(loraData[i], HEX);
}
//arduboy.setCursor(1, 30);
//arduboy.print("Exit: loong key_B... ");
pinsLoraLOW();
/*
pinsLoraHIGH();
ResponseStructContainer c;
c = Lora.getConfiguration();
Configuration configuration = *(Configuration*) c.data;
//printParameters(configuration);
arduboy.setCursor(1, 48);
arduboy.print(c.status.getResponseDescription());
arduboy.setCursor(1, 55);
arduboy.print(c.status.code);
c.close();
*/
arduboy.display(); // Displaying information on the screen
/*
//Lora.resetModule();
//while ( !digitalRead(pinAUX)); // waiting for readiness add 19052023
//request parameters
//for (int i = 0; i < 3; i++) {
//Serial1.write(byte (0xC1));
//delay(2000); // adding a delay to prevent data loss
//}
ResponseStructContainer c;
c = Lora.getConfiguration();
// It's important get configuration pointer before all other operation
Configuration configuration = *(Configuration*) c.data;
printParameters(configuration); //output of the set parameters of Lora
//printParameters_(); //simplified output of confirmation of accepted parameters with Lora
//printLoRaConfiguration();
arduboy.setCursor(1, 50);
arduboy.print(c.status.getResponseDescription());
arduboy.print(c.status.code);
c.close();
*/
//pinsLoraLOW(); // according to the manual, we return pins M0 M1 to LOW
/*
//digitalWrite(10, LOW);
//digitalWrite(11, LOW);
//Lora.resetModule(); //reset lora
//handleButtonsHoldExit();
*/
handleButtonsHoldExit();
}
void handleIncomingNicknames() {
// Read incoming message from serial
if (Serial1.available()) {
String incomingMessageNickname = Serial1.readString();
if (incomingMessageNickname.length() > 0) {
Serial.println("Received Scan data from module:");
Serial.write(incomingMessageNickname.c_str(), incomingMessageNickname.length());
Serial.println(" ");
if (strcmp(incomingMessageNickname.c_str(), "scan") == 0) {
/////////////////////////////////////////////////// /////////////////////////////
sendNickname(nickname); //this is just sending a nickname to everyone via an open channel
unsigned char comma = ':';
Serial1.write(&comma, 1);
Lora.sendMessage(&comma);
//sendAddress(address); //send the address to everyone via an open channel
sendAddress(ADDH, ADDL);
// after sending the Scan command, we set our generated address to the parameters of the Lora module, it is no longer default!!!
//because the subscriber accepted my address parameters for communication in the address channel sendFixedData
setMyConfigurationLora(ADDH, ADDL);
//sendAddress(address); //was when sended all in one address
//Serial.println(ADDH, HEX);
//Serial.println(ADDL, HEX);
/////////////////////////////////////////////////// /////////////////////////////
}
/*
//waitForPairingResponse(incomingMessageNickname);
if (strcmp(incomingMessageNickname.c_str(), "pair? Yes-A/No-B") == 0) {
arduboy.clear();
arduboy.setCursor(0, 30);
arduboy.print("pair? Yes-A/No-B");
if (arduboy.justPressed(A_BUTTON)){
// if button A is pressed, send "Y" (Yes) to another Arduino
sendFixedData(nickname); //send your nickname
sendFixedData(": ");
sendFixedData("pair: Y"); // create a pair
arduboy.setCursor(0, 20);
arduboy.print("pair: Y");
}
if (arduboy.justPressed(B_BUTTON)){
// if button A is pressed, send "Y" (Yes) to another Arduino
sendFixedData(nickname); //send your nickname
sendFixedData(": ");
sendFixedData("pair: N"); // create a pair
arduboy.setCursor(0, 20);
arduboy.print("pair: N");
}
}
/*
//if this piece of code is commented, then the Lora module passes the test
//waitForPairingResponse(incomingMessageNickname);
if (strcmp(incomingMessageNickname.c_str(), "pair: Y") == 0) {
arduboy.setCursor(0, 30);
arduboy.print("Pair created!");
}
if (strcmp(incomingMessageNickname.c_str(), "pair: N") == 0) {
arduboy.setCursor(0, 30);
arduboy.print("Pairing rejected");
setDefaultConfiguration();
}
*/
//changeMyAddressOnAddressPair(); //change your address to address
else {
bool found = false;
for (int i = 0; i < MAX_NICKNAMES; i++) {
if (nicknames[i] == incomingMessageNickname) { //check already accepted nicknames for matching names
found = true; //if found sets the flag to true
break;
}
}
if (!found) {
for (int i = 0; i < MAX_NICKNAMES; i++) { //run through the list of accepted new nicknames
if (nicknames[i].length() == 0) {
nicknames[i] = incomingMessageNickname;
newNicknames[i] = true; //flag for new nicknames
break;
}
}
}
}
}
}
}
void handleIncomingNicknames() {
// Read incoming message from serial
if (Serial1.available()) {
String incomingMessageNickname = Serial1.readString();
if (incomingMessageNickname.length() > 0) {
Serial.println("Received Scan data from module:");
Serial.write(incomingMessageNickname.c_str(), incomingMessageNickname.length());
Serial.println(" ");
if (strcmp(incomingMessageNickname.c_str(), "scan") == 0) {
/////////////////////////////////////////////////// /////////////////////////////
sendNickname(nickname); //this is just sending a nickname to everyone via an open channel
unsigned char comma = ':';
Serial1.write(&comma, 1);
Lora.sendMessage(&comma);
//sendAddress(address); //send the address to everyone via an open channel
sendAddress(ADDH, ADDL);
//We set our generated address to the parameters of the Lora module, it is no longer default!!!
setMyConfigurationLora(ADDH, ADDL);
//sendAddress(address);
//Serial.println(ADDH, HEX);
//Serial.println(ADDL, HEX);
/////////////////////////////////////////////////// /////////////////////////////
}
/*
//waitForPairingResponse(incomingMessageNickname);
if (strcmp(incomingMessageNickname.c_str(), "pair? Yes-A/No-B") == 0) {
arduboy.clear();
arduboy.setCursor(0, 30);
arduboy.print("pair? Yes-A/No-B");
if (arduboy.justPressed(A_BUTTON)){
// if button A is pressed, send "Y" (Yes) to another Arduino
sendFixedData(nickname); //send your nickname
sendFixedData(": ");
sendFixedData("pair: Y"); // create a pair
arduboy.setCursor(0, 20);
arduboy.print("pair: Y");
}
if (arduboy.justPressed(B_BUTTON)){
// if button A is pressed, send "Y" (Yes) to another Arduino
sendFixedData(nickname); //send your nickname
sendFixedData(": ");
sendFixedData("pair: N"); // create a pair
arduboy.setCursor(0, 20);
arduboy.print("pair: N");
}
}
/*
//if this piece of code is commented, then the Lora module passes the test
//waitForPairingResponse(incomingMessageNickname);
if (strcmp(incomingMessageNickname.c_str(), "pair: Y") == 0) {
arduboy.setCursor(0, 30);
arduboy.print("Pair created!");
}
if (strcmp(incomingMessageNickname.c_str(), "pair: N") == 0) {
arduboy.setCursor(0, 30);
arduboy.print("Pairing rejected");
setDefaultConfiguration();
}
*/
//changeMyAddressOnAddressPair(); //change your address to address
else {
bool found = false;
for (int i = 0; i < MAX_NICKNAMES; i++) {
if (nicknames[i] == incomingMessageNickname) { //check already accepted nicknames for matching names
found = true; //if found sets the flag to true
break;
}
}
if (!found) {
for (int i = 0; i < MAX_NICKNAMES; i++) { //run through the list of accepted new nicknames
if (nicknames[i].length() == 0) {
nicknames[i] = incomingMessageNickname;
newNicknames[i] = true; //flag for new nicknames
break;
}
}
}
}
}
}
}
void changeMyAddressOnAddressPair(String selectedNicknames) {
selectedNicknames.trim(); // remove spaces at the beginning and end of the string
String delimiter = ":";
int delimiterPosition = selectedNicknames.indexOf(delimiter);
if (delimiterPosition >= 0) {
String nickname = selectedNicknames.substring(0, delimiterPosition);
String addressString = selectedNicknames.substring(delimiterPosition + 1);
delimiter=",";
delimiterPosition = addressString.indexOf(delimiter);
if (delimiterPosition >= 0 && (addressString.length() - delimiterPosition) > 1) {
String incomingH = addressString.substring(0, delimiterPosition); //.toInt(); // replace ADDH with incomingADDH
incomingADDH = incomingH.toInt(); // change ADDH
String incomingL = addressString.substring(delimiterPosition + 1); //.toInt(); // replace ADDL with incomingADDL
incomingADDL = incomingL.toInt(); // change ADDL
Serial.println(" ");
Serial.println("Received incomingADDH:");
Serial.println(incomingADDH);
Serial.println("Received incomingADDL:");
Serial.println(incomingADDL);
//handleButtonsHoldExit(); //exit menu
// get out of here by pressing button B
if (arduboy.justPressed(A_BUTTON)) {
arduboy.clear(); // clear screen
arduboy.setCursor(0, 0);
arduboy.print("incomingADDH:"); //+ incomingADDH);
arduboy.print(incomingADDH, HEX);
arduboy.setCursor(0, 8);
arduboy.print("incomingADDL:"); // + incomingADDL);
arduboy.println(incomingADDL, HEX);
delay(2000);
// while (!arduboy.pressed(B_BUTTON)) {
// arduboy.idle();
// }
// Temporarily change the address for the address channel to the address of the pair
setAddrConfiguration(incomingADDH, incomingADDL); //passing the addresses to the function for writing new Lora parameters
getConfigurationLora(); //read what was written to the Lora module
//setDefaultConfiguration();
// add messaging functions over the address channel
while (!arduboy.pressed(A_BUTTON)) {
arduboy.idle();
}
/*
*
*/
/*
while (!arduboy.pressed(B_BUTTON)) {
arduboy.idle();
}
arduboy.clear(); // clear screen
arduboy.setCursor(0, 0);
arduboy.print("RecoverDefaultConf:");
setDefaultConfiguration();
getConfigurationLora();
*/
//arduboy.display(); // display the image on the screen
//sendData("pair is made"); ///DEBUG
}
if (arduboy.justPressed(B_BUTTON)) {
//sendData("pairing rejected"); ///DEBUG
//setDefaultConfiguration();
delay(500);
//return(1);
}
//makePairFunction();
}
}
}
a few screenshots…starting the messenger, entering a nickname and generating addresses…then go to the BROscan menu and send the ‘scan’ command, then the received address is selected with the A button and recorded on your device for transmission over the address channel, and the sender, in turn, has his own generated address too. this ensures a single address transmission of sandFixedDate…