text:
esp based smart light system over alexa malfunctioning
i made a home automation system using esp 32 and 8 channel relay but within 2 or 3 months my relay automatically turns off after sending the signal to it through esp32 but if i connect directly without esp32 it functions absolutely fine. that means that my relay if fine but what must be the possible reason for this malfunctioning.
this is my code
#include <ESP8266WiFi.h>
#include <Espalexa.h>
Espalexa espalexa;

// define the GPIO connected with Relays and switches
#define RelayPin1 5  //D23
#define RelayPin2 4  //D22
#define RelayPin3 0  //D21
#define RelayPin4 2  //D19
#define RelayPin5 14  //D18
#define RelayPin6 12  //D5
#define RelayPin7 13  //D25
#define RelayPin8 15  //D26

#define SwitchPin1 3  //D13
#define SwitchPin2 1  //D12
#define SwitchPin3 10  //D14
#define SwitchPin4 9  //D27
#define SwitchPin5 8  //D33
#define SwitchPin6 11  //D32
#define SwitchPin7 7  //D15
#define SwitchPin8 6   //D4

bool oldStateSwitch_1;
bool oldStateSwitch_2;
bool oldStateSwitch_3;
bool oldStateSwitch_4;
bool oldStateSwitch_5;
bool oldStateSwitch_6;
bool oldStateSwitch_7;
bool oldStateSwitch_8;

#define wifiLed    16   //D2

// WiFi Credentials
const char* ssid = "akkikisu";
const char* password = "anirudh@123";

// device names
String Device_1_Name = "a1";
String Device_2_Name = "a2";
String Device_3_Name = "a3";
String Device_4_Name = "a4";
String Device_5_Name = "a5";
String Device_6_Name = "a6";
String Device_7_Name = "a7";
String Device_8_Name = "a8";

// prototypes
boolean connectWifi();

//callback functions
void firstLightChanged(uint8_t brightness);
void secondLightChanged(uint8_t brightness);
void thirdLightChanged(uint8_t brightness);
void fourthLightChanged(uint8_t brightness);
void fifthLightChanged(uint8_t brightness);
void sixthLightChanged(uint8_t brightness);
void senventhLightChanged(uint8_t brightness);
void eighthLightChanged(uint8_t brightness);

boolean wifiConnected = false;

//our callback functions
void firstLightChanged(uint8_t brightness)
{
  //Control the device
  if (brightness == 255)
    {
      digitalWrite(RelayPin1, LOW);
      Serial.println("Device1 ON");
    }
  else
  {
    digitalWrite(RelayPin1, HIGH);
    Serial.println("Device1 OFF");
  }
}

void secondLightChanged(uint8_t brightness)
{
  //Control the device
  if (brightness == 255)
    {
      digitalWrite(RelayPin2, LOW);
      Serial.println("Device2 ON");
    }
  else
  {
    digitalWrite(RelayPin2, HIGH);
    Serial.println("Device2 OFF");
  }
}

void thirdLightChanged(uint8_t brightness)
{
  //Control the device
  if (brightness == 255)
    {
      digitalWrite(RelayPin3, LOW);
      Serial.println("Device3 ON");
    }
  else
  {
    digitalWrite(RelayPin3, HIGH);
    Serial.println("Device3 OFF");
  }
}

void fourthLightChanged(uint8_t brightness)
{
  //Control the device
  if (brightness == 255)
    {
      digitalWrite(RelayPin4, LOW);
      Serial.println("Device4 ON");
    }
  else
  {
    digitalWrite(RelayPin4, HIGH);
    Serial.println("Device4 OFF");
  }
}

void fifthLightChanged(uint8_t brightness)
{
  //Control the device
  if (brightness == 255)
    {
      digitalWrite(RelayPin5, LOW);
      Serial.println("Device5 ON");
    }
  else
  {
    digitalWrite(RelayPin5, HIGH);
    Serial.println("Device1 OFF");
  }
}

void sixthLightChanged(uint8_t brightness)
{
  //Control the device
  if (brightness == 255)
    {
      digitalWrite(RelayPin6, LOW);
      Serial.println("Device6 ON");
    }
  else
  {
    digitalWrite(RelayPin6, HIGH);
    Serial.println("Device6 OFF");
  }
}

void seventhLightChanged(uint8_t brightness)
{
  //Control the device
  if (brightness == 255)
    {
      digitalWrite(RelayPin7, LOW);
      Serial.println("Device7 ON");
    }
  else
  {
    digitalWrite(RelayPin7, HIGH);
    Serial.println("Device7 OFF");
  }
}

void eighthLightChanged(uint8_t brightness)
{
  //Control the device
  if (brightness == 255)
    {
      digitalWrite(RelayPin8, LOW);
      Serial.println("Device8 ON");
    }
  else
  {
    digitalWrite(RelayPin8, HIGH);
    Serial.println("Device8 OFF");
  }
}

// connect to wifi – returns true if successful or false if not
boolean connectWifi()
{
  boolean state = true;
  int i = 0;

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");
  Serial.println("Connecting to WiFi");

  // Wait for connection
  Serial.print("Connecting...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if (i > 20) {
      state = false; break;
    }
    i++;
  }
  Serial.println("");
  if (state) {
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  }
  else {
    Serial.println("Connection failed.");
  }
  return state;
}

void addDevices(){
  // Define your devices here.
  espalexa.addDevice(Device_1_Name, firstLightChanged); //simplest definition, default state off
  espalexa.addDevice(Device_2_Name, secondLightChanged);
  espalexa.addDevice(Device_3_Name, thirdLightChanged);
  espalexa.addDevice(Device_4_Name, fourthLightChanged);
  espalexa.addDevice(Device_5_Name, fifthLightChanged);
  espalexa.addDevice(Device_6_Name, sixthLightChanged);
  espalexa.addDevice(Device_7_Name, seventhLightChanged);
  espalexa.addDevice(Device_8_Name, eighthLightChanged);

  espalexa.begin();
}

void setup()
{
  Serial.begin(115200);

  pinMode(RelayPin1, OUTPUT);
  pinMode(RelayPin2, OUTPUT);
  pinMode(RelayPin3, OUTPUT);
  pinMode(RelayPin4, OUTPUT);
  pinMode(RelayPin5, OUTPUT);
  pinMode(RelayPin6, OUTPUT);
  pinMode(RelayPin7, OUTPUT);
  pinMode(RelayPin8, OUTPUT);

  pinMode(wifiLed, OUTPUT);

  pinMode(SwitchPin1, INPUT_PULLUP);
  pinMode(SwitchPin2, INPUT_PULLUP);
  pinMode(SwitchPin3, INPUT_PULLUP);
  pinMode(SwitchPin4, INPUT_PULLUP);
  pinMode(SwitchPin5, INPUT_PULLUP);
  pinMode(SwitchPin6, INPUT_PULLUP);
  pinMode(SwitchPin7, INPUT_PULLUP);
  pinMode(SwitchPin8, INPUT_PULLUP);

  //During Starting all Relays should TURN OFF
  digitalWrite(RelayPin1, HIGH);
  digitalWrite(RelayPin2, HIGH);
  digitalWrite(RelayPin3, HIGH);
  digitalWrite(RelayPin4, HIGH);
  digitalWrite(RelayPin5, HIGH);
  digitalWrite(RelayPin6, HIGH);
  digitalWrite(RelayPin7, HIGH);
  digitalWrite(RelayPin8, HIGH);

  oldStateSwitch_1 = ! digitalRead( SwitchPin1 ) ;  // note inverted
  oldStateSwitch_2 = ! digitalRead( SwitchPin2 ) ;  // note inverted
  oldStateSwitch_3 = ! digitalRead( SwitchPin3 ) ;  // note inverted
  oldStateSwitch_4 = ! digitalRead( SwitchPin4 ) ;  // note inverted
  oldStateSwitch_5 = ! digitalRead( SwitchPin5 ) ;  // note inverted
  oldStateSwitch_6 = ! digitalRead( SwitchPin6 ) ;  // note inverted
  oldStateSwitch_7 = ! digitalRead( SwitchPin7 ) ;  // note inverted
  oldStateSwitch_8 = ! digitalRead( SwitchPin8 ) ;  // note inverted

    // repeat for seitched 2 to 8

  // Initialise wifi connection
  wifiConnected = connectWifi();

  if (wifiConnected)
  {
    addDevices();
  }
  else
  {
    Serial.println("Cannot connect to WiFi. So in Manual Mode");
    delay(1000);
  }
}

void loop()
{
   if (WiFi.status() != WL_CONNECTED)
  {
    //Serial.print("WiFi Not Connected ");
    digitalWrite(wifiLed, LOW); //Turn off WiFi LED
  }
  else
  {
    //Serial.print("WiFi Connected  ");
    digitalWrite(wifiLed, HIGH);
    //Manual Switch Control
    //WiFi Control
    if (wifiConnected){
      espalexa.loop();
      delay(1);
    }
    else {
      wifiConnected = connectWifi(); // Initialise wifi connection
      if(wifiConnected){
      addDevices();
      }
    }
  }

//main code

static uint32_t lastSwitchTest = 0 ;  // static initialised once only

      if ( millis() - lastSwitchTest > 250 ) {  // every 250ms
      lastSwitchTest = millis() ;

      // switch 1

      bool stateSwitch_1 = digitalRead( SwitchPin1 ) ;
      if (  oldStateSwitch_1 != stateSwitch_1 ) {
         oldStateSwitch_1 = stateSwitch_1 ;
         Serial.println("Switch 1 changed");
         EspalexaDevice* d1 = espalexa.getDevice(0); //this will get "first device", the index is zero-based
         if ( stateSwitch_1 == HIGH )  {  // HIGH = off
            Serial.println("Switch 1 off");
            d1->setPercent(0); //set value "brightness" in percent
            digitalWrite(RelayPin1, HIGH);
         }
         else { // switch on
            Serial.println("Switch 1 on");
            d1->setPercent(100); //set value "brightness" in percent
            digitalWrite(RelayPin1, LOW);
         }
      }

      // switch 2

      bool stateSwitch_2 = digitalRead( SwitchPin2 ) ;
      if ( oldStateSwitch_2 != stateSwitch_2 ) {
         oldStateSwitch_2 = stateSwitch_2 ;
         Serial.println("Switch 2 changed");
         EspalexaDevice* d2 = espalexa.getDevice(0); //this will get "first device", the index is zero-based
         if ( stateSwitch_2 == HIGH )  {  // HIGH = off
            Serial.println("Switch 2 off");
            d2->setPercent(0); //set value "brightness" in percent
            digitalWrite(RelayPin2, HIGH);
         }
         else { // switch on
            Serial.println("Switch 2 on");
            d2->setPercent(100); //set value "brightness" in percent
            digitalWrite(RelayPin2, LOW);
         }
      }

      // switch 3

      bool stateSwitch_3 = digitalRead( SwitchPin3 ) ;
      if ( oldStateSwitch_3 != stateSwitch_3 ) {
         oldStateSwitch_3 = stateSwitch_3 ;
         Serial.println("Switch 3 changed");
         EspalexaDevice* d3 = espalexa.getDevice(0); //this will get "first device", the index is zero-based
         if ( stateSwitch_3 == HIGH )  {  // HIGH = off
            Serial.println("Switch 1 off");
            d3->setPercent(0); //set value "brightness" in percent
            digitalWrite(RelayPin3, HIGH);
         }
         else { // switch on
            Serial.println("Switch 3 on");
            d3->setPercent(100); //set value "brightness" in percent
            digitalWrite(RelayPin3, LOW);
         }
      }
      // switch 4

      bool stateSwitch_4 = digitalRead( SwitchPin4 ) ;
      if ( oldStateSwitch_4 != stateSwitch_4 ) {
         oldStateSwitch_4 = stateSwitch_4 ;
         Serial.println("Switch 4 changed");
         EspalexaDevice* d4 = espalexa.getDevice(0); //this will get "first device", the index is zero-based
         if ( stateSwitch_4 == HIGH )  {  // HIGH = off
            Serial.println("Switch 1 off");
            d4->setPercent(0); //set value "brightness" in percent
            digitalWrite(RelayPin4, HIGH);
         }
         else { // switch on
            Serial.println("Switch 4 on");
            d4->setPercent(100); //set value "brightness" in percent
            digitalWrite(RelayPin4, LOW);
         }
      }
      // switch 5

      bool stateSwitch_5 = digitalRead( SwitchPin5 ) ;
      if ( oldStateSwitch_5 != stateSwitch_5 ) {
         oldStateSwitch_5 = stateSwitch_5 ;
         Serial.println("Switch 5 changed");
         EspalexaDevice* d5 = espalexa.getDevice(0); //this will get "first device", the index is zero-based
         if ( stateSwitch_5 == HIGH )  {  // HIGH = off
            Serial.println("Switch 1 off");
            d5->setPercent(0); //set value "brightness" in percent
            digitalWrite(RelayPin5, HIGH);
         }
         else { // switch on
            Serial.println("Switch 5 on");
            d5->setPercent(100); //set value "brightness" in percent
            digitalWrite(RelayPin5, LOW);
         }
      }
      // switch 6

      bool stateSwitch_6 = digitalRead( SwitchPin6 ) ;
      if ( oldStateSwitch_6 != stateSwitch_6 ) {
         oldStateSwitch_6 = stateSwitch_6 ;
         Serial.println("Switch 6 changed");
         EspalexaDevice* d6 = espalexa.getDevice(0); //this will get "first device", the index is zero-based
         if ( stateSwitch_6 == HIGH )  {  // HIGH = off
            Serial.println("Switch 1 off");
            d6->setPercent(0); //set value "brightness" in percent
            digitalWrite(RelayPin6, HIGH);
         }
         else { // switch on
            Serial.println("Switch 6 on");
            d6->setPercent(100); //set value "brightness" in percent
            digitalWrite(RelayPin6, LOW);
         }
      }
      // switch 7

      bool stateSwitch_7 = digitalRead( SwitchPin7 ) ;
      if ( oldStateSwitch_7 != stateSwitch_7 ) {
         oldStateSwitch_7 = stateSwitch_7 ;
         Serial.println("Switch 7 changed");
         EspalexaDevice* d7 = espalexa.getDevice(0); //this will get "first device", the index is zero-based
         if ( stateSwitch_7 == HIGH )  {  // HIGH = off
            Serial.println("Switch 1 off");
            d7->setPercent(0); //set value "brightness" in percent
            digitalWrite(RelayPin7, HIGH);
         }
         else { // switch on
            Serial.println("Switch 7 on");
            d7->setPercent(100); //set value "brightness" in percent
            digitalWrite(RelayPin7, LOW);
         }
      }
      // switch 8

      bool stateSwitch_8 = digitalRead( SwitchPin8 ) ;
      if ( oldStateSwitch_8 != stateSwitch_8 ) {
         oldStateSwitch_8 = stateSwitch_8 ;
         Serial.println("Switch 8 changed");
         EspalexaDevice* d8 = espalexa.getDevice(0); //this will get "first device", the index is zero-based
         if ( stateSwitch_8 == HIGH )  {  // HIGH = off
            Serial.println("Switch 1 off");
            d8->setPercent(0); //set value "brightness" in percent
            digitalWrite(RelayPin8, HIGH);
         }
         else { // switch on
            Serial.println("Switch 8 on");
            d8->setPercent(100); //set value "brightness" in percent
            digitalWrite(RelayPin8, LOW);
         }
      }

      // switch 2 to 8
      // just copy/paste/adjust using switch 1 as a template

    } // if ( millis
} // loop()

Every 2 or 3 months you get a spurious triggering of your relay module which you attribute to a software problem on the esp32. Is that correct? If so, it could be a bad handling of the millis() rollover somewhere in your code or a library. This rollover occurs every 49 days.

@6v6gt and how can i rectify my problem

I'd suspect the button library acebutton.h . It appears to use 16bit datatypes for holding timings, probably derived from millis(), for button debouncing etc. 32 bit integers would be more appropriate. Using another library may solve this. But you have to conduct a long term test.

which library can i use . and can you tell me the appropriate code for that

Let's get the problem description right before looking deeper for a solution. When you say that it works without the ESP32, do you mean that you are able to connect the 8 channel relay module directly to the Alexa? You said this spurious behaviour happens within 2 or 3 months. Is it possible that it happens regularly every 49 days? Are you using push buttons or toggle type switches for the manual relay control?
Is it so that you will only know you have a working solution after testing over a 2 to 3 month period?

https://iotcircuithub.com/esp32-alexa-home-automation-system/ so here you can find all the detals

OK. From the project link, it is clear that the buttons are in fact toggle type switches. Please answer the remaining questions I've asked before. Also, if you press the reset button on the ESP32 do you get the same effect that you say appears after 2-3 months, that is spurious switching of the relays? The button library adds an unnecessary complexity and the code can be restructured to eliminate it. It is not certain that that would solve the problem, though. A memory leak may also give similar effects.

yes after pressing the reset button also i face the same issue. and yes i think it may be occuring within 49 days of time and one more big probem is that i can re program my board as i broke the micro usb pin

You are using the following project as a code base: https://iotcircuithub.com/esp32-alexa-home-automation-system/
You appear to have confirmed that the same problem symptoms appear when the ESP32 is reset, that is that some lights are in the wrong state at system start. A reset can be caused by such things as a system reset following a power outage, a crash or simply pressing the reset button on the device.
You are using a button handling library AceButton.h in combination with latched switches. The problem here is that the button handling library is intended for momentory push-to-make buttons and assumes that the switch is in the "un-pushed" state at system start. This may not reflect the position of the latched switches where some could be in the on position and others in the off position. This could result in missed events on system start.
Anyway, you do not need a button library. Especially for toggle type switches, like you are using, where it is necessary only to read the switch say every 250ms and test if the state has been changed since the last reading. No other debouncing is required.
In setup() you'd read each switch and store the inverse of its current state in a variable, say oldStateSwitch_1. It is necessary to store the inverse of the state to trigger a first time switch state change action in the loop().
Something like . . .
void setup() {
    . . .

    oldStateSwitch_1 = ! digitalRead( switchPin1 ) ;  // note inverted
    // repeat for seitched 2 to 8
    . . .

}

In the loop(), you'd do something like . . .
void loop() {

. . .
. . .

    static uint32_t lastSwitchTest = 0 ;  // static initialised once only

    if ( millis() - lastSwitchTest > 250 ) {  // every 250ms
      lastSwitchTest = millis() ;

      // switch 1

      bool stateSwitch_1 = digitalRead( switchPin1 ) ;
      if ( oldStateSwitch_1 != stateSwitch_1 ) {
         oldStateSwitch_1 = stateSwitch_1 ;
         Serial.println("Switch 1 changed");
         EspalexaDevice* d1 = espalexa.getDevice(0); //this will get "first device", the index is zero-based
         if ( stateSwitch_1 == HIGH )  {  // HIGH = off
            Serial.println("Switch 1 off");
            d1->setPercent(0); //set value "brightness" in percent
            digitalWrite(RelayPin1, HIGH);
         }
         else { // switch on
            Serial.println("Switch 1 on");
            d1->setPercent(100); //set value "brightness" in percent
            digitalWrite(RelayPin1, LOW);
         }
      }

      // switch 2 to 8
      // just copy/paste/adjust using switch 1 as a template

    } // if ( millis
} // loop()

All AceButton code should be deleted.

now again the same kind of thing is happening but this time the switches automatically go off and agfter some time they turn on if the board's blue light is on but sometimes that blue light goes off and the board is not able to connect to wifi now how do i resolve this

@RathoreBrothers   Spurious resetting of a micro controller together with WiFi connectivity problems are notoriously difficult to investigate. What happens when the system is running normally and (test a) you press the reset button on the esp32 and (test b) you switch off the WiFi router? Do you get similar symptoms to the ones you have described?

when i press reset the boards normally resets and i am able to access the lights and when i turn off the wifi then also i am able to access through switches but not over alexa but the thing is after a period of time the lights go off and on after some time

can you please reply

@RathoreBrothers If you press reset on the esp32, do the lights return to the state they were in before the reset?   Are the switches of the same type as illustrated in the project, that is they hold their position as either ON or OFF or are you using push buttons?
If the code you are using is not the same as in your original question, please  update the question with the new code. Have you looked through the comments in the project and video to see if other people have the same problem?

yes lights come back in their original state . no i am not using push buttons . the code is same as you suggested me previously and no i could  not find people with the problem may be no one has tried on this scale .

@RathoreBrothers if you paste in the full code into the question I can check that there are no basic errors in interpreting what I suggested, but I can't test it because I don't use Alexa. There are over 100 open issues with that espalexa library so opening an issue in its github repository may not bring a quick fix. Did the new code make the situation worse?

new code kind of made the situation worse as the lights turn off frequently but they again turn on automatically

can you please reply

@RathoreBrothers if you paste in the full code into the question I can check that there are no basic errors in interpreting what I suggested, but I can't test it because I don't use Alexa. Paste it in after your original code.

here you go i posted my renewed code


text:
LoRa to MQTT sensor data can't be read
I'm trying to transfer data from a temperature sensor that is located outside my WiFi area. I have chosen LoRa technology between an ESP32 equipped with an SX1278 and a TTGO Lilygo LoRa.
So far everything works fine, but as soon as I try to publish the data via Mosquitto MQTT in order to have access to the home assistant, things are get worse. I use MQTT Explorer to view the exchanges with Mosquitto. I also monitor the data on the serial port.
Everything works correctly as long as I don't publish the temperature data. But from the moment I publish it after changing it to string to switch to MQTT, I have some problems:

The serial port displays wrong values of the string  and scrolls continuously.
The data sent to MQTT are well displayed, coherent with the serial port, but remain incoherent and the number of publications increase quickly.
From a certain moment, things do not move anymore.

So I have at least two problems, and even though I looked at many examples, I have trouble understanding everything.
You will find attached the code loaded into the Lilygo receiver hoping that it will help solve my problem(s):
#include <SPI.h>
#include <LoRa.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <Streaming.h>
#include <Ticker.h>

#define OLED_SDA 21 // Attention: Les broches SDA et SCL de l'affichage OLED sont inversées sur le dessin de LilyGO et sur GitHub.
#define OLED_SCL 22
#define OLED_RST 12 // Note: Le TTGO Lora32 v2 n'utilise pas le signal reset, mais la librairie Adafruit_SSD1306, oui.
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

const int csPin = 18; // LoRa radio chip select-TTGO
const int resetPin = 23; // LoRa radio reset-TTGO
const int irqPin = 26; // change for your board; must be a hardware interrupt pin-TTGO
const int sckPin = 5; //-TTGO
const int misosPin = 19; //-TTGO
const int mosiPin = 27; //-TTGO
const char* ssid = "xxxxxx"; // Nom du wifi
const char* password = "xxxxxx"; // Mot de passe wifi

const char* mqtt_server = "xxx.xxx.x.xx"; // Adresse IP du brovker MQTT
const char* mqtt_username = "xxxxx"; // User MQTT
const char* mqtt_password = "xxxxxx"; // Password MQTT
const char* mqtt_topic = "ESP32/DS18B20/temp_piscine"; // Nom du topic MQTT envoyé par home assistant

char incoming ;
char msg[4];

WiFiClient espClient;
PubSubClient client(espClient);

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);

void setup() {
  Serial.begin(115200);
  while (!Serial);

  // setup WiFi
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  //initialize OLED
  Wire.begin(OLED_SDA, OLED_SCL);
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
  }
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("LORA RECEIVER ");
  display.display();

  Serial.println("LoRa Receiver");

  // override the default CS, reset, and IRQ pins (optional)
    SPI.begin(sckPin, misosPin, mosiPin, csPin);
    LoRa.setPins(csPin, resetPin, irqPin); // set CS, reset, IRQ pin

  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

//Fonction connexion au wifi appelé dans le setup
void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  display.setCursor(0,0);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

//Fonction connexion au wifi appelé dans le setup
void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;

  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();
}

//Fonction connexion au serveur Mqtt  dans le loop
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client", mqtt_username, mqtt_password)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void loop() {
  client.loop();
  // try to parse packet
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    // received a packet
    Serial.print("Received packet ");
    // read and print packet
    display.clearDisplay();
    display.setCursor(0,0);
    while (LoRa.available()) {
      incoming = ((char)LoRa.read());
      //Serial.print((char) LoRa.read());
      Serial.print(incoming);
      display.print(incoming);
    }
    // print RSSI of packet
    Serial.print("' with RSSI ");
    Serial.println(LoRa.packetRssi());
    //display.setCursor(0,0);
    display.print("' with RSSI ");
    display.println(LoRa.packetRssi());
    display.display();
  }
  if (!client.connected()) {
    reconnect();
  }
  dtostrf(incoming, 6, 2, msg);
  Serial.print (msg);
  client.publish(mqtt_topic,msg,false);
  //client.publish(mqtt_topic,dtostrf(LoRa.packetRssi(),6,2,msg),false);
}

Hi, I don't see anything obviously wrong - what are the reported RAM usage values when the program is built ? It could certainly by that you are experiencing some kind of stack overflow, or memory corruption.

Hello and thank you for your support. I finally found the problem, which was that using incoming needs to be stored in a buffer to be used as it was sent char by char. I also found the possibility to use LoRa.readString(), which allows a full string storage. I used after the function LoRaData.indexOf..., which allows to select specific parts of text with specific marks such as #, *, /, ...
Here is an example of the code used for those who could be interested.
void loop() {
  client.loop();
// try to parse packet
  int packetSize = LoRa.parsePacket();
  if (packetSize)
{
    // received a packet
    Serial.println("Received packet ");
    // read and print packet
    display.clearDisplay();
    display.setCursor(0,0);
    while (LoRa.available()) //>0 retiré
    {
      String LoRaData = LoRa.readString();
      Serial.print(LoRaData);
    // Get Text, temperature and end text : *Temp.piscine #21.56*C*
      int pos1 = LoRaData.indexOf('#');
      int pos2 = LoRaData.indexOf('*');
      Text = LoRaData.substring(0, pos1);
      temperature = LoRaData.substring(pos1 +1, pos2);
      End = LoRaData.substring(pos2+1, LoRaData.length());
    }
    // print RSSI of packet
    Serial.print("' with RSSI ");
    Serial.println(LoRa.packetRssi());
     display.print("temperature Piscine = ");
    display.print(temperature);
    display.print("°C");
    display.print("' with RSSI ");
    display.println(LoRa.packetRssi());
    display.display();
      }
}

I still need to work on it, but it seems to work fine.

In your dtostrf(incoming, 6, 2, msg);, you want to store a float that has a minimum width of 6, with 2-digit precision, you will need an array of at leat 9 bytes(plus NULL terminator) for a value like '12345.78', you only allow 4 bytes for your msg[4]; which is definitely insufficient.
Even if your temperature is 32.45, it will still need an array of 6 for msg.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Reading/writing Ntag215 with RC522
I ordered Ntag215 from Aliexpress. The tags are identified just fine, yet I have issues writing/reading to them because of failed authentication. I am using Arduino Uno + RFID-RC522 module.
This is my code below:
#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN 9  //
#define SS_PIN 10  //

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

void setup() {
  Serial.begin(9600);  // Initialize serial communications with the PC
  while (!Serial)
    ;                  // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  SPI.begin();         // Init SPI bus
  mfrc522.PCD_Init();  // Init MFRC522
  Serial.println(F("Scan PICC to see UID, type, and data blocks..."));
}

void loop() {
  // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
  if (!mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  // Select one of the cards
  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  Serial.print(F("Card UID:"));
  dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
  Serial.println();
  Serial.print(F("PICC type: "));
  MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
  Serial.println(mfrc522.PICC_GetTypeName(piccType));

  MFRC522::MIFARE_Key key = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
  MFRC522::StatusCode status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 1, &key, &(mfrc522.uid));
  Serial.println(mfrc522.GetStatusCodeName(status));
}

void dump_byte_array(byte *buffer, byte bufferSize) {
    for (byte i = 0; i < bufferSize; i++) {
        Serial.print(buffer[i] < 0x10 ? " 0" : " ");
        Serial.print(buffer[i], HEX);
    }
}

And this is the output I get.
01:27:26.704 -> Scan PICC to see UID, type, and data blocks...
01:27:30.357 -> Card UID: 04 CB 4A 57 19 61 80
01:27:30.390 -> PICC type: MIFARE Ultralight or Ultralight C
01:27:30.422 -> Timeout in communication.

Always get Timeout in communication. With Mifare 1KB tags this is not an issue. Any idea?

it times out after 32 ms ... maybe the timeout setting is too short

Ok after more trial and error and research I have made it possible to Write and Read to Ntag215. Here are code snippets for writing and reading. It was not required to Authenticate to write the data the tag.
Writing: It is actually quite simple. The main rule is that the writing can start from the page 4. And the bufferSize has to be 4. Here is example just writing "A" character to the tag.
    char charToProgram = "A";
    byte data = charToProgram;       // Data to write (ASCII character "A")
    byte blockAddr = 4;  // Block address to write to

    // Write the data to the tag
    MFRC522::StatusCode status = reader.MIFARE_Ultralight_Write(4, &data, 4);

    if (status == MFRC522::StatusCode::STATUS_OK) {
      Serial.println("SUCCESS! Wrote to card!");
      reader.PICC_HaltA();
    }

Reading:
    int blockAddr = 4;  // Block address to read from
    byte data[18];
    byte size = 18;
    // Write the data to the tag
    MFRC522::StatusCode status = reader.MIFARE_Read(blockAddr, data, &size);

    if (status == MFRC522::StatusCode::STATUS_OK) {
      Serial.print("Read character: ");
      Serial.println((char) data[0]);
      reader.PICC_HaltA();
    }

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
LIS3DH not working with arduino
I am new to LIS3DH and tried to interface it with Arduino Uno. I have made the circuit as follows-
LIS3DH    :    Arduino Uno
SCL       :    SCL (GPIO18)
SDA       :    SDA (GPIO19)
3.3v      :    3.3v
Gnd       :    Gnd
I used the example code from below link -
sparkfun LIS3DH hookup guide
Even though I tried to change the scl/sda pins to A4 and A5, I am not getting any results. All the time I am getting same values for all orientations.
Let me know if anyone can help me.
Thanks

Try https://playground.arduino.cc/Main/I2cScanner/ if it finds any address in the bus

Hi, just to update, deleting the header file "SPI.h" makes it work. I don't know why but it is working. Also, same thing happened in esp8266 nodemcu.


text:
Why can't I upload a sketch by connecting directly to the serial pins?
I have an handful of fake arduino nanos.  The work fine, but as an experiment, I tried to program them with a usb serial adapter (a real FTDI one).  It doesn't work, but also, strangely, it seems to stop the bootloader from working properly too, or just puts the arduino in a mode where the /dev/ttyUSB* device doesn't appear, and only reappears when I burn the bootloader again
When I try to upload the sketch using the usb serial adapter, I get this:
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00
Failed uploading: uploading error: exit status 1

Then, when I try to upload a sketch over usb again, /dev/ttyUSB* no longer appears when I plug in the usb cable to the normal usb jack.
However, when I can still put the sketch on using an in-circuit-programmer, and when I use the in-circuit-programmer to burn the bootloader again, /dev/ttyUSB* appears again, and I can upload sketches over usb again.
Is that possible?  What could I be doing wrong
Here is how I connected the usb to serial adapter to the fake arduino:

(checkout https://i.stack.imgur.com/nh3d6.jpg for a bigger picture)
So basically I have connected between the arduino (left column) and the usb to serial adapter right column:
TX - RX
RX - TX
VIN - VCC
GND - GND
RST - 0.1uF capacitor - DTR

I have tried it with and without the reset pin.
The usb to serial adapter is set to 5V.

another clue:
If I leave the adapter and arduino connected as in the picture, but plug the usb cable into the arduino instead of the adapter, so the adapter is powered by the arduino - it still gets the error that I have shown, and stops working completely until I reburn the bootloader.

Does anybody have any idea why this could be happening?

UPDATE:
After it was pointed out, I started using the 5v pin instead of the VCC pin on the fake arduino, but the same thing keeps happening:

burn the boot loader
normal usb upload works
try to upload with the serial adapter
doesn't work
normal usb upload no longer works until I burn the bootloader again

thanks.  I connected two adapters together to make sure they both worked, and sent messages both ways.  I should have mentioned at

Vin is for 7 to 12 V input. feed 5 V over the 5 V pin. the DTR may not work so try a manual reset while avrdude attempts to upload

You appear to have connected the 5v output of the FTDI adapter to the Vin pin of the Nano. You should instead use the 5v pin of the Nano to avoid the path through the internal voltage regulator. You are also aware that if you use the ICSP pins to download a sketch to the Nano, that overwrites the boot loader ?

Yes I have changed power to the 5v pin since @Juraj pointed it out, and gotten the same result.  Yeah, I burned the bootloader using the ICSP pins each time.  That's the only way I could fix normal upload.  Once I fix the bootloader, I can upload sketches until I try to upload with the serial adapter, and then the bootloader seems to stop working.

I have ordered a real arduino nano, so I'll try with that as soon as it gets here - to try to zero in on the issue

It turns out I had this problem https://askubuntu.com/questions/1403705/dev-ttyusb0-not-present-in-ubuntu-22-04. if anybody has a similar problem (a fake arduino that keeps disappearing) try sudo apt-get remove brltty before anything else. I'm not sure if that was the main problem, or just made it hard to figure out the main problem.

OK this was a combination of at least two things:

Main problem:
connecting the fake arduino's RST pin to the FTDI's DTR pin via a 0.1uF capacitor seems to stop it from uploading, when when you manually reset.  Also when I remove it it doesn't seem to fix itself right away if you can believe it.

Red Herring
This was not the direct cause of this issue, but is probably a big problem for a lot of other fake arduinos out there:
When I went back to the built-in USB, brltty's udev rules were claiming the CH341 as described here https://askubuntu.com/questions/1403705/dev-ttyusb0-not-present-in-ubuntu-22-04
So if you just have the simpler problem of a fake arduino not appearing, this might solve the problem for you:
sudo apt-get remove brltty

or if you need brltty you can just go into the udev rules that come with it and comment out this one:
# Device: 1A86:7523
# Baum [NLS eReader Zoomax (20 cells)]
ENV{PRODUCT}=="1a86/7523/*", ENV{BRLTTY_BRAILLE_DRIVER}="bm", GOTO="brltty_usb_run"

(as long as that isn't the screen reader you use - then you might just have to buy a real arduino, or make some better udev rules that recognise your screenreader from the port it's plugged into)
The reason this confused me is that when I tried to plug in to the standard usb port after failing to use the programmer, the above udev rules kicked me out.  But then I think when I burned a new bootloader, because you still have to power the board from usb while the pololu is connected, I managed to have it connected without the above udev rule kicking it - and then when I tried the external FTDI again, and then plugged back in the internal CH341, the brltty udev rule claimed it, and it seemed like trying to upload over FTDI is what broke it.

wouldn't you have the same problem uploading with the on-board FTDI? how is this related to the use of external FTDI on RX.TX pin?

yeah - that's a good point.  I haven't quite figured it out.  I think either this was the only problem, and I totally misinterpreted it - or there was another problem, but having this problem at the same time made it really hard to figure out.

I have updated the answer @Juraj.  The direct cause was trying to automatically reset - which you also suggested I stop, and the CH431 udev issue just distracted me from getting to the bottom of that, since I couldn't verify that the arduino was working at all.

It appears the boot loader does not support serial programming. You would need to change that first. Is the baud rate the same?

it works over USB and the USB chip connects to the same RX/TX as the header pins RX/TX


text:
Potential difference across the same wire
This issue may be weird, and I'm not sure if this is because of my wiring, but it would seem that I do not have the same voltage (or approximately the same voltage) between the VCC(3.3V) and the VCC power rail of my breadboard.
When measuring the voltage, there is ~0.300 mV difference. And indeed measuring VCC and GND gives me 2.9 V, instead of 3.3 V

I measured the flat jumper, it doesn't have any resistance (~~0)

The ESP is consuming below 100mA, so no voltage drop

Could anyone explain me that ?
See attached pictures

It's not "same" wire. There are at least contacts between board pin and bread board and bread board to wire... But if those rails are unloaded, it'll be quite unexpected to have any voltage drop

You are not measuring the wire. Try putting one probe on the actual wire where it goes into the breadboard, not the Arduino 3.3V point, and the other probe on the other end of that wire.

This question seem to belong in electrical engineering community rather than here.

The only reasonable explanation is that the path between the 3.3V pin and the wire you are measuring does indeed have non-zero resistance. The wires look dirty to me from the photo, plus there would be internal resistance in the breadboard connectors.
You are measuring from the 3.3V pin and not the other end of the wire. I suggest using a different wire, or cleaning that one with sandpaper or by filing it down until you see shiny copper. Also try a different pin on the breadboard.
This is really a hardware or measurement issue. There is no way that a wire with zero resistance from one end to the other is going to have a 0.242V drop across it.

I struggled a few days to get it work, but it would seem that I don't have any more voltage drop :) (or below 10mv), thank you for your answer !


text:
Arduino nano + 4x 7 segment display + 74HC595 - Only dot points are turn on
I am trying to run a thermometer with thermocouple sensor on Arduino Nano.
I have bought 4x 7 segment display and 74HC595 chip. Everything is connected like in the attached diagram below (without DS18B20) , but when I uploaded sketch to Nano - only dots are turn on .
Below You Can find my code
#include <OneWire.h>

const int latchPin = 8; // Pin connected to ST_CP of 74HC595
const int clockPin = 9; // Pin connected to SH_CP of 74HC595
const int dataPin = 10; // Pin connected to DS of 74HC595
const int digitPins[4] = {
    3, 4, 5, 6}; // pins to control the 4 common anode pins of display
// seven segment digit bits + blank + minus
const byte digit[12] = {
    B00111111, // 0
    B00000110, // 1
    B01011011, // 2
    B01001111, // 3
    B01100110, // 4
    B01101101, // 5
    B01111101, // 6
    B00000111, // 7
    B01111111, // 8
    B01101111, // 9
    B00000000, // Blank
    B01000000  //-
};

int digitBuffer[4] = {1};
int digitScan = 0;
int soft_scaler = 0;
float tempC, tempF;
int tmp;
boolean sign = false;

void setup()
{
    TCCR2A = 0;
    TCCR2B = (1 << CS21);
    TIMSK2 = (1 << TOIE2);
    TCNT2 = 0;

    for (int i = 0; i < 4; i++)
        pinMode(digitPins[i], OUTPUT);

    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
}

ISR(TIMER2_OVF_vect)
{
    soft_scaler++;
    if (soft_scaler == 15)
    {
        refreshDisplay();
        soft_scaler = 0;
    }
};

void refreshDisplay()
{
    for (byte k = 0; k < 4; k++)
        digitalWrite(digitPins[k], LOW);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
    digitalWrite(latchPin, HIGH);
    delayMicroseconds(50);
    digitalWrite(digitPins[digitScan], HIGH);
    digitalWrite(latchPin, LOW);

    if (digitScan == 1)
    {
        shiftOut(dataPin, clockPin, MSBFIRST,
                 ~(digit[digitBuffer[digitScan]] | B10000000));
    }
    else
    {
        shiftOut(dataPin, clockPin, MSBFIRST, ~digit[digitBuffer[digitScan]]);
    }

    digitalWrite(latchPin, HIGH);
    digitScan++;
    if (digitScan > 3)
        digitScan = 0;
}

void loop()
{

    tempC = 90.8;
    tmp = int(tempC * 10);
    if (tempC < 0)
    {
        sign = true;
        tmp = abs(tmp);
    }
    else
    {
        sign = false;
    }

    if (int(tmp) / 1000 == 0)
    {
        digitBuffer[3] = 10;
        if (sign)
        {
            digitBuffer[3] = 11;
        }
    }
    else
    {
        digitBuffer[3] = int(tmp) / 1000;
    }

    if (int(tmp) / 1000 == 0 && (int(tmp) % 1000) / 100 == 0)
    {
        digitBuffer[2] = 10;
        if (sign)
        {
            digitBuffer[2] = 11;
            digitBuffer[3] = 10;
        }
    }
    else
    {
        digitBuffer[2] = (int(tmp) % 1000) / 100;
    }

    digitBuffer[1] = (int(tmp) % 100) / 10;
    digitBuffer[0] = (int(tmp) % 100) % 10;

    delay(500);
}

I didn't connect thermocouple yet, but I use constant "tempC" with value = 90.8, to check if it works. If I change the value to higher - dots on displays are more dimmed.

please indent your code properly ... right now, it is difficult to read

That is a big display. That only the dots turns on is an indication that the voltage could be too low. The dots probably have less series diodes than the segments. Green display diodes also have a relatively high forward voltage. There may be other problems too. Post a link to the data sheet or vendor site for that display.
Also this indicates a software problem because the schematic implies a common cathode type display: //pins to control the 4 common anode pins of display Remember also the absolute max 40mA limit for Arduino pins especially relevant for d3 to d6 here

Your digit pins can probably not source enough current for the display segments to light. You need a PNP transistor with a proper base resistor on each digit pin to drive the displays using an active low (inverted) signal. This would have been easier if your display was of the Common Cathode type. The fact that the dots are the only thing to light might also indicate there's something wrong with your code.

Thank You for response! You may be right, that transistors will be necessary. Below You can find vendor site of this display
https://sklep.avt.pl/wyswietlacz-led-2-30-57mm-zielony-wa.html You can find in the descrpition - this is common anode display.

The vendor description is not very good, however it is clear that 5 volts is not enough for these displays implying that you have to redesign the circuit to include a higher voltage power source. It does appear from the description, however, to be a common anode device. The screen shot from the data sheet shows each segment has 4 diodes in series and the DP has 2 diodes in series. That the DP lights with 5 volts indicates that the segments will light with 10 volts (possibly a bit less). Because it is common anode type you could use a TPIC6B595 shift register to replace the 74HC595. You need also 4 high side switches (each 1xPNP + 1xNPN transistor) for the 4 anodes. For this, you could also use a high side driver chip, say a MIC2981. Since the segment diode voltage drop is not shown, but should be in the range 2.1 to 4 volts, you really need to do a test to discover the optimum value of the segment current limiting resistors to give the 10mA talked about in the description, at the voltage you decide to drive the display at. The DP really requires a correspondingly higher value current limiting resistor.

Thank You for Your support!
Does changing 74HC595 to TPIC6B595 is requiring changing code or circuit?
And to be sure - on the output of D3-D6 I need to place MIC2981?

The wiring to the TPIC6B595 is different to that of the 74HC595. You'd best search for a tutorial Arduino TPIC6B595. Also, the data you send is inverted because sending a "1" switches on a segment by pulling it LOW. On the 74HC595, sending a "1" would have switched the segment off by pulling it HIGH. It would be easiest to invert the table, for example "8" is currently B01111111, //8. You'd change this to B10000000, //8 . The MIC2981 is an 8 channel source driver. You'd connect Arduino pins D3 to D6 to  MIC2981 pins 1 to 4. The MIC2981 outputs 18 to 15 would go to the display common anodes.

Looking at your code, it is difficult to see how all four dots could be displayed simultaneously as in your picture. Only the dot on the second digit should be displayed. However, the pinout of the display on the schematic differs from that on the vendor document. The anode is connected to pins 3 & 8 on the schematic and 1 & 5 in the vendor document. This implies also that you have wired the display incorrectly.
The code change for the TPIC6B595 should be even easier than I said earlier. Simply remove the inverting tildas '~' in the two shiftOut() statements.


text:
Nano 33 BLE Sense powered with Vin and USB at the same time
I have a project where I would like to power an Arduino Nano 33 BLE Sense
with USB and Vin at the same time.
The idea is to charge an external LiPo 3.7V through a charger module
that would take the load from the 3.3V pin (that would be powered through USB)
and at the same time keep powering the Arduino through Vin
because I want to avoid a power interruption when I unplugged the USB cable
that would interrupt the writing operation (on a text file on an SD card).
So the goal is to prevent data corruption on a writing operation on a text file.
I know text files are supposed to be less corruptible (compared to a database)
but I want to be sure the operation would be uninterrupted.
I've seen this post:
What happens if I power the Arduino with both the USB and external power voltage simultaneously?
But it's related to the Arduino UNO R3.
It basically says:
When Vin >6.6V the opamp turns the mosfet off.

so the USB disconnects.

When Vin <6.6V the opamp turns the mosfet on.

so the USB stays connected.

On Arduino's website:
https://store-usa.arduino.cc/products/arduino-nano-33-ble-sense
it says:

Vin: This pin can be used to power the board with a DC voltage source.
If the power is fed through this pin, the USB power source is disconnected.

It does not mention from what voltage it would disconnect the USB power.
I did not find the same schematic for the Arduino Nano 33 BLE Sense.
Just this:https://docs.arduino.cc/hardware/nano-33-ble-sense

Interactive Viewer
Interact with the schematics, the PCB and a 3D model of the product.

and this: https://docs.arduino.cc/static/353d3c445c28b1da1fe1f9d6eafa948d/ABX00031-schematics.pdf
I'm not very familiar with reading schematics but I could not find similar information about vin and USBVCC.
That'd be great if somebody had some insight on that.
I would welcome any suggestion.
Cheers!

If I connect a battery charger/controller on VIN, my battery would be protected.
And I could connect a booster 5V and add a shottky diode so its connection to VIN would be closed if booster+ < VIN
Like this ?

In this power block you can see there is only one Schottky diode with the voltage drop under 0.5V@2A. That means D2 is closed around the condition: VUSB < VIN.
On the other side if you add 3.6-4.2V battery on VIN there will be current flowing from VUSB to battery.
Basically you need another shottky diode Bat+ -> [A|K] -> VIN  so when there is bigger voltage on the VIN it'll "shut off" the battery (otherwise it'll be charged by almost 5V)
Depending on the application and sensors you are planning to use, you might want to consider for example Seeed Studio XIAO nRF52840 Sense that has battery charging circuit and pads for the battery on the bottom (although it's not the "bread board" pins)

That's awesome!
Thanks for the details.
I thought I had to charge the battery through the 3.3V.
But what you are showing is that VUSB feeds VIN.
So if I connect a battery charger/controller on VIN,
my battery would be protected.
And I could connect a booster 5V
and add a shottky diode so its connection to VIN would be closed
if booster+ < VIN
I even like the option with Seeed Studio XIAO nRF52840 Sense better.
It's smaller than the Arduino 33 BLE Sense
and it's got a USB-C connector.

Do you even need booster? If you don't need 5V, you can use VIN for charging only and 3V3 output from accu. Definitely not step up connected to charging input

I need a booster because the minimum operating input voltage on VIN is 4.5V (on the Arduino 33 BLE). And I want to use a small 3.7v LiPo battery.


text:
Motion-activated lights
I am attempting to follow this tutorial to light up a dark staircase with motion-activated LED strips. If my understanding of the tutorial is correct, essentially the Arduino's job is to power or depower transistors at the appropriate time to prohibit/allow enough voltage over the LED strips on the stairs.
I have assembled a few light strips and soldered the microcontroller to the PCB with the appropriate components and was ready to test the device. The author of the guide helpfully created this video demonstrating the expected behavior of the device on start-up: the lights should blink as shown and then turn off, awaiting activation from a motion sensor. However when I try to replicate this my lights simply turn on and never turn off, fade, or blink.
Consulting the FAQ on the guide, I tried reorienting my transistors, thinking I perhaps had them backward. This had no effect.
I then tried to verify that my microprocessor was working and programmed correctly. I modified the code in the setup section, adding the following commands:
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
for(int i=0; i<10; i++){
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    delay(2000);
}

The intention was to make the built-in LED on the board blink on and off a few times during startup. While the board was connected to the computer, it indeed blinked on and off after I hit upload. When it's attached to the power supply from the PCB it does not blink (though the LED lights for the stairs turn on as I have described).
It seems to me that the microprocessor is simply not getting power or is not connected properly to the PCB. However I have done my best to verify all the connections and cannot find any problem. This is my first project of this type and am not sure what else to try. Any guidance with troubleshooting would be very much appreciated.
I apologize for the long post but I wanted to be sure to include all the necessary information. Thank you for reading!
Below are images of the PCB and schematics from the guide, which hopefully correspond to how I've actually connected the components.

Here is the code from the guide plus my blinking loop. The original is available at the author's github.
##Shift_Stairs.ino

#include <math.h>
#include <SPI.h>
//#include <MemoryFree.h>
//#include "expoDutyCycles.h"

//Data pin is MOSI (atmega168/328: pin 11. Mega: 51)
//Clock pin is SCK (atmega168/328: pin 13. Mega: 52)
const int ShiftPWM_latchPin=10;
const bool ShiftPWM_invertOutputs = 0; // if invertOutputs is 1, outputs will be active low. Usefull for common anode RGB led's.

#include <ShiftPWM.h>   // include ShiftPWM.h after setting the pins!

const int SWITCH_PIN = A0;
const int PHOTORESISTOR_PIN = A2;
const int MOTION_SENSOR_TOP_PIN = 2;
const int MOTION_SENSOR_BOTTOM_PIN = 3;

const unsigned char maxBrightness = 255;
const unsigned char pwmFrequency = 75;
const int numRegisters = 2;
const int NUMLEDs = 9;
const int MOTION_SENSOR_WARMUP_TIME = 10;
const int ON_TIME = 10000; /* The duration between turn on and turn off. */
const int LIGHT_THRESHOLD = 300; /* Anything below this sensor value will enable lights */

/* These are used to detect rising edges in the absence of interrupts.
   Using interrupts with ShiftPWM crashes the program. */
unsigned char lastReadTopPin = LOW;
unsigned char lastReadBotPin = LOW;

volatile unsigned char topActivated = false;
volatile unsigned char bottomActivated = false;
unsigned long lastMotionTime = 0;

const char BOTTOM_TO_TOP = 1;
const char TOP_TO_BOTTOM = 2;
/* For sake of the animation, stores the direction of propegation.
   Set when animation is active, cleared when animation is done.  */
char directionTriggered = 0;

const unsigned long BRIGHTNESS_SM_PERIOD = 2000; /* in μs */
unsigned long lastBrightnessSM = 0;

/* LED 0 is on the top of stairs */
unsigned char brightnesses[NUMLEDs] = {0};

void setup()   {
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH);
    for(int i=0; i<10; i++){
      digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
      delay(2000);
    }
    pinMode(ShiftPWM_latchPin, OUTPUT);
    SPI.setBitOrder(LSBFIRST);
    // SPI_CLOCK_DIV2 is only a tiny bit faster in sending out the last byte.
    // SPI transfer and calculations overlap for the other bytes.
    SPI.setClockDivider(SPI_CLOCK_DIV4);
    SPI.begin();

    Serial.begin(9600);

    /* Turn on pullup resistor for switch */
    digitalWrite(SWITCH_PIN, HIGH);

    ShiftPWM.SetAmountOfRegisters(numRegisters);
    ShiftPWM.Start(pwmFrequency,maxBrightness);
    // Print information about the interrupt frequency, duration and load on your program
    ShiftPWM.SetAll(0);
    ShiftPWM.PrintInterruptLoad();
    // Fade in all outputs
    for(int j=0;j<maxBrightness;j++){
        ShiftPWM.SetAll(j);
        delay(3);
    }
    // Fade out all outputs
    for(int j=maxBrightness;j>=0;j--){
        ShiftPWM.SetAll(j);
        delay(3);
    }
}
void loop()
{
    /* Detect rising edge with polling. Interrupts crash the program. */
    unsigned char pinRead = digitalRead(MOTION_SENSOR_TOP_PIN);
    if(pinRead == HIGH && lastReadTopPin == LOW){
        topActivated = true;
    }
    lastReadTopPin = pinRead;
    /* Detect rising edge with polling. Interrupts crash the program. */
    pinRead = digitalRead(MOTION_SENSOR_BOTTOM_PIN);
    if(pinRead == HIGH && lastReadBotPin == LOW){
        bottomActivated = true;
    }
    lastReadBotPin = pinRead;

    /* Resets flags */
    if(topActivated){
        if(directionTriggered == 0){
            directionTriggered = TOP_TO_BOTTOM;
        }
        lastMotionTime = millis();
        topActivated = false;
    }
    if(bottomActivated){
        if(directionTriggered == 0){
            directionTriggered = BOTTOM_TO_TOP;
        }
        lastMotionTime = millis();
        bottomActivated = false;
    }

    /* State machine */
    if(micros() - lastBrightnessSM > BRIGHTNESS_SM_PERIOD){
        brightnessSM();
        lastBrightnessSM = micros();
    }
}
/**
    Returns true if switch is in "1" position.
*/
boolean switchPressed(){
    return !digitalRead(SWITCH_PIN);
}

###brightnessSM.ino
enum brightnessStates {
    sFullyOn,
    sOff,
    sTurningOn,
    sTurningOff,
    sOverrideSwitch
};

int brightnessState = sOff;

void brightnessSM(){
    /* Actions */
    switch(brightnessState){
    case sFullyOn:
        break;
    case sOff:
        break;
    case sTurningOn:{
        /* Increase brightness of lights. This for loop goes from -NUMLEDs to 0 or
           0 to NUMLEDs depending on the direction of propegration. */
        char startLight = -1 * (directionTriggered - 1) * (NUMLEDs - 1);
        char endLight   = -1 * (directionTriggered - 2) * (NUMLEDs - 1);
        for(char l = startLight; l <= endLight; l++){

            /* Turn on the next LED only if the ones before it
               are on*/
            if(brightnesses[abs(l)] != maxBrightness){
                brightnesses[abs(l)] += 5;
                ShiftPWM.SetOne(abs(l), brightnesses[abs(l)]);
                break;
            }

            /* Turn on the next LED only if the one before it is partially on */
//            if(brightnesses[abs(l)] != maxBrightness){
//                if(l == startLight || (brightnesses[abs(l - 1)] > maxBrightness*3/10)){
//                    brightnesses[abs(l)] += 1;
//                    ShiftPWM.SetOne(abs(l), expoDutyCycles[brightnesses[abs(l)]]);
//                }
//            }
        }
        break;
    }
    case sTurningOff:{
        /* Decrease brightness of lights. This for loop goes from -NUMLEDs to 0 or
           0 to NUMLEDs depending on the direction of propegration. */
        char startLight = -1 * (directionTriggered - 1) * (NUMLEDs - 1);
        char endLight   = -1 * (directionTriggered - 2) * (NUMLEDs - 1);
        for(char l = startLight; l <= endLight; l++){
            /* Turn on the next LED only if the ones before it
               are on*/
            if(brightnesses[abs(l)] != 0){
                brightnesses[abs(l)] -= 5;
                ShiftPWM.SetOne(abs(l), brightnesses[abs(l)]);
                break;
            }

            /* Turn on the next LED only if the one before it is partially on */
//            if(brightnesses[abs(l)] != 0){
//                if(l == startLight || (brightnesses[abs(l - 1)] < maxBrightness*9/10)){
//                    brightnesses[abs(l)] -= 1;
//                    ShiftPWM.SetOne(abs(l), expoDutyCycles[brightnesses[abs(l)]]);
//                }
//            }
        }
        break;
    }
    case sOverrideSwitch:
        break;
    }

    /* Transitions */
    switch(brightnessState){
    case sFullyOn:
        if(millis() - lastMotionTime > ON_TIME){
            brightnessState = sTurningOff;
        }
        if(switchPressed()){
            transitionToOverrideSwitch();
        }
        break;
    case sOff:
        if(directionTriggered != 0){
            if(analogRead(PHOTORESISTOR_PIN) < LIGHT_THRESHOLD){
                brightnessState = sTurningOn;
            }
            else {
                directionTriggered = 0;
            }
        }
        if(switchPressed()){
            transitionToOverrideSwitch();
        }
        break;
    case sTurningOn:{
        /* If all the lights are on then proceed */
        unsigned char allOn = true;
        for(unsigned char l = 0; l < NUMLEDs; l++){
            if(brightnesses[l] != maxBrightness){
                allOn = false;
                break;
            }
        }
        if(allOn){
            brightnessState = sFullyOn;
        }
        if(switchPressed()){
            transitionToOverrideSwitch();
        }
        break;
    }
    case sTurningOff:{
        /* If all the lights are off then proceed */
        unsigned char allOff = true;
        for(unsigned char l = 0; l < NUMLEDs; l++){
            if(brightnesses[l] != 0){
                allOff = false;
                break;
            }
        }
        if(allOff){
            directionTriggered = 0;
            brightnessState = sOff;
        }
        if(switchPressed()){
            transitionToOverrideSwitch();
        }
        break;
    }
    case sOverrideSwitch:
        if(switchPressed() == false){
            /* Switch all LEDs off */
            for(char l = 0; l < NUMLEDs; l++){
                ShiftPWM.SetOne(l, 0);
                brightnesses[l] = 0;
            }
            directionTriggered = 0;
            brightnessState = sOff;
        }
        break;
    }
}
void transitionToOverrideSwitch(){
    brightnessState = sOverrideSwitch;
    /* Switch all LEDs on */
    for(unsigned char l = 0; l < NUMLEDs; l++){
        ShiftPWM.SetOne(l, maxBrightness);
        brightnesses[l] = maxBrightness;
    }
}

Check the orientation of the Arduino. Is it upside-down? Check also the voltage between the pins labeled GND and VCC.

Thanks for the response. I am reading 12V across the pins which seems good. I'm fairly sure the orientation is correct but I'll double check.

Consulting the schematics it looks like the (knockoff) version of the board I used has the FTDI header oriented the other way around, but the rest of the pins match. I have some spares so I could try it flipped if nothing else works.

Thanks, images added, code will follow. I'd be happy to add anything else you think will be helpful.

Where exactly have you measured 12V? Have you measured between Vcc and ground of the Arduino? 12V would be bad.

what happens if you run a minimal sketch , such as blink builtin LED?

the circuit has no reset ... the outputs are always enabled ... that means that the output may be in any state at power-on ... maybe start with simple sketch to bit-bang the input signals ... set pins 10, 11, 13 LOW, toggle pin 13 LOW-HIGH-LOW sixteen times to shift in all zeros, toggle pin 10 LOW-HIGH-LOW to transfer shifted data to outputs ... delay one second ... set pin 11 HIGH and repeat the pin 13 and pin 10 actions ... that should turn off all of the LEDs and then turn them back on ... pin 11 is data, pin 13 is the serial shift-in clock, pin 10 is the output latch clock

I can get the built-in LED to blink when I have the Arduino hooked up to my computer and I upload the sketch. Nothing happens on the Arduino when I plug in the power supply on the PCB. The code has been verified by other users who have successfully followed the guide so I'd be very surprised if that was the source of the issue. When I have a chance I will try your idea.

your circuit is similar to https://wokwi.com/projects/301213976182653448

Your soldering is really grizzly looking. Not enough heat, no flux, not heating the work before feeding solder... something. Before worrying about much else I would figure out what's up with that, because until then it may just drive you anyone that tries to help you nuts.

The image of the Printed Circuit Board (PCB) posted in the above question contains many examples of what are commonly referred to as Cold Solder Joints.  These types of joints are unreliable and occasionally provide no electrical connectivity. And are often impossible to visually verify.  The first 2 minutes of this video demonstrate how heat and flux can be combined to remedy cold solder joints involving a PCB and feed-through pin.
(I can edit/change the following as we narrow in on the solution for this problem. The objective is to make a good stackexchange question & answer.)
Symptom:

The project behaves as expected when cabled to the PC.  This assumes the cable to the PC (likely to a USB/CDC to Serial Port) contains Ground, In, Out and Power. The expected behavior is to turn the LEDs on and off.
The project does not work when disconnected from the PC and is powered by an external power supply.  The LEDs only turn on.

Consider verifying power to the processor or, better, at the processor.  For the problem as described in the question, there may be an interruption of the power path from the external power supply to the processor.  Check all the solder joints involved in connecting the Arduino's power input to the PCB. Likely the processor (Arduino) was powered up during programming through the Ground and Power pins of the serial port cable.  Once that cable was removed, the processor may not be powered and may have not been running while the PCB was only powered from an external source.


text:
Powering up a 16x2 LCD display with only a 9V battery
I'm using an Arduino (Nano 33 IoT) board for a project and apparently this board can only supply with 3.3 volts when a 9V battery is connected to it through Vin and GND pins. In other words, I'm powering the Arduino board with a 9V battery, but I want to power supply an LCD display through my Arduino, but I can't.
This Arduino board only has a 3.3 volts pin. It has a 5V pin but it's only enabled when the Arduino is powered by USB.
The problem: The LCD display only takes up to 5.5V, and its minimum required voltage is 4.5V. I cannot power it from the Arduino board because voltage is too low, and I cannot power it directly from the 9V battery because it's too high.
What can be done?
Note: I don't have a voltage regulator to use between the LCD and battery.
Is it possible to use voltage divider?
Note: The LCD screen that I'm using is connected to I2C protocol module. It has only 4 pins: SCL and SDA pins (connected to arduino), and 2 power pins (GND and VCC).
it should look like this when connected to a regular arduino uno:

What would the circuit look like if I desire to use voltage divider?
Or can I simply use just one resistor between the 9V battery positive pin and the LCD's positive power pin?

You can't use resistor, you need a regulator to bring the 9v down to 5V. BTW, how long do you expecting your 9V battery to last for? With WiFi (Nano 33 IoT has Wifi chip that could take up to 150mA during transmission), plus display, it won't last long.

To add to the list of problems that @hcheung started, you should consider if the LCD you have chosen is able to reliably operate while receiving what is likely a 0 to 3.3 volt data signal.  Some might, others may not. I2C is an open drain bus, but is it pulled up to 3.3 volts on the processor board?  Or is it pulled up to 5 volts on the LCD board? In the latter case, you need to instead ask if the processor is 5 volt tolerant.

... follow up: I could put the above into an answer w/more details if you like.  But, if this were my project, I'd go out and buy an I2C LCD that is designed to work at 3.3 volts.  Otherwise some of the things you would need to do: Buy a 9 to 5 volt regulator, understand how an I2C bus works which might lead to removing SMD parts on the Nano 33 IoT PCB and / or might lead to adding parts to the LCD PCB.

your picture shows a UNO, that would work. Posting the correct frizzy picture would help. Best is to post an annotated schematic.

If it's important to you to have backlighting, you should probably say. Because that will have an impact on any answer you get.

Yeah, battery won't last long. I think if I turn off backlight it would make it last slightly longer.
@st2000 I think that would be a good solution instead of buying a regulator. But most LCDs need 5V to work. If I find one with I2C bus which operates at 3.3, it would be the best solution.

Although it is effectively a 3.3 volt device, the nano 33 iot does have a 5v pin. Ideally, you would use an I2C compatible level shifter between the nano 33 iot and the LCD screen.


text:
How to save the current SPI settings with out have a global variable keeping track?
I am making a function for one of my devices, my device needs a particular SPI setting. I was hoping to save the current setting of the SPI class into some variable, load in the required setting, do a transfer, and after that load back the old setting.
I know there is an object for the SPISettings, but i dont know how to pull the current settings without me having to create a global variable that keeps track of it.
void sendSPI(){
 SPISettings oldSettings = ??? ;   //save old SPI Settings
 SPISettings mySettings(14000000, MSBFIRST, SPI_MODE0);

 digitalWrite(CSPIN,LOW);
 SPI.beginTransaction(mySettings); //load in new SPI Settings
 SPI.transfer(0x0);
 digitalWrite(CSPIN,HIGH);

 SPI.beginTransaction(mySettings); //Revert to old SPI Settings
}

What about trying static?

@st2000 the problem is i do not know the function for access the current settings

every library which uses SPI should start the transaction with the setting for the specific device. so you don't have to restore the settings. what are your other devices?

I'm going to assume you know what you want (but this may be a case where there are better ways to do what you want in C++ when considering the problem from a higher level perspective). In your class, write a method that will return ("expose") the desired variables.  Then, each time you instantiate your class, call those functions to return the desired values.

"every library which uses SPI should start the transaction with the setting for the specific device. ... "  I've had cases @Juraj where the I2C device was "unconventional" and had to use unusual settings.  But have to admit, I've never tried mixing these w/more conventional I2C devices on the same bus.

@st2000 "Once you have your SPI parameters, use SPI.beginTransaction() to begin using the SPI port." from https://docs.arduino.cc/learn/communication/spi?#serial-peripheral-interface-spi

https://github.com/arduino/ArduinoCore-avr/blob/master/libraries/SPI/src/SPI.h#L203 you can make a backup for SPSR and SPCR (but it kinda expects you are using clasic AVR Arduino)

@Juraj im using adafruit libraries, and they have their own spi/i2c classes kind of a rats nest, im just making sure i wont inadvertently bug out their libraries. It also assures that my function is compatible with libraries not following conventions

How to save the current SPI settings with out have a global variable keeping track? is a somewhat misleading question because you said  i do not know the function for access the current settings ... when you figure out how to read the current settings, then save them in EEPROM

the adafruit libraries have software (bit-banging) SPI as an option, but you don't use software SPI pins for multiple devices. If you use hardware SPI they relay on the SPI library and use beginTransaction


text:
best practice for performance: empty loop() when using interrupt?
I'm working on a little midi hardware project and I'm using attachInterrupt() to assign a callback function to an interrupt pin.
Nothing gets done in the loop function, so it looks like this:
void loop() { return; }

So far this seems to work out, but I'm wondering if this is a bad practice? I tried adding a short delay() call in there instead but I couldn't really measure if it performed better or worse.

no need for return  ... there is nothing to return to

loop() returns to main() (from where it was called, inside an infinite loop) after every iteration, whether or not you write a return; statement. The only case of such a function not returning one that contains an infinite loop to prevent it.

If you are using just one ISR to check a pin, this boils down to the question, which alternative has more overhead: a loop polling the pin, or the interrupt service entry and exit. You need to measure or look into the assembly code.

There is no particular reason to worry about doing nothing in loop - the processor has to be doing something -  you don't need to give it extra work.
Plus, there is an implied return at the end of functions, you don't need to add your own.
The bigger issue is that interrupt handlers should be short, so that you don't miss another interrupt while you are doing something lengthy in the first interrupt.

I think I can answer my own question.
I realized that I can keep my state change and debouncing logic in the interrupt routine and move everything else to the loop function, which seems cleaner.
edit: well not necessarily cleaner. I agree with @jsotola, ISR should only do the bare minimum.
In the end I figured not even using an ISR in the first place was even better for my use case.

putting too much code into an ISR is just asking for trouble ... especially the debounce code, it hangs the program for too long if it is inside a non-looping code block ... put the debounce code inside loop() so that the interval between keybounces can be measured without pausing the program

Debounce code in an ISR  can be OK if works by rejecting events (say button presses) which occur within say 50ms of the last accepted event because this can be coded without blocking. But, yes, in principle, an ISR should be very lightweight and quick to execute.


text:
Troubleshooting UART communication between nano 33 ble sense r2 and Adafruit Feather 32u4 with LoRa Radio Module
I've tried connecting the gnd's for both the boards and have connected rx to tx and vice versa in both the boards. I've powered both by batteries, and I'm trying to get sensor data from the nano, and trying to send it to the feather via UART, and long distance away using the Lora capabilities of the Feather.
I've loaded this program in the nano:
/*
Including libraries
*/
//Accelerometer{
#include "Arduino_BMI270_BMM150.h"
//Accelerometer}
//Temperature and humidity{
#include <Arduino_HS300x.h>
//Temperature and humidity}
//Pressure{
  #include <Arduino_LPS22HB.h>
//Pressure}

/*
Creating variables for sensors
*/
//Acceleration variables{
float x, y, z;
//Acceleration variables}
//Temperature and humidity variables{
float temperature;
float humidity;
//Temperature and humidity variables}
//Pressure variables{
float pressure;
//Pressure variables}

void setup() {

/*
Setting up sensors
*/
Serial1.begin(9600);
//Accelerometer{
  if (!IMU.begin()) {
    Serial1.println("Failed to initialize IMU!");
    int i = 0;
    Serial1.println("Trying again\n");
    while (!IMU.begin()){
      if(i>0){
        Serial1.print(" Failed\n");
      }
      Serial1.print("Try number ");
      Serial1.print(i);
      i++;
      delay(1000);
    }
    Serial1.print("Passed\nOn attempt number ");
    Serial1.print(i);
    Serial1.print("\n");
  }
//Accelerometer}
//Temperature and humidity{
if (!HS300x.begin()) {
  Serial1.println("Failed to initialize humidity temperature sensor!");
  int i = 0;
    Serial1.println("Trying again\n");
    while (!HS300x.begin()){
      if(i>0){
        Serial1.print(" Failed\n");
      }
      Serial1.print("Try number ");
      Serial1.print(i);
      i++;
      delay(1000);
    }
    Serial1.print("Passed\nOn attempt number ");
    Serial1.print(i);
    Serial1.print("\n");
}
//Temperature and humidity}
//Pressure{
if (!BARO.begin()) {
  Serial1.println("Failed to initialize pressure sensor!");
    int i = 0;
    Serial1.println("Trying again\n");
    while (!BARO.begin()){
      if(i>0){
        Serial1.print(" Failed\n");
      }
      Serial1.print("Try number ");
      Serial1.print(i);
      i++;
      delay(1000);
    }
    Serial1.print("Passed\nOn attempt number ");
    Serial1.print(i);
    Serial1.print("\n");
}
//Pressure}
}

void loop() {
  /*
  Read sensor data into the variables
  */
  //Read acceleration{
  if (IMU.accelerationAvailable()) {
    IMU.readAcceleration(x, y, z);
  }
  //Read acceleration}
  //Read temperature and humidity{
  temperature = HS300x.readTemperature();
  humidity = HS300x.readHumidity();
  //Read temperature and humidity}
  //Read pressure{
  pressure = BARO.readPressure();
  //Read pressure}

  /*
  Print the sensor data to Serial1 (hopefully implement sending this data to the lora feather, which will radio it to a distant arduino)
  */
  Serial1.print("\nAcceleration (x, y, z): ");
  Serial1.print(x);
  Serial1.print(", ");
  Serial1.print(y);
  Serial1.print(", ");
  Serial1.print(z);
  Serial1.print("\nTemperature: ");
  Serial1.print(humidity);
  Serial1.print("\nHumidity: ");
  Serial1.print(humidity);
  Serial1.print("\nPressure: ");
  Serial1.print(pressure);
  delay(1000);

}

I've loaded this program in the transmitting feather:
/* The program for the feather1 to take information from nano 33 ble sense rev2 and radio it to  where the feather2
** will communicate to the ground station's program todisplay the data in a user friendly manner, and will display results
*/
#include <RH_RF95.h>

// LoRa settings
#define RFM95_CS 8
#define RFM95_RST 4
#define RFM95_INT 7
#define RFM95_FREQ 915.0

RH_RF95 rf95(RFM95_CS, RFM95_INT);

void setup() {
  Serial.begin(9600);
  pinMode(RFM95_RST, OUTPUT);
  digitalWrite(RFM95_RST, HIGH);
  delay(100);
  digitalWrite(RFM95_RST, LOW);
  delay(10);
  digitalWrite(RFM95_RST, HIGH);
  delay(10);
  if (!rf95.init()) {
    Serial.println("LoRa init failed. Check your connections.");
    while (1) ;
  }
  rf95.setFrequency(RFM95_FREQ);
  rf95.setTxPower(23, false);
  Serial.println("LoRa Transmitter Ready!");
}

void loop() {
  static uint16_t messageCount = 0;
  String input;
  while (Serial.available() > 0) {
    char c = Serial.read();
    input += c;
  }
  if (input.length() > 0) {
    uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
    input.getBytes(buf, input.length() + 1);
    rf95.send(buf, input.length() + 1);
    rf95.waitPacketSent();
    Serial.println("Sent message #" + String(messageCount) + ": " + input);
    messageCount++;
  }
  delay(1000);
}

I've got this program in the receiving feather:
/* The program for the feather2 to recieve information from feather1 ** and will communicate to the ground station's program todisplay the data in a user friendly manner, and will display results
*/

#include <RH_RF95.h>

// LoRa settings
#define RFM95_CS 8
#define RFM95_RST 4
#define RFM95_INT 7
#define RFM95_FREQ 915.0

RH_RF95 rf95(RFM95_CS, RFM95_INT);

void setup() {
  Serial.begin(9600);
  while (!Serial) ; // Wait for serial port to be available
  /* The infinite while loop above not needed if you're not using rx/tx for sending
  ** the recieved radio data to your program or are using some other method to
  */
  pinMode(RFM95_RST, OUTPUT);
  digitalWrite(RFM95_RST, HIGH);
  delay(100);
  digitalWrite(RFM95_RST, LOW);
  delay(10);
  digitalWrite(RFM95_RST, HIGH);
  delay(10);
  if (!rf95.init()) {
    Serial.println("LoRa init failed. Check your connections.");
    while (1) ;
  }
  rf95.setFrequency(RFM95_FREQ);
  rf95.setTxPower(23, false);
  Serial.println("LoRa Receiver Ready!");
}

void loop() {
  if (rf95.available()) {
    uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
    uint8_t len = sizeof(buf);
    if (rf95.recv(buf, &len)) {
      Serial.print("Received: ");
      Serial.println((char*)buf);
    } else {
      Serial.println("LoRa receive failed");
    }
  }
}

I have been able to establish UART communication between two Unos before, but I'm unable to find out why it isn't working in this case. I can confirm it isn't working because the Serial monitor for the recieving feather (feather2) only shows this:
17:52:39.840 -> LoRa Receiver Ready!

Why this is happening, and any potential fixes for this?

As I see 32U4 I'd expect the Serial is used for native USB serial (CDC). If you want to use usart on pins 0 and 1, you'd have to use Serial1 instead.
Nano 33 BLE is the same, it has native USB and you are correctly using Serial1 for accessing serial pins 0 and 1 (however nRF52840 can use any pins).


text:
HC-05 Disconnects Underwater(predictably). How to make it reconnect by itself?
So I have an application where I send a Bluetooth module underwater(in a waterproof case). I have the Arduino+module sending my computer on-land a constant stream of numbers. Predictably, when the module goes underwater the stream cuts. I then need to remove the Arduino+module from the housing and reconnect/restart the connection.
Is there any way for the connection to start again by itself once above water. On my computer it says the Arduino and computer are connected the whole time. Maybe the code is just "pausing" on the serial.write() step?
Any advice would be appreciated.
#include <SoftwareSerial.h>
SoftwareSerial MegaloDon(10,11); //TX = 10, RX = 11, Ground = Ground, VCC = 5V
int BluetoothData;

unsigned long myTime = 0;
int givenHour;
int givenMin;
int givenSec;
int storeMin = 0;
int hour = 0;
int mins = 0;
int sec = 0;
int store = 0;
int count = 0;
int interval = 0;
int countToMin = 0;

void setup() { //time being set from recieving computer before being submerged in housing
  Serial.begin(9600);
  MegaloDon.begin(9600); //megalodon is the recieving computer
  MegaloDon.println("Bluetooth ON");
  Serial.println("start");
  Serial.flush();
  while (!Serial.available());
  givenHour = Serial.readStringUntil(',').toInt();
  givenMin = Serial.readStringUntil(',').toInt();
  givenSec = Serial.readStringUntil('.').toInt();
  MegaloDon.println(String(givenHour) + " : " + String(givenMin) + " : " + String(givenSec));

}

//min --> 3,600,000
void loop() {
  while(!MegaloDon.available()){ //Megalodon is the recieving computer
  myTime = millis();
  sec = givenSec + (myTime/1000);
  if (sec < 60){
    MegaloDon.println(String(givenHour) + " : " + String(givenMin) + " : " + String(sec));
  }
  if (sec >= 60){
    store = (sec % 60);
     if (sec % 60 == 0){
       count = count + 1;
       if(count%52 == 0 || count > 52){
        countToMin = count/52;
        mins = givenMin + countToMin;
        hour = givenHour;
        if(mins%60 ==0){
          mins = 0;
          hour = givenHour + countToMin;
        }
        if(mins )
        if(mins > 60){
          mins = mins%60;
        }
       }
     }
    MegaloDon.println(String(hour) + " : " + String(mins) + " : " + String(store)); //send to onshore computer step
  }
  }
}

//to use, plug the USB in, run arduino code with COM6, then run the python code, then open the TeraTerm COM8 port, unplug the USB

Based on the code you have shown us, I believe you may be correct when you say "Maybe the code is just "pausing" on the serial.write() step?".

@VE7JRO Thanks so much for the response. I updated my question with the relevant code snippet and my "serial.write()" is "println". I don't know that there is much of a difference but was wondering if you had any ideas on how to fix the issue.

Perhaps you could share your entire sketch with us?

@VE7JRO Will do. Thank you.


text:
How to set ESP32 RTC clock source
According to the manufacturer's link below, the default RTC timekeeping in the ESP32 is supposedly based on Internal 150 kHz RC oscillator.
Apparently, there is another option called Internal 8.5 MHz oscillator, divided by 256 (~33 kHz) that has better stability without needing an external crystal. That link goes on to say that

To modify the RTC clock source, set CONFIG_RTC_CLK_SRC in the project configuration.

All good information but NO EXAMPLES given. Can anyone point me to an example showing

how I can prove what the current clock source is, and
how to set actually it?

https://docs.espressif.com/.../system/system_time.html

The default is 150kHz RC, see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/system_time.html#rtc-timer-clock-sources

@hcheung Please don't answer questions with links that you have not read. I know all about the defaults and other options. The document does not show how to go about changing it.

Please don't assumed that I didn't read the document just because you don't understand it. The document is clearly said that "To modify the RTC clock source, set CONFIG_RTC_CLK_SRC in project configuration", it further provide the link to CONFIG_RTC_CLK_SRC page which again clearly indicated that the configuration is part of Component config > Hardware Settings > RTC Clock Config which you can find it here.

In summary, you are presuming that it can be dynamically change via programming, but it is not, you need to Edit sdkconfig.defaults file, set CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256=y and run idf.py to build it.

@hcheung my apologies then. Too many people post a link assuming it answer the OP question. The is no "sdkconfig.defaults" on my system,. There plenty of sdkconfig.h for each board, and there is one file "sdkconfig" file with no extender. The .h files indeed have macros defining those options.
I did make the change you suggested in that file, also commenting out the default one. But I do not have an idf.py file, and would not know how to run it. Is there a document that offers all the steps and where to get the needed tools?
Thanks in advance.

idf.py is part of esp-idf tools.


text:
4x TPIC6B595 + 4x 7 segment display
I am going to use 4x TPIC6B595 and 4x 7 segment display with common anode.
Below You Can find vendor site of this display.
https://sklep.avt.pl/wyswietlacz-led-2-30-57mm-zielony-wa.html
Here is my diagram:

I want to display 4 digit number. Will it work? Or do i need also MIC2981 chip to supply more current?
I didn't use shift registers like TPIC before. Could You show me a basic code to make display show 4 digit number?
Thanks in advance.

In this case you don't need the MIC2981 to switch the anodes because the anodes can be continuously powered. In your previous attempt, which used a single shift register and multiplexing, it was necessary to switch the anodes. Check that 9 volts is enough before proceeding too far. 12volts is probably better with that display.
You may find this project helpful as a code example: https://github.com/HeikkiHietala/large-7-segment-led-display/blob/master/Arduino-bigdigit03-clock.ino

Thank You for Your big support! That's what I need.


text:
Modbus RS485 Decode the message received
I'm try to read some value from a soil NPK sensor using RS485 Modbus e Arduino uno.
I menage to sent the request msg and I got the response but now i don't know how to read the response in order to get the information I need.
the following code sent the request to get moisture value to the sensor:
#include <SoftwareSerial.h>

#define RE 8
#define DE 7

const byte msg[] = {0x01,0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};
byte values[11];

SoftwareSerial mod(2, 3);

void setup() {

  Serial.begin(4800);

  mod.begin(4800);

  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);

  delay(500);
}

void loop() {
  test();

}

byte test(){
  digitalWrite(DE,HIGH);
  digitalWrite(RE,HIGH);
  delay(10);
  Serial.flush();

  if(mod.write(msg,sizeof(msg))==8){
    digitalWrite(DE,LOW);
    digitalWrite(RE,LOW);

    for(byte i=0;i<7;i++){
     values[i] = mod.read();
    Serial.print(values[i],HEX);

    }

    Serial.println();
    Serial.flush();
    delay(4000);

  }

}

My response is following bits:
114BA4134
1D5112A671
341D2119B
A61341D51
12A671341
E811BBAB13
41DB114BA4
1341DB11
4BA41341DB
114BA4134
1E311CA691
341C911EB
A11341E31
1CA691341
EC11FA6A13
41E4117BA8

looking at the datasheet below there should be a data area in the message response from the sensor.
how to convert this bit info to my humidty value.

my be this example from the datasheet can help

114BA4134 ... you have to print spaces between the bytes ... looks like leading zeros are not printed ... don't bother trying to decode the mess you have right now ... also, add code to print the leading zero ... if (values[i] < 16) Serial.print(0);


text:
How to connect a ps/2 keyboard to an arduino?
I want to connect an old hp ps/2 keyboard to my arduino (nucleo 64 F303RE). The keyboard has a power rating of 5v and 50mA, I guess this is milliamps.
The ps/2 connector has 4 connecting cables:
GND
VCC
CLK
DATA
I have wired up the GND to the ground of the arduino and the VCC. However, the keyboard does not properly light up or respond to the caps key being pressed. I am able to measure suppodly 5v coming out of the clock pin.
What could be the issue?
I would have expected that the keyboard would display some leds and when the caps lock would be pressed at least the caps light would turn on or off.

You'll need (very old) documentation about the PS/2 protocol. If I remember correctly, the protocol requires pulling down the clock to start the communication. And send some "A"s to initialize the device.

https://www.eecg.utoronto.ca/~jayar/ece241_08F/AudioVideoCores/ps2/ps2.html#:~:text=for%20sending%20commands-,PS%2F2%20Keyboard%20protocol,the%20host%20and%20the%20keyboard.

there is a library https://playground.arduino.cc/Main/PS2Keyboard/ . use 5V to power the keyboard and use 5 V tolerant pins on the STM32


text:
What type of pin header is this?
Most of the Arduino uno boards have black female pin header. when i bought a ardiuno uno the digital pins 0 to 7 are made of silver pins. What type of pin  header is that? How to use these kind of pin headers?

it is just the black plastic removed

What makes them basically unusable. You should remove them and solder on a new one

if you do not want to do any soldering, then you may be able to push on another shell ... you could also put heat shrink tubing on each of those forks

These are corrupted female headers so remove them and solder new ones.


text:
Motor encoder and interrupts
I'm trying to write motor controller for automated blinds using Raspberry Pi Pico with arduino-pico.
My problem is that I can't seem to get a consistent result from motor encoders.
In my setup function I attach the interrupt:
void motor0Enc1handler() {
  motor0.handleEnc1();
}

void setup() {
  attachInterrupt(digitalPinToInterrupt(motor0.getEnc1()), motor0Enc1handler, RISING);
}

Motor is a class with the following interrupt processing code:
int Motor::getEnc1() {
  return _enc1;
}
void Motor::handleEnc1() {
  // debug only
  if (digitalRead(_enc1) != HIGH) {
    _false_triggers++;
  }

  if (digitalRead(_enc2) == HIGH) {
    // debug only
    if (!_going_down) {
      _direction_changes++;
    }
    _going_down = true;

    _pos = _isLeft ? _pos - 1 : _pos + 1;
  } else {
    // debug only
    if (_going_down) {
      _direction_changes++;
    }
    _going_down = false;

    _pos = _isLeft ? _pos + 1 : _pos - 1;
  }
}

Interrupt is attached to one of the hall effect sensors on the motor. It has 2 sensors set an angle, so the direction of the motor can be determined.
For example, when _enc1 is HIGH and _enc2 is low at the same time it means that the motor is moving in one direction, when _enc2 is also high it moves in the opposite direction.
Here is much better explanation of this.
The main point is that the timing is extremely important to properly calculate the number of rotations the motor made.
For example, if handleEnc1 is delayed the motor would have slightly moved already and digitalRead(_enc2) will return incorrect value.
In my interrupt I've set up a few debugging variables:
_false_triggers is incremented when handleEnc1 is triggered, but when trying to read the same pin value it returns unexpected result. For example, handleEnc1 is triggered on RISING, so I would expect the pin value to be HIGH. If it's not high, it means that the interrupt was delayed and the hall effect sensor is not reporting a different value, because the motor shaft has rotated.
_direction_changes is incremented when motor is supposed to be moving in a single direction, so I would expect digitalRead(_enc2) == HIGH to always be true or false depending on the direction. If the motor keeps turning in the same direction it should never be incremented.
My hardware setup is:
Raspberry Pi Pico (_enc1 is pin 20, _enc2 is pin 21).
Motor is JGA25-370 with encoders.
Interrupts are triggered at about 2 interrupts per millisecond.
What happens is that I get non-zero _direction_changes and _false_triggers during normal operation:

start the motor to go in a single direction
serial print direction changes and false triggers from time to time
write current motor position into a file with LittleFS in flash memory.

In this case I get about 15-20 _direction_changes per 10000 steps and around 10 _false_triggers.
When I disable writing of motor position into a flash file it get less _direction_changes (around 10) and _false_triggers drops to zero, which is an improvement and it proves that the code is susceptible to competing interrupts (I imagine writing to file system or serial uses interrupts).
However, this is not ideal, since I need to use SPI as well to talk via nRF24l01 and I also need to persist current motor position periodically in case of a power loss.
Also, I don't want to have a position drift for my automated blinds, even though it's relatively small, but it will compound over time.
Am I not using interrupts correctly encoders?
Is there a better way to approach this?
I was thinking about attaching interrupts to both _enc1 and enc2 and push events into a queue and then process it in the main code, but I don't think it's going to work. I can only attach interrupts to either FALLING or RISING so I would be able to detect pulses in a single direction, if I attach interrupts to CHANGE it would mean I'd have to read pin value from within interrupt which is prone to the same issue that I'm already experiencing.
I guess my main problem is that I feel like I shouldn't be having this problem. I only have 2 pulses per millisecond, so it's not that many. Interrupt code is not doing much (unless I'm not supposed to do digitalRead in an interrupt). So I feel like there should be a reliable way to maintain motor position even if there is other stuff going on in the application.
The full code is here in case it's helpful.

"Am I not using interrupts correctly encoders"? I would suggest that you read Nick Gammon's Interrupt to understand the "do and don't of interrupt" first. I would also suggest you move most of the code in your Motor::Motor() construct to Motor::begin() as when you instantiating an instance of Motor object before the setup(), many of the peripherals might not be ready, or available yet.

Thanks!
I've read the post and so far other than not using volatile it seems like I'm not violating any rules of interrupts. That post even mentioned reading and writing to pins.
Since it's Raspberry Pi Pico I was able to use PIO to read interrupts (found a project on Github) which seems to have improved things, but I'd still like to to understand why it's not reliable the way I've implemented it.
Thanks for the advice about moving Motor::begin() into setup, it's a good point.