Arduboy Messenger

We need a different approach to solve this problem:
we will generate when we press the button!

void enterNickname() {
    // Set the initial coordinates for the cursor
    int cursor_x = 20;
    int cursor_y = 25;

    arduboy.setCursor(0, 0);
    arduboy.print("Enter Nickname:");
    arduboy.display();

    uint8_t currentLetterIndex = 0;

    bool addressSaved = false;

    while (true) {
      arduboy.display();
      handleButtonsLR();
      drawKeyboard();

      arduboy.pollButtons();

      arduboy.setCursor(cursor_x, cursor_y);
      arduboy print(nickname);
      arduboy.setTextColor(WHITE);
      arduboy.setCursor(selectedLetterX + 2, selectedLetterY + 2);
      arduboy.print(selectedLetter);

      if (arduboy.justPressed(A_BUTTON)) {
        int length = strlen(nickname);

        if (length < 16) {
          nickname[length] = selectedLetter;
          nickname[length + 1] = '\0';
        }
      }
      memcpy(nickname, nickname, sizeof(nickname));
    
      arduboy.setCursor(0, 30);
      if (!addressSaved) {
        arduboy.print(F("Save address: press key A.."));
      } else {
        arduboy.setCursor(0, 50);
        arduboy.print(F("Exit: press key B.."));
      }
      arduboy.display();
     
      if (!addressSaved && arduboy.justPressed(A_BUTTON)) {
        // Generate and store addresses
        generateAddress(address);
        //addressStr = String(address[0], HEX) + String(address[1], HEX);
        String addressStr = String(address[0], HEX) + String(address[1], HEX);
        addressSaved = true;
      } else if (addressSaved && arduboy.justPressed(B_BUTTON)) {
        DDRB &= ~(1 << 5); // Set PB5 input
        pinsLoraHIGH();

        // Send commands to configure the LoRa module
        for (int i = 0; i < 6; i++) {
          Serial1.write(0xC2); //HEAD: C2 without save after disconnected C0 with saving
          Serial1.write((unsigned char)address[0]); //Receiver Address ADDH
          Serial1.write((unsigned char)address[1]); //Receiver Address ADDL
          Serial1.write(0x18); //parameters speed rx/tx 9600 0.3k bod airspeed
          Serial1.write(0x17); //Receiver channel =0x17=23 (410M+23=433MHz) 1f-441mhz
          Serial1.write(0x44); //transparent transmission 20dbm
          delay(50); // add a delay to prevent data loss
        }
        pinsLoraLOW();
        
        // Display the nickname and address on the screen and in the console
        arduboy.clear();
        arduboy.setCursor(0, 0);
        arduboy.print(F("Your Nickname:"));
        arduboy print(nickname);
        arduboy.setCursor(0, 10);
        arduboy.print(F("Your address:"));
        
        arduboy.print(address[0], HEX);
        arduboy.print(F(","));
        arduboy.print(address[1], HEX);

        arduboy.setCursor(0, 30);
        arduboy.print(F("Press key A.."));
        arduboy.display();
        
        while (!arduboy.pressed(A_BUTTON)) {
          arduboy.idle();
        }
        break;
      }
    }
}

now it doesn’t seem to give any errors, you need to try to load it into the console.

yes, my solution worked and the address was successfully generated and written to the module using simple commands sent from Serial1.
But at the same time, I need to save the initial parameters for polling (scanning) freed subscribers in an open channel, for this I provided for resetting the parameters to the initial ones in the LoraConfig screen: by long pressing button A (this is one of the options), since the generated address is already unique and not a single device can be polled at the same time, I checked (the EBYTE library did not want to accept and remember addresses and does not work as expected). Now the saved address needs to be transferred one to one to another who requests it and its address should be displayed on your screen (the old algorithm has been preserved and works as expected, if anything :)).
If someone understands why the EBYTE Lora E32 library does not want to accept and read addresses through atmega 32u4, respect to that!

Are you sure there isn’t more to the error message?
What do you get if you press the Copy error message button?

Without actual error messages I can’t help to identify the problem.

In your first version while(true) doesn’t actually loop because it ends with a break and doesn’t have any continues, and there’s a break that isn’t actually in a loop at all.

The second version doesn’t have either of those issues.

Either way, I think you’d be better off handling this with a state machine and splitting the code into smaller functions. E.g.

enum class State : uint8_t
{
	EnteringName,
	NameEntered,
	NameSaved,
	DisplayAddressAndName,
};

State state;

void loop()
{
	if(!arduboy.nextFrame())
		return;

	arduboy.pollButtons();

	arduboy.clear();
	
	switch(state)
	{
		case State::EnteringName:
			this->updateEnteringName();
			break;
			
		case State::NameEntered:
			this->updateNameEntered();
			break;
			
		case State::NameSaved:
			this->updateNameSaved();
			break;
			
		case State::DisplayAddressAndName:
			this->updateDisplayAddressAndName();
			break;
	}
	
	arduboy.display();
}

void updateEnteringName()
{
	if(arduboy.justPressed(A_BUTTON))
	{
		// ...
	}
	
	if(arduboy.justPressed(B_BUTTON))
	{
		// ...
	}
	
	// Print "Enter Nickname: "
	// Draw keyboard
	// Draw other stuff
}

void updateNameEntered()
{
	if(arduboy.justPressed(A_BUTTON))
	{
		state = State::NameSaved;
	}
	
	// Print "Press A to save."
}

void updateNameSaved()
{
	if(arduboy.justPressed(A_BUTTON))
	{
		state = State::DisplayAddressAndName;
	}
	
	// Print "Press B to exit."
}

void updateDisplayAddressAndName()
{
	if(arduboy.justPressed(A_BUTTON))
	{
		state = /* next state */;
	}
	
	// Print address and name
}

Breaking the code up into actual states would mean you don’t have to rely on the idling and loops, you could just have separate states that each handle a different step of the process.

Yes, I was already thinking of splitting some of the code into smaller functions. And yes, I like the previous version of the code more how it works, at least I see the correct address that was sent to me by the ‘scan’ command. And at the expense of enum, I will think of a lot of interesting ideas… Thanks

ps… In fact, there are already more than 20 iterations of the arduboy messenger (:

Enumerations are no more expensive than integers.
(Internally they are integers, all the added type safety is just zero-cost compile-time magic.)

1 Like

…began to understand EBYTE LoRa E32 library.
My mistake was that I didn’t read the Serial1 port which communicates directly with the module, so I got zeros instead of values.
Now it looks like this:

//function for restoring the initial configuration of the modes of transmitting/receiving messages over a common channel
void setDefaultConfiguration() {
     //set the state of pins M0 M1 to HIGH - MODE3
     DDRB &= ~(1 << 5); // Set PB5 input
     pinsLoraHIGH();
     /*
     //Serial1.flush(); // clear buffer
     // while ( !digitalRead(pinAUX)); // waiting for readiness add 19052023
     //delay(2000);
     */
  
   // Send commands to configure the LoRa module
   /*
   for (int i = 0; i < 6; i++) {
     Serial1.write(0xC2); //HEAD: C2 without save after disconected C0 with saving
     Serial1.write(0x0); //Receiver Address ADDH
     Serial1.write(0x1); //Receiver Address ADDL
     Serial1.write(0x18); //parameters speed rx/tx 9600 0.3k bod airspeed
     Serial1.write(0x17); //Receiver channel =0x17=23 (410M+23=433MHz) 1f-441mhz
     Serial1.write(0x44); //transparent transmission 20dbm
     delay(50); // add a delay to prevent data loss
   }
     */
    
     ResponseStructContainer c;
     c = Lora.getConfiguration();
     Configuration configuration = *(Configuration*) c.data;
     Serial1.println(c.status.getResponseDescription()); //if you need the output of the set parameters in Serail
     Serial1.println(c.status.code);
     configuration.ADDH=0x00; //setting default address values //1st byte
     configuration.ADDL=0x02; //setting default address values //2nd byte
     configuration.CHAN = 0x17; //0x00-0x1f+410=441mhz MaxFreq//0x17// freq=23+410=433mhz //3rd byte
    
     //data transfer will be in fixed transfer mode, in which the master device is
     //transmitting commands and data to the slave device, and the slave device simply listens and transmits data in response.
     //4th byte
     configuration.OPTION.fec = FEC_1_ON; //FEC_0_OFF;
     configuration.OPTION.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; //FT_FIXED_TRANSMISSION;
     configuration.OPTION.ioDriveMode = IO_D_MODE_PUSH_PULLS_PULL_UPS;
     configuration.OPTION.transmissionPower = POWER_20; //POWER_17;
     configuration.OPTION.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_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 off, the settings remain!!!
     ResponseStatus rs = Lora.setConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE); //settings are lost when the power is turned off
     Serial1.println(rs.getResponseDescription());
     arduboy.setCursor(1, 48);
     arduboy.print(rs.getResponseDescription());
     Serial.println(rs.getResponseDescription());
     Serial1.println(rs.code);
     arduboy.setCursor(1, 55);
     arduboy.print(rs.code);
     Serial.println(rs.code); //if 1 then the lora module is ready to work
    
     printParameters(configuration);
    
     c.close();
     delay(500);
     // while ( !digitalRead(pinAUX)); //wait for Lora to be ready after accepting the settings
     //Lora.resetModule();
     //restore the state of pins M0 M1 to MODE0
     pinsLoraLOW();
     //Serial1.flush(); // clear buffer
     //handleButtonsHoldExit();
}

void printParameters(struct Configuration configuration) {
   arduboy.clear();
   arduboy.setCursor(1, 0);
  
   // Display values from the Configuration structure
   arduboy.print("HEAD: ");
   Serial1.println(configuration.HEAD, BIN);
   arduboy.print(configuration.HEAD, BIN);
  
   arduboy.setCursor(1, 10);
   arduboy.print("ADDH: ");
   Serial1.println(configuration.ADDH, HEX);
   arduboy.print(configuration.ADDH, HEX);
  
   arduboy.setCursor(1, 20);
   arduboy.print("ADDL: ");
   Serial1.println(configuration.ADDL, HEX);
   arduboy.print(configuration.ADDL, HEX);
  
   arduboy.setCursor(1, 30);
   arduboy.print("CHAN: ");
   Serial1.println(configuration.CHAN, DEC);
  
   Serial1.println(configuration.getChannelDescription());
   arduboy.print(configuration.CHAN, DEC);
  
   arduboy.setCursor(1, 40);
   arduboy.print("TxPw: ");
   Serial1.println(configuration.OPTION.transmissionPower, BIN);
   arduboy.print(configuration.OPTION.transmissionPower, BIN);
  
   arduboy.setCursor(1, 50);
   arduboy.print("PwStat: ");
   Serial1.println(configuration.OPTION.getTransmissionPowerDescription());
   arduboy.print(configuration.OPTION.getTransmissionPowerDescription());
   
   arduboy.display();
   handleButtonsHoldExit();
}

I divided the transfer of addresses so that there would be no confusion in receiving data:

void send Address(int ADD, int ADD) {
  String address = String(ADD);
  String address = String(ADD);

// Sending the ADDH part
to Serial1.print(address); // sending to Serial1
  Lora.SendMessage(address); // we send by LoRa
  
  // Sending comma
  unsigned char command = ',';
  Serial1.write(&command, 1);
  Lora.sendMessage(&comma, 1);
  
  // Sending the ADDL part 
  Serial1.print(address); // send to Serial1
  Lora.SendMessage(address); // we send by LoRa

  Serial.println("Send address: ");
  Serial.print(address);
  Serial.print(",");
  Serial.println(address);
}

I checked, accepts what I generated on the transmitting side correctly. now on…

listening to commands from Serial1:

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());
      
      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); //sending the address to everyone via an open channel
        sendAddress(ADDH, ADDL); //sending ADDH ADDL addresses to everyone via an open channel
        //////////////////////////////////////////////////////////////////////////////
      }
        
        //waitForPairingResponse(incomingMessageNickname);
         else if (strcmp(incomingMessageNickname.c_str(), "pair: Y") == 0) {
              arduboy.setCursor(0, 30);
              arduboy.print("Pair created!");
          
         }
         else if (strcmp(incomingMessageNickname.c_str(), "pair: N") == 0) {
              arduboy.setCursor(0, 30);
              arduboy.print("Pairing rejected");
              setDefaultConfiguration();
         }
         //if ((strcmp(incomingMessageNickname.c_str(), "pair: Y") == 0) || (strcmp(incomingMessageNickname.c_str(), "pair: N") == 0)) {
      }
      else {
        bool found = false;
        for (int i = 0; i < MAX_NICKNAMES; i++) {
if (nicknames[i] == incomingMessageNickname) { //checking already accepted nicknames by name match
            found = true; //if found, sets the flag to true
            break;
          }
        }
        if (!found) { 
          for (int i = 0; i < MAX_NICKNAMES; i++) { //running through the list of accepted new nicknames
            if (nicknames[i].length() == 0) {
              nicknames[i] = incomingMessageNickname;
              newNicknames[i] = true; //flag for new nicknames 
              break;
            }
          }
        }
      }
    }
}

we send the scan command with the ‘right button’ and see who responded to us:

void displayNicknames() {
  
  arduboy.setCursor(1, 1);
  arduboy.print("Select Nickname:");
  int textWidth = arduboy.getCharacterWidth("Select Nickname:");
  arduboy.drawRect(0, 0, textWidth + 2, 10, WHITE);
  arduboy.setCursor(100, 2);
  arduboy.print(selectedNicknameIndex + 1);

  bool newNicknameFound = false;

  for (int i = 0; i < MAX_NICKNAMES; i++) {
    if (newNicknames[i]) {
      if (previousNicknameIndex == i) {
        arduboy.fillRect(0, 10 + i * 10, 128, 10, WHITE);
        arduboy.setTextColor(BLACK);
      } else {
        arduboy.fillRect(0, 10 + i * 10, 128, 10, BLACK);
        arduboy.setTextColor(WHITE);
      }
      arduboy.setCursor(0, 10 + i * 10);
      arduboy.print(nicknames[i].c_str());
      newNicknames[i] = false;
      newNicknameFound = true;
    } else {
      if (previousNicknameIndex == i) {
        arduboy.fillRect(0, 10 + i * 10, 128, 10, WHITE);
        arduboy.setTextColor(BLACK);
      } else {
        arduboy.fillRect(0, 10 + i * 10, 128, 10, BLACK);
        arduboy.setTextColor(WHITE);
      }
      arduboy.setCursor(0, 10 + i * 10);
      arduboy.print(nicknames[i].c_str());
    }
  }
  if (!newNicknameFound) {
    if (arduboy.justPressed(UP_BUTTON)) {
      previousNicknameIndex = selectedNicknameIndex; // update the previous selected nickname before changing the index
      selectedNicknameIndex--;
      if (selectedNicknameIndex < 0) {
        selectedNicknameIndex = MAX_NICKNAMES - 1;
      }
    }
    else if (arduboy.justPressed(DOWN_BUTTON)) {
      previousNicknameIndex = selectedNicknameIndex;
      selectedNicknameIndex++;
      if (selectedNicknameIndex >= MAX_NICKNAMES) {
        selectedNicknameIndex = 0;
      }
    }
  }
  if (arduboy.justPressed(A_BUTTON)) {
    beep.tone(beep.freq(1000)); // Play a 1000Hz tone until stopped
    arduboy.delayShort(30); // Delay for 30ms
    beep.noTone(); // Stop the tone
    
    //here we will poll the functions to create a pair:
    //while it works for sending only via the address channel, but not exactly %), in the open channel after the decomment, it is necessary to TODO does not work:
    
    changeMyAddressOnAddressPair(nicknames[selectedNicknameIndex]); //changing our address to the address of the selected pair in the function
    
    //makePair(); // if we comment on this function, there are no errors! the decor gives out - Error compiling for board Arduboy FX.

    //makePairFunction(); //we will request it in changeMyAddressOnAddressPair..we send a confirmation request that the pair has been created pair: Y/N
    
    //sendNickname(nicknames[selectedNicknameIndex]);
    
  }
  arduboy.display();
}

further more interesting…the function of changing the address to the address of the pair:

void changeMyAddressOnAddressPair(String selectedNicknames) {
  int commaIndex = selectedNicknames.indexOf(',');

  String incomingH = selectedNicknames.substring(0, commaIndex);
  String incomingL = selectedNicknames.substring(commaIndex + 1);

  //Configuration config = Lora.getConfiguration().response; // getting the current configuration
  incomingADDH = incomingH.toInt(); // changing ADDH
  incomingADDL = incomingL.toInt(); // changing ADDL
  // Temporarily changing the address for the address channel to the address of the pair
  setAddrConfiguration(incomingADDH, incomingADDL);
  getConfigurationLoraPair();
}

culmination…another function of creating a pair:

void makePair() { 

  sendFixedData(nickname); // sending your nickname
  sendFixedData(": "); //separator
  sendFixedData("pair: Y/N"); //creating a pair
  arduboy.setCursor(1, 0);
  arduboy.print(F("pair? Yes-A/No-B"));
  
  // We send a message to confirm the creation of a pair
  if (arduboy.justPressed(A_BUTTON)){
    // if the A button is pressed, we send "Y" (Yes) to another Arduino 
    sendFixedData(nickname); // sending your nickname
    sendFixedData(": ");
    sendFixedData("pair: Y"); //creating a pair
    arduboy.setCursor(1, 20);
    arduboy.print(F("Pair request sent"));
  }
  
  else if (arduboy.justPressed(B_BUTTON)) {
    sendFixedData(nickname); // sending your nickname
    sendFixedData(": ");
    sendFixedData("pair: N");
    arduboy.setCursor(0, 20);
    arduboy.print(F("Pairing rejected"));
  }
  
  //waitForPairingResponse();
  
  //handleButtonsHoldExit();
}

if you decomment makePair() in void handleIncomingNicknames() at the end, an error occurs:
Error compiling for board Arduboy FX.

without makePair();
note: Sketch uses 22126 bytes (74%) of program storage space. Maximum is 29696 bytes.
Global variables use 2120 bytes (82%) of dynamic memory, leaving 440 bytes for local variables. Maximum is 2560 bytes.

note: what we will see in port:

Arduino: 1.8.19 (Windows 7), Board: "Arduboy FX, Arduboy optimized core, Cathy3K (starts with menu)"
C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\HP\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\HP\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\HP\Documents\Arduino\libraries -fqbn=arduboy-homemade:avr:arduboy-fx:core=arduboy-core,boot=cathy3k -vid-pid=2341_8036 -ide-version=10819 -build-path C:\Users\HP\AppData\Local\Temp\arduino_build_133126 -warnings=none -build-cache C:\Users\HP\AppData\Local\Temp\arduino_cache_34420 -prefs=build.warn_data_percentage=75 -verbose C:\Users\HP\YandexDisk\ARDUBOY\ArduGAME_projects\AGLM_TEST_nickname_addh_addl_19_23052023\AGLM_TEST_nickname_addh_addl_19_23052023.ino

C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\HP\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\HP\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\HP\Documents\Arduino\libraries -fqbn=arduboy-homemade:avr:arduboy-fx:core=arduboy-core,boot=cathy3k -vid-pid=2341_8036 -ide-version=10819 -build-path C:\Users\HP\AppData\Local\Temp\arduino_build_133126 -warnings=none -build-cache C:\Users\HP\AppData\Local\Temp\arduino_cache_34420 -prefs=build.warn_data_percentage=75 -verbose C:\Users\HP\YandexDisk\ARDUBOY\ArduGAME_projects\AGLM_TEST_nickname_addh_addl_19_23052023\AGLM_TEST_nickname_addh_addl_19_23052023.ino

Using board 'arduboy-fx' from platform in folder: C:\Users\HP\AppData\Local\Arduino15\packages\arduboy-homemade\hardware\avr\1.3.8

Using core 'arduboy' from platform in folder: C:\Users\HP\AppData\Local\Arduino15\packages\arduboy-homemade\hardware\avr\1.3.8

Detecting libraries used...

"C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_ARDUBOY -DARDUINO_ARCH_AVR -DARDUBOY_10 -DCART_CS_SDA -DUSB_VID=0x2341 -DUSB_PID=0x8036 "-DUSB_MANUFACTURER=\"Arduboy Inc\"" "-DUSB_PRODUCT=\"Arduboy\"" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\cores\\arduboy" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\variants\\arduboy" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\sketch\\AGLM_TEST_nickname_addh_addl_19_23052023.ino.cpp" -o nul

Alternatives for LoRa_E32.h: [EByte_LoRa_E32_library@1.5.12]

ResolveLibrary(LoRa_E32.h)

  -> candidates: [EByte_LoRa_E32_library@1.5.12]

"C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_ARDUBOY -DARDUINO_ARCH_AVR -DARDUBOY_10 -DCART_CS_SDA -DUSB_VID=0x2341 -DUSB_PID=0x8036 "-DUSB_MANUFACTURER=\"Arduboy Inc\"" "-DUSB_PRODUCT=\"Arduboy\"" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\cores\\arduboy" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\variants\\arduboy" "-IC:\\Users\\HP\\Documents\\Arduino\\libraries\\EByte_LoRa_E32_library" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\sketch\\AGLM_TEST_nickname_addh_addl_19_23052023.ino.cpp" -o nul

Alternatives for SoftwareSerial.h: [SoftwareSerial@1.0]

ResolveLibrary(SoftwareSerial.h)

  -> candidates: [SoftwareSerial@1.0]

"C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_ARDUBOY -DARDUINO_ARCH_AVR -DARDUBOY_10 -DCART_CS_SDA -DUSB_VID=0x2341 -DUSB_PID=0x8036 "-DUSB_MANUFACTURER=\"Arduboy Inc\"" "-DUSB_PRODUCT=\"Arduboy\"" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\cores\\arduboy" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\variants\\arduboy" "-IC:\\Users\\HP\\Documents\\Arduino\\libraries\\EByte_LoRa_E32_library" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\libraries\\SoftwareSerial\\src" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\sketch\\AGLM_TEST_nickname_addh_addl_19_23052023.ino.cpp" -o nul

Alternatives for Arduboy2.h: [Arduboy2@6.0.0 Arduboy2@6.0.0]

ResolveLibrary(Arduboy2.h)

  -> candidates: [Arduboy2@6.0.0 Arduboy2@6.0.0]

"C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_ARDUBOY -DARDUINO_ARCH_AVR -DARDUBOY_10 -DCART_CS_SDA -DUSB_VID=0x2341 -DUSB_PID=0x8036 "-DUSB_MANUFACTURER=\"Arduboy Inc\"" "-DUSB_PRODUCT=\"Arduboy\"" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\cores\\arduboy" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\variants\\arduboy" "-IC:\\Users\\HP\\Documents\\Arduino\\libraries\\EByte_LoRa_E32_library" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\libraries\\SoftwareSerial\\src" "-IC:\\Users\\HP\\Documents\\Arduino\\libraries\\Arduboy2\\src" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\sketch\\AGLM_TEST_nickname_addh_addl_19_23052023.ino.cpp" -o nul

Alternatives for EEPROM.h: [EEPROM EEPROM@2.0]

ResolveLibrary(EEPROM.h)

  -> candidates: [EEPROM EEPROM@2.0]

"C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_ARDUBOY -DARDUINO_ARCH_AVR -DARDUBOY_10 -DCART_CS_SDA -DUSB_VID=0x2341 -DUSB_PID=0x8036 "-DUSB_MANUFACTURER=\"Arduboy Inc\"" "-DUSB_PRODUCT=\"Arduboy\"" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\cores\\arduboy" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\variants\\arduboy" "-IC:\\Users\\HP\\Documents\\Arduino\\libraries\\EByte_LoRa_E32_library" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\libraries\\SoftwareSerial\\src" "-IC:\\Users\\HP\\Documents\\Arduino\\libraries\\Arduboy2\\src" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\libraries\\EEPROM\\src" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\sketch\\AGLM_TEST_nickname_addh_addl_19_23052023.ino.cpp" -o nul

Using cached library dependencies for file: C:\Users\HP\Documents\Arduino\libraries\EByte_LoRa_E32_library\LoRa_E32.cpp

Using cached library dependencies for file: C:\Users\HP\AppData\Local\Arduino15\packages\arduboy-homemade\hardware\avr\1.3.8\libraries\SoftwareSerial\src\SoftwareSerial.cpp

Using cached library dependencies for file: C:\Users\HP\Documents\Arduino\libraries\Arduboy2\src\Arduboy2.cpp

Using cached library dependencies for file: C:\Users\HP\Documents\Arduino\libraries\Arduboy2\src\Arduboy2Audio.cpp

Using cached library dependencies for file: C:\Users\HP\Documents\Arduino\libraries\Arduboy2\src\Arduboy2Beep.cpp

Using cached library dependencies for file: C:\Users\HP\Documents\Arduino\libraries\Arduboy2\src\Arduboy2Core.cpp

Using cached library dependencies for file: C:\Users\HP\Documents\Arduino\libraries\Arduboy2\src\Arduboy2Data.cpp

Using cached library dependencies for file: C:\Users\HP\Documents\Arduino\libraries\Arduboy2\src\Sprites.cpp

Using cached library dependencies for file: C:\Users\HP\Documents\Arduino\libraries\Arduboy2\src\SpritesB.cpp

Generating function prototypes...

"C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_ARDUBOY -DARDUINO_ARCH_AVR -DARDUBOY_10 -DCART_CS_SDA -DUSB_VID=0x2341 -DUSB_PID=0x8036 "-DUSB_MANUFACTURER=\"Arduboy Inc\"" "-DUSB_PRODUCT=\"Arduboy\"" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\cores\\arduboy" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\variants\\arduboy" "-IC:\\Users\\HP\\Documents\\Arduino\\libraries\\EByte_LoRa_E32_library" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\libraries\\SoftwareSerial\\src" "-IC:\\Users\\HP\\Documents\\Arduino\\libraries\\Arduboy2\\src" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\libraries\\EEPROM\\src" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\sketch\\AGLM_TEST_nickname_addh_addl_19_23052023.ino.cpp" -o "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\preproc\\ctags_target_for_gcc_minus_e.cpp"

"C:\\Program Files (x86)\\Arduino\\tools-builder\\ctags\\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\preproc\\ctags_target_for_gcc_minus_e.cpp"

Compiling sketch...

"C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_ARDUBOY -DARDUINO_ARCH_AVR -DARDUBOY_10 -DCART_CS_SDA -DUSB_VID=0x2341 -DUSB_PID=0x8036 "-DUSB_MANUFACTURER=\"Arduboy Inc\"" "-DUSB_PRODUCT=\"Arduboy\"" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\cores\\arduboy" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\variants\\arduboy" "-IC:\\Users\\HP\\Documents\\Arduino\\libraries\\EByte_LoRa_E32_library" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\libraries\\SoftwareSerial\\src" "-IC:\\Users\\HP\\Documents\\Arduino\\libraries\\Arduboy2\\src" "-IC:\\Users\\HP\\AppData\\Local\\Arduino15\\packages\\arduboy-homemade\\hardware\\avr\\1.3.8\\libraries\\EEPROM\\src" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\sketch\\AGLM_TEST_nickname_addh_addl_19_23052023.ino.cpp" -o "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\sketch\\AGLM_TEST_nickname_addh_addl_19_23052023.ino.cpp.o"

Compiling libraries...

Compiling library "EByte_LoRa_E32_library"

Using previously compiled file: C:\Users\HP\AppData\Local\Temp\arduino_build_133126\libraries\EByte_LoRa_E32_library\LoRa_E32.cpp.o

Compiling library "SoftwareSerial"

Using previously compiled file: C:\Users\HP\AppData\Local\Temp\arduino_build_133126\libraries\SoftwareSerial\SoftwareSerial.cpp.o

Compiling library "Arduboy2"

Using previously compiled file: C:\Users\HP\AppData\Local\Temp\arduino_build_133126\libraries\Arduboy2\Arduboy2.cpp.o

Using previously compiled file: C:\Users\HP\AppData\Local\Temp\arduino_build_133126\libraries\Arduboy2\Arduboy2Audio.cpp.o

Using previously compiled file: C:\Users\HP\AppData\Local\Temp\arduino_build_133126\libraries\Arduboy2\Arduboy2Beep.cpp.o

Using previously compiled file: C:\Users\HP\AppData\Local\Temp\arduino_build_133126\libraries\Arduboy2\Arduboy2Data.cpp.o

Using previously compiled file: C:\Users\HP\AppData\Local\Temp\arduino_build_133126\libraries\Arduboy2\Arduboy2Core.cpp.o

Using previously compiled file: C:\Users\HP\AppData\Local\Temp\arduino_build_133126\libraries\Arduboy2\Sprites.cpp.o

Using previously compiled file: C:\Users\HP\AppData\Local\Temp\arduino_build_133126\libraries\Arduboy2\SpritesB.cpp.o

Compiling library "EEPROM"

Compiling core...

Using precompiled core: C:\Users\HP\AppData\Local\Temp\arduino_cache_34420\core\core_67e8e4cec76053b7e64cf64275c17d63.a

Linking everything together...

"C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr/bin/avr-gcc" -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega32u4 -o "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126/AGLM_TEST_nickname_addh_addl_19_23052023.ino.elf" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\sketch\\AGLM_TEST_nickname_addh_addl_19_23052023.ino.cpp.o" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\libraries\\EByte_LoRa_E32_library\\LoRa_E32.cpp.o" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\libraries\\SoftwareSerial\\SoftwareSerial.cpp.o" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\libraries\\Arduboy2\\Arduboy2.cpp.o" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\libraries\\Arduboy2\\Arduboy2Audio.cpp.o" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\libraries\\Arduboy2\\Arduboy2Beep.cpp.o" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\libraries\\Arduboy2\\Arduboy2Core.cpp.o" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\libraries\\Arduboy2\\Arduboy2Data.cpp.o" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\libraries\\Arduboy2\\Sprites.cpp.o" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126\\libraries\\Arduboy2\\SpritesB.cpp.o" "C:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126/..\\arduino_cache_34420\\core\\core_67e8e4cec76053b7e64cf64275c17d63.a" "-LC:\\Users\\HP\\AppData\\Local\\Temp\\arduino_build_133126" -lm

C:\Users\HP\AppData\Local\Temp\ccPwcyue.ltrans0.ltrans.o: In function `sendFixedData(char const*)':

C:\Users\HP\YandexDisk\ARDUBOY\ArduGAME_projects\AGLM_TEST_nickname_addh_addl_19_23052023/AGLM_TEST_nickname_addh_addl_19_23052023.ino:2027: undefined reference to `setAddrConfiguration()'

collect2.exe: error: ld returned 1 exit status

Multiple libraries were found for "Arduboy2.h"

 Used: C:\Users\HP\Documents\Arduino\libraries\Arduboy2

 Not used: C:\Users\HP\AppData\Local\Arduino15\packages\arduboy-homemade\hardware\avr\1.3.8\libraries\Arduboy2

Multiple libraries were found for "EEPROM.h"

 Used: C:\Users\HP\AppData\Local\Arduino15\packages\arduboy-homemade\hardware\avr\1.3.8\libraries\EEPROM

 Not used: C:\Program Files (x86)\Arduino\libraries\EEPROM

Using library EByte_LoRa_E32_library at version 1.5.12 in folder: C:\Users\HP\Documents\Arduino\libraries\EByte_LoRa_E32_library 

Using library SoftwareSerial at version 1.0 in folder: C:\Users\HP\AppData\Local\Arduino15\packages\arduboy-homemade\hardware\avr\1.3.8\libraries\SoftwareSerial 

Using library Arduboy2 at version 6.0.0 in folder: C:\Users\HP\Documents\Arduino\libraries\Arduboy2 

Using library EEPROM at version 2.0 in folder: C:\Users\HP\AppData\Local\Arduino15\packages\arduboy-homemade\hardware\avr\1.3.8\libraries\EEPROM 

exit status 1

Error compiling for board Arduboy FX.

This is exactly the kind of thing I was hoping to see.

When you see that message it means that there’s a linker error rather than a compiler error.

The message above explains what the problem is:

setAddrConfiguration has seemingly been declared but not defined.

Without seeing the whole of the code I couldn’t say for definite what’s wrong. If you do think you’re defining setAddrConfiguration somewhere then I’m guessing there’s either a spelling mistake or a mistake in the order at which things are included.

If you’ve just shoved everything into a single .ino file, that could also be the problem. Arduino preprocesses the .ino files to produce a .cpp file and sometimes it produces incorrect results.

(That’s one of the reasons I prefer to use .ino files as little as possible. .h and .cpp files are more difficult to learn how to use properly, but they’re more dependable.)


The later parts of the message show that you’ve still got both the original Arduboy2 libraries installed as well as the homemade package. The compiler resolved the conflict by choosing to use the homemade package.


This is getting to the point where you might want to think about looking for ways to save RAM.

To start, I’d suggest wrapping your strings in the F macro, which puts them in progmem instead of RAM. It’ll only work for the Arduino libraries though, not for the avr-libc libraries (i.e. strcmp, strcpy et cetera).

E.g. arduboy.print(F("Select Nickname:"));.

(с днём рожде́ния by the way.)

1 Like

:slight_smile: Thank you

A bit of optimization…

void makePair() { 

  // Creating a string containing your nickname, a separator and a message about creating a pair
  String message = nickname + ": " + "pair: Y/N";

  // We send this line on the serial port
  sendFixedData(message);

  // Display a message on the display
  arduboy.setCursor(1, 0);
  arduboy.print(F("pair? Yes-A/No-B"));
  
  // We send a message to confirm the creation of a pair
  if (arduboy.justPressed(A_BUTTON)){

    // Creating a line with a message about the successful creation of a pair
    String pairMessage = nickname + ": " + "pair: Y";
    
    // We send this line on the serial port
    sendFixedData(pairMessage);

    arduboy.setCursor(1, 20);
    arduboy.print(F("Pair request sent"));
  }
  
  else if (arduboy.justPressed(B_BUTTON)) {

    // Creating a line with a message about the rejection of the request to create a pair
    String rejectMessage = nickname + ": " + "pair: N";
    
    // We send this line on the serial port
    sendFixedData(rejectMessage);

    arduboy.setCursor(0, 20);
    arduboy.print(F("Pairing rejected"));
  }

  //waitForPairingResponse();
  
  //handleButtonsHoldExit();
}

Have you checked it? It doesn’t work that way for me, since it is necessary to transfer 6bytes

No. I have nothing to test it.

That’s the idea. as long as there are not 6 bytes received the while will loop.

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…


the module will receive them anyway, you can control it in the Lora E32 parameter mapping function ‘void getConfigurationLora()’ :
here the main thing is to provide pause in parameter passing:

for (int i = 0; i < 6; i++) {
     Serial1.write(0xC2); //HEAD: C2 without save after disconected C0 with saving
     Serial1.write(ADDH); //Receiver Address ADDH
     Serial1.write(ADDL); //Receiver Address ADDL
     Serial1.write(0x1A); //0x18 parameters speed rx/tx 9600 0.3k bod airspeed
     Serial1.write(0x17); //Receiver channel =0x17=23 (410M+23=433MHz) 1f-441mhz
     Serial1.write(0xC4); //0xC4 transparent transmission 20dbm
     delay(50); // add a delay to prevent data loss
   }

you also need a pause when reading the parameters, and everything must be at the same data rates!

uint8_t loraData[6] = {0}; // Create an array to store parameters

   delay(1000); // Give the module time to return the parameters
  
   Serial1.write(0xC1); // Pass 3 bytes for the module to return the current parameters
   Serial1.write(0xC1);
   Serial1.write(0xC1);

   if (Serial1.available() >= 6) { // Check if enough bytes are available
     for (int i = 0; i < 6; i++) { // Read bytes into array
       loraData[i] = Serial1.read();
       //Serial.print(loraData[i], HEX);
       //Serial.print(" ");
     }
     Serial.println();
   }
  
   for (int i = 0; i < 6; i++) { // Display parameter values on the screen
     
      arduboy.println(loraData[i], HEX);
   }

in Setup need add better this test:

// Check AUX pin state for new modules. If is LOW then active
  if (digitalRead(pinAUX) == LOW) {
    digitalWrite(pinM0, LOW);
    digitalWrite(pinM1, HIGH);
    //pause(100);
    digitalWrite(pinM0, HIGH);
  }

Yes, this idea takes place if a packet of 6 bytes is sent several times. But here the idea is that a high level appears on the AUX pin after receiving these 6bytes, so the module will be ready for further manipulations. I would suggest another way to check the received bytes, say the bytes of the address (ADDH, ADDL) can be any from 0-255 they can not be checked, but the remaining 4bytes should be compared, if they came the wrong ones, then they cannot be written to the module.

p.s. to do this, I have provided in menu 4 (with a gear) the restoration of the Lora parameters, while holding the A button, this will return the module to its original state without reboot messenger

changed the nickname selection function in the BROscanner menu. Now from the first click goes to the selection of the desired nickname:

void displayNicknames() {
   /*
  arduboy.setCursor(1, 1);
  arduboy.print("Select Nickname:");
  uint8_t textWidth = arduboy.getCharacterWidth("Select Nickname:");
  arduboy.drawRect(0, 0, textWidth + 2, 10, WHITE);
  arduboy.setCursor(100, 2);
  */
  arduboy.fillRect(0, 0, 96, 9, WHITE); // creating a background inversion on the top row
  
  arduboy.setCursor(1, 1);
  arduboy.setTextColor(BLACK);
  arduboy.print("Select Nickname:");
  uint8_t textWidth = arduboy.getCharacterWidth("Select Nickname:");
  arduboy.setTextColor(WHITE);
  arduboy.setCursor(110, 1);
  arduboy.print(selectedNicknameIndex + 1);

  bool newNicknameFound = false;

  // Set selectedNicknameIndex to 0 on first launch.
  if (previousNicknameIndex == MAX_NICKNAMES && selectedNicknameIndex == MAX_NICKNAMES) {
    previousNicknameIndex = 0;
    selectedNicknameIndex = 0;
  }

   for (int i = 0; i < MAX_NICKNAMES; i++) {
    if (newNicknames[i]) {
      if (previousNicknameIndex == i) {
        arduboy.fillRect(0, 10 + i * 10, 128, 10, WHITE);
        arduboy.setTextColor(BLACK);
      } else {
        arduboy.fillRect(0, 10 + i * 10, 128, 10, BLACK);
        arduboy.setTextColor(WHITE);
      }
      arduboy.setCursor(0, 10 + i * 10);
      arduboy.print(nicknames[i].c_str());
      newNicknames[i] = false;
      newNicknameFound = true;
    } 
    else {
      if (previousNicknameIndex == i) {
        arduboy.fillRect(0, 10 + i * 10, 128, 10, WHITE);
        arduboy.setTextColor(BLACK);
      } else {
        arduboy.fillRect(0, 10 + i * 10, 128, 10, BLACK);
        arduboy.setTextColor(WHITE);
      }
      arduboy.setCursor(0, 10 + i * 10);
      arduboy.print(nicknames[i].c_str());
    }
  }

    if (previousNicknameIndex != selectedNicknameIndex) {
        arduboy.fillRect(0, 10 + previousNicknameIndex * 10, 128, 10, BLACK);
        arduboy.setTextColor(WHITE);
        arduboy.setCursor(0, 10 + previousNicknameIndex * 10);
        arduboy.print(nicknames[previousNicknameIndex].c_str());
        arduboy.fillRect(0, 10 + selectedNicknameIndex * 10, 128, 10, WHITE);
        arduboy.setTextColor(BLACK);
        arduboy.setCursor(0, 10 + selectedNicknameIndex * 10);
        arduboy.print(nicknames[selectedNicknameIndex].c_str());
    }
    previousNicknameIndex = selectedNicknameIndex;


  if (arduboy.justPressed(UP_BUTTON)) {
    if (selectedNicknameIndex == 0) {
      previousNicknameIndex = selectedNicknameIndex;
      selectedNicknameIndex = MAX_NICKNAMES - 1;
    } else {
      previousNicknameIndex--;
      selectedNicknameIndex--;
    }
  }

  if (arduboy.justPressed(DOWN_BUTTON)) {
    if (selectedNicknameIndex == MAX_NICKNAMES - 1) {
      previousNicknameIndex = selectedNicknameIndex;
      selectedNicknameIndex = 0;
    } else {
      previousNicknameIndex++;
      selectedNicknameIndex++;
    }
  }
  if (arduboy.justPressed(A_BUTTON)) {
    beep.tone(beep.freq(1000)); // Play a 1000Hz tone until stopped
    arduboy.delayShort(30); // Delay for 30ms
    beep.noTone(); // Stop the tone
    
    //here we will poll the functions to create a pair:
       changeMyAddressOnAddressPair(nicknames[selectedNicknameIndex]); //changing our address to the address of the selected pair in the function
  }
  arduboy.display();
}

let’s deal further with the transmission protocol when creating a pair… will have to add a flag for transmission in the open channel (transparentTransmission) and in the address channel (fixedTransmission) since we have only one function for receiving messages…

LoRa_ArduChat_rev25_12062023.hex (68.1 KB)

I propose to give the name of the messenger Arduboy, let it be a “PagerBoy” (:





2 Likes