body:
I am trying to implement [WPS][1] on ESP32. [A WT32-SC01 Plus][2] to be exact.
It seems to working so far that I'll get the WPS connection but then it takes around 5 minutes [!!!] to get IP address from the router.
Also when the WPS connection was successful, after a reboot it do not reconnect but expects a new WPS initialization.

Can you take a look and tell me what am I doing wrong.

Here is my code:

    #include "WiFi.h"
    #include "esp_wps.h"

    #define ESP_MANUFACTURER  "ESPRESSIF"
    #define ESP_MODEL_NUMBER  "ESP32"
    #define ESP_MODEL_NAME    "ESPRESSIF IOT"
    #define ESP_DEVICE_NAME   "ESP STATION"

    struct WiFiHandler
    {
        bool connected = false;
        bool connecting = true;
        bool wpsDone = false;

        WiFiHandler()
        {
            WiFi.mode( WIFI_STA );
            // WiFi.setAutoReconnect( false );
            WiFi.onEvent( [ = ] ( WiFiEvent_t event, arduino_event_info_t info ) -> void
            {
                switch( event ) {
                    case ARDUINO_EVENT_WIFI_STA_START:
                        Output::Message( "Station Mode Started" );
                    break;
                    case ARDUINO_EVENT_WPS_ER_PIN:
                        Output::Message( "PIN: %d", info.wps_er_pin.pin_code );
                    break;
                    case ARDUINO_EVENT_WIFI_STA_GOT_IP:
                        Output::StartUpMsg( "Connected" );
                        connected = true;
                        connecting = false;
                    break;
                    case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
                        Output::Message( "Reconnecting" );
                        WiFi.reconnect();
                    break;
                    case ARDUINO_EVENT_WPS_ER_SUCCESS:
                        Output::StartUpMsg( "WPS Successfull." );
                        WiFi.disconnect();
                        wpsStop();
                        WiFi.begin();
                        wpsDone = true;
                    break;
                    case ARDUINO_EVENT_WPS_ER_FAILED:
                        Output::StartUpMsg( "WPS Failed!" );
                        connecting = false;
                    break;
                    case ARDUINO_EVENT_WPS_ER_TIMEOUT:
                        Output::StartUpMsg( "WPS Timedout!" );
                        connecting = false;
                    break;
                }
            } );
        }

        bool initialise()
        {
            int cnt = 0;
            TaskHandle_t taskHandle = NULL;
            xTaskCreate( this->blink, "WiFiConnect", 1000, this, 1, &taskHandle );
            Output::StartUpMsg( "Establishing network connection ..." );

            if( String( WiFi.SSID().c_str() ).length() ) {
                WiFi.begin( WiFi.SSID().c_str(), WiFi.psk().c_str() );
                while( ( WiFi.reconnect() != ESP_OK && !this->connected ) && ( ++cnt < 20 ) ) {
                    lv_bar_set_value( ui_BootProgress, lv_bar_get_value( ui_BootProgress ) + 1, LV_ANIM_ON );
                    delay( 100 );
                }
            }
            if( !this->connected ) {
                WiFi.begin();
                Output::StartUpMsg( "Please initialise WPS connection on the router." );
                cnt = 0;
                if( wpsInit() ) {
                    if( esp_wifi_wps_start( 1000 ) != ESP_OK ) {
                        Output::StartUpMsg( "Can't start WPS" );
                    }
                    while( WiFi.status() != WL_CONNECTED )
                    {
                        delay( 1000 );
                        if( WiFi.status() == WL_IDLE_STATUS && wpsDone ) {
                            WiFi.reconnect();
                        }
                        // if( WiFi.status() == WL_CONNECTION_LOST && wpsDone ) {
                        //     WiFi.disconnect();
                        //     WiFi.begin( WiFi.SSID().c_str(), WiFi.psk().c_str() );
                        // }
                        Output::Message( WiFi.SSID().c_str() );
                        Output::Message( WiFi.localIP().toString().c_str() );
                        Output::Message( String( WiFi.status() ).c_str() );
                    }
                    delay( 2000 );
                    this->connected = true;
                }
            }
            if( this->connected ) {
                while ( !WiFi.SSID().length() )
                {
                    lv_bar_set_value( ui_BootProgress, lv_bar_get_value( ui_BootProgress ) + 1, LV_ANIM_ON );
                    delay( 100 );
                }
                Output::StartUpMsg( "Connected to: " + WiFi.SSID() );
                while ( !String( WiFi.localIP() ).length() || WiFi.localIP().toString() == "0.0.0.0" )
                {
                    lv_bar_set_value( ui_BootProgress, lv_bar_get_value( ui_BootProgress ) + 1, LV_ANIM_ON );
                    delay( 100 );
                }
                Output::StartUpMsg( "IP: " + String( WiFi.localIP().toString() ) );
                delay( 500 );
                this->connecting = false;
                this->connected = true;
            }
            return this->connected;
        }

        String getIP()
        {
            return String( WiFi.localIP().toString() );
        }

        String getPass()
        {
            return String( WiFi.psk().c_str() );
        }

        String getNetworkName()
        {
            return String( WiFi.SSID() );
        }

        String getMAC()
        {
            return String( WiFi.macAddress() );
        }

        static void blink( void *pvParameter )
        {
            WiFiHandler *l_pThis = ( WiFiHandler * ) pvParameter;
            for( int i = 0; l_pThis->connecting; i++ )  {
                i%2 ? lv_obj_add_flag( ui_WiFiStatus1, LV_OBJ_FLAG_HIDDEN ) : lv_obj_clear_flag( ui_WiFiStatus1, LV_OBJ_FLAG_HIDDEN );
                delay( 250 );
            }
            l_pThis->connected ? lv_obj_clear_flag( ui_WiFiStatus1, LV_OBJ_FLAG_HIDDEN ) : lv_obj_add_flag( ui_WiFiStatus1, LV_OBJ_FLAG_HIDDEN );
            vTaskDelete( NULL );
        }

        static bool wpsInit()
        {
            int cnt = 0;
            esp_wps_config_t config;
            config.wps_type = WPS_TYPE_PBC;
            strcpy( config.factory_info.manufacturer, ESP_MANUFACTURER );
            strcpy( config.factory_info.model_number, ESP_MODEL_NUMBER );
            strcpy( config.factory_info.model_name, ESP_MODEL_NAME );
            strcpy( config.factory_info.device_name, ESP_DEVICE_NAME );
            esp_err_t status = esp_wifi_wps_enable( &config );

            if( status != ESP_OK ) {
                Output::StartUpMsg( "WPS config failed! " + String( esp_err_to_name( status ) ) );
                return false;
            }
            return true;
        }

        static void wpsStop()
        {
            if( esp_wifi_wps_disable() ) {
                Output::StartUpMsg( "WPS Disable Failed" );
            }
        }
    };

  [1]: https://en.wikipedia.org/wiki/Wi-Fi_Protected_Setup
  [2]: http://www.wireless-tag.com/wp-content/uploads/2022/11/WT32-SC01-Plus-V1.3-EN.pdf

title: Issues getting WPS working on ESP32

Answers: 1

body:
Ok people, my router was apparently acting weird. It seems to works fine now!

EDIT: Why the hell someone downvoted my answer? people are weird


body:
I've been playing around with several Arduino ethernet modules based on the ENC28J60 and the W5500 chipset. All modules are advertised as 10/100M, but in reality only work when the port of a switch is configured to handle 10M explicitly.

At this point in time that isn't a problem, however I'll be switching to new switches in the near future that can no longer handle 10M, having 100M as the slowest possible port speed.

How can I still connect my Arduino modules to these new switches (specifically Extreme Networks 5720-48MW)? Are there ethernet modules available that can connect to the 5720-48MW switches? And if so, how do I differentiate these modules, since all modules are advertised as 10/100M?

title: How to connect Arduino to a switch that doesn't accept 10M?

Answers: 0


body:
I am using adafruit DS3502 breakout board for arduino. When I follow procedure written in
https://learn.adafruit.com/ds3502-i2c-potentiometer/arduino

My serial display shows correct voltage values.

My question is: When I remove RL,RH, RW pins from arduino and measure resistance between RW and RL or RW and RH with a multimeter, it doesnt show correct value in ohms. It shows between 300 to 400 K Ohms. Anyone knows is this known behaviour or am I doing something wrong.

title: Digital potentiometer DS3502 question

Answers: 0


body:
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()

title: esp based smart light system over alexa malfunctioning

Answers: 1

body:
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.


body:
I'm trying to transfer data from a temperature sensor that is located outside my wifi area. I have chosen the 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 onto home assistant, things are getting 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 the mqtt are well displayed in coherence with the serial port but remain incoherent and the number of publications increase quickly
- from a certain moment, things does not moves anymore.

So I have at least two problems and even if 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 to 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);

    }

title: Lora to Mqtt sensor cannot be read

Answers: 2

body:
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`.

body:
Hello and thank you for your support, I finally found the pb which was that using incoming need 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() who allow a full string storage. I used after the function LoRaData.indexOf... which allow to select specific part of text with specific marks such as #, *, /, ...
Here is an example of the code used for 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.


body:
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?

title: Reading/writing Ntag215 with RC522

Answers: 1

body:
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();
    }
```


body:
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][1]

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

  [1]: https://learn.sparkfun.com/tutorials/lis3dh-hookup-guide/all

title: LIS3DH not working with arduino

Answers: 0


body:
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:

[![adapter connected to fake arduino][1]][1]

(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

  [1]: https://i.stack.imgur.com/nh3d6m.jpg

title: Why can't I upload a sketch by connecting directly to the serial pins?

Answers: 2

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

body:
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.


body:
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

[![pin layout][1]][1]

[![enter image description here][2]][2]

[![enter image description here][3]][3]

  [1]: https://i.stack.imgur.com/np6J3.jpg
  [2]: https://i.stack.imgur.com/nUu2k.jpg
  [3]: https://i.stack.imgur.com/PfON7.jpg

title: Potential difference across the same wire

Answers: 1

body:
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.


body:
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) [![schematic][1]][1], but when I uploaded sketch to Nano - only dots are turn on [![dots][2]][2].

Below You Can find my code

```c
#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.

  [1]: https://i.stack.imgur.com/QJQH5.png
  [2]: https://i.stack.imgur.com/JFXia.jpg

title: Arduino nano + 4x 7 segment display + 74HC595 - Only dot points are turn on

Answers: 1

body: 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.


body:
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:
https://arduino.stackexchange.com/questions/893/what-happens-if-i-power-the-arduino-with-both-the-usb-and-external-power-voltage
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 ?

[![charger + booster][1]][1]

  [1]: https://i.stack.imgur.com/Xb5ID.png

title: Nano 33 BLE Sense powered with Vin and USB at the same time

Answers: 1

body:
[![enter image description here][1]][1]

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)

  [1]: https://i.stack.imgur.com/OTz93.png


body:
I am attempting to follow [this tutorial](https://speedysignals.com/2013/08/01/how-to-assemble-stair-lights/) 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](https://www.youtube.com/watch?v=Lc4w2SDPnmE&embeds_euri=https://speedysignals.com/&feature=emb_imp_woyt&ab_channel=AndrewOng) 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.

[![PCB diagram][1]][1]

[![PCB Schematic][2]][2]

[![My Device][3]][3]

Here is the code from the guide plus my blinking loop. The original is available at the [author's github](https://github.com/androng/Shift-stairs).

```
##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;
    }
}
```
  [1]: https://i.stack.imgur.com/SBMoS.png
  [2]: https://i.stack.imgur.com/BJEUY.png
  [3]: https://i.stack.imgur.com/FkBuT.jpg

title: Motion-activated lights

Answers: 1

body:
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][1].  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][2] 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.

  [1]: https://www.pcbdirectory.com/community/what-is-a-cold-solder-joint
  [2]: https://www.youtube.com/watch?v=VLubdi6aC3g


body:
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:
[![Figure 1: Arduino UNO with I2C LCD displaay][1]][1]

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?

  [1]: https://i.stack.imgur.com/NC9T7.png

title: Powering up a 16x2 LCD display with only a 9V battery

Answers: 0


body:
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
    }

title: How to save the current SPI settings with out have a global variable keeping track?

Answers: 0


body:
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.

title: best practice for performance: empty loop() when using interrupt?

Answers: 2

body:
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.

body:
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.


body:
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:
```lang-cpp
/*
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:
```lang-cpp
/* 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:
```lang-cpp
/* 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?

title: Troubleshooting UART communication between nano 33 ble sense r2 and Adafruit Feather 32u4 with LoRa Radio Module

Answers: 1

body:
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).


body:
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(countR == 0 || count > 52){
        countToMin = count/52;
        mins = givenMin + countToMin;
        hour = givenHour;
        if(mins` ==0){
          mins = 0;
          hour = givenHour + countToMin;
        }
        if(mins )
        if(mins > 60){
          mins = mins`;
        }
       }
     }
    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
```

title: HC-05 Disconnects Underwater(predictably). How to make it reconnect by itself?

Answers: 0


body:
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
1) how I can prove what the current clock source is, and
2) how to set actually it?

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

title: How to set ESP32 RTC clock source

Answers: 0


body:
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:
[![diagram][1]][1]

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.

  [1]: https://i.stack.imgur.com/SPjeC.png

title: 4x TPIC6B595 + 4x 7 segment display

Answers: 0


body:
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.

[![pic][1]][1]

my be this example from the datasheet can help

[![pic 2][2]][2]

  [1]: https://i.stack.imgur.com/viPrg.png
  [2]: https://i.stack.imgur.com/hcvIF.png

title: Modbus RS485 Decode the message received

Answers: 0


body:
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.

title: How to connect a ps/2 keyboard to an arduino?

Answers: 0


body:
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?

[![The image shows an adruino uno r3. with some silver pin headers][1]][1]

  [1]: https://i.stack.imgur.com/AtKV7.jpg

title: What type of pin header is this?

Answers: 0


body:
I'm trying to write motor controller for automated blinds using Raspberry Pi Pico with [arduino-pico](https://github.com/earlephilhower/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](https://support.maxongroup.com/hc/en-us/articles/360005962273-Encoder-channels-A-and-B-phase-shift-and-direction-of-rotation) 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](https://github.com/Leonti/roller-blinds-controller/blob/5e23abdf5bd3ab8ca2ab23c6e84c46d3b1650210/firmware/src/main.cpp) in case it's helpful.

title: Motor encoder and interrupts

Answers: 0


body:
I'm working on a project where i have a Raspberry pi Pico connected to a NRF24l01+ to send some data.

However i'm not recieving any data on the reciever and i think that its because the SPI bus is not getting initialised propperly.

I have tested this code to try and troubleshoot the error
```
/*
  If your serial output has these values same then Your nrf24l01 module is in working condition :

  EN_AA          = 0x3f
  EN_RXADDR      = 0x02
  RF_CH          = 0x4c
  RF_SETUP       = 0x03
  CONFIG         = 0x0f

  This code is under public domain

  Last updated on 21/08/28
  https://dhirajkushwaha.com/elekkrypt
 */

#include <SPI.h>
#include <RF24.h>
#include <printf.h>

RF24 radio(12, 5);

byte addresses[][6] = {"1Node", "2Node"};

void setup() {
  Serial.begin(9600);
  delay(5000);
  SPI.begin();
  Serial.println("start");
  radio.begin();
  radio.setPALevel(RF24_PA_LOW);

  radio.openWritingPipe(addresses[0]);
  radio.openReadingPipe(1, addresses[1]);
  radio.startListening();
  printf_begin();

  radio.printDetails();

}

void loop() {
//  empty

}
```
And i'm recieving this as output
```
start
SPI Speedz = 10 Mhz
STATUS  = 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
RX_ADDR_P0-1 = 0x0000000000 0x0000000000
RX_ADDR_P2-5 = 0x00 0x00 0x00 0x00
TX_ADDR  = 0x0000000000
RX_PW_P0-6 = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA  = 0x00
EN_RXADDR = 0x00
RF_CH  = 0x00
RF_SETUP = 0x00
CONFIG  = 0x00
DYNPD/FEATURE = 0x00 0x00
Data Rate = 1 MBPS
Model  = nRF24L01+
CRC Length = Disabled
PA Power = PA_MIN
ARC  = 0
```
which doesnt look good...

I have checked the pins with my oscilloscope and appart from some activity on the CSN line i'm not seeing any data over the other pins at all. This is leading me to believe that the pico is not initialising the SPI bus in the correct way.

These are my connections:
```
VCC (nRF24L01) => 3.3V output (Raspberry Pi Pico).
GND (nRF24L01) => GND (Raspberry Pi Pico).
SCK (nRF24L01) => GP6 (Raspberry Pi Pico).
MOSI (nRF24L01) => GP7 (Raspberry Pi Pico).
MISO (nRF24L01) => GP4 (Raspberry Pi Pico).
IRQ (nRF24L01) => not connected
CE (nRF24L01) => GP12 (Raspberry Pi Pico).
CSN (nRF24L01) => GP5 (Raspberry Pi Pico
```
If anyone could help me out with this that would be greatly appreciated i need this thing to work really badly.

title: Raspberry pi pico (Arduino core) not initialising SPI correctly for NRF24l01

Answers: 0


body:
I have to use PWM to control some lights. I do this successfully with:
`analogWrite(11, 127);`
for a 50% PWM pulse on `pin 11`.

Now, i also have to have `tone()` support on my code. When I do:
`tone(10, melodyArray[thisNote], noteDuration);`
I invoke the `tone()` function on `pin 10`.

When I do so, then PWM pulse is corrupted. Since I do not have an oscilloscope, I cannot exactly understand what happens.
But from the effects on the lights, I can speculate that the PWM pin (`pin 11`) is always `HIGH` or always `LOW`.

It is obvious that the PWM pin and the `tone()` pin are different.

Why does this happen? Perhaps the `tone()` uses some timers that interfere with the PWM?
When I comment out the `tone()` line, the PWM works as intended.

Is there a solution to this? Can I use the tone() function and still have `PWM` support (on another pin)?

title: tone() corrupts the PWM on a different pin

Answers: 1

body:
To quote from the [Arduino documentation][1] of `tone()`:

> Use of the tone() function will interfere with PWM output on pins 3 and 11 (on boards other than the Mega).

So yes, you should use a different pin than 3 or 11 for `analogWrite()`. This is because `tone()` will configure the hardware Timer2 for outputting these timed signals via hardware. PWM on these pins is also tied to Timer2. When both functions are trying to configure Timer2 in a different way, there will be conflicts.

Note: The documentation talks about "boards other than the Mega", which was true when there weren't other Arduino boards than the old Uno/Nano/Mini (based on the Atmega328p). Nowadays there are so much boards, which all can be programmed with the Arduino framework, that this sentence is a real stretch. Instead I would say "on boards based on the Atmega328p". Depending on your used board your mileage may very. Check the microcontrollers datasheet for the hardware Timers it has and their connected pins.

  [1]: https://reference.arduino.cc/reference/en/language/functions/advanced-io/tone/


body:
I am working with a ESP32-C3 devkit. I am using the internal ADC on that chip to read from an analog microphone. I initialize the ADC like this:

    adc_continuous_config_t dig_cfg = {
        .sample_freq_hz = 20000,
        // ...
    };
    ESP_ERROR_CHECK(adc_continuous_config(handle, &dig_cfg));

If I reduce the sample frequency to, say 1000 Hz, then will each sample represent, roughly, an average of 20 samples from my previous stream (where the sample frequency was 20,000 Hz)? Or is it more like I will get just one out of every 20 samples from the original stream?

The reason I ask is that I'm hoping to perform a kind of low-pass filter by changing the ADC sampling frequency and I'm wondering what's going on inside the ADC hardware when I change the sampling frequency.

title: If I reduce ADC sample rate, do I get an average over the time period?

Answers: 1

body:
Possibly not. The ADC on the Arduino Uno (a different processor, I know) uses the "sample and hold" technique. This means that the ADC samples the input voltage at a point in time, copying it into a sample-and-hold capacitor. It then successively compares it to be above or below threshold voltages to generate the individual bits of the resulting number. I have some details about the Uno ADC [here](http://gammon.com.au/adc).

It probably does this so that, when sampling a rapidly changing signal (like audio) it samples a moment in time, rather than having the comparison be of a signal that is changing over time.

I can't find technical details for the ESP32 ADC sampling method, but it seems likely that a lower sample rate will simply sample less data points, not take an average. This  could lead to wildly inaccurate results.

You might want to check out the [Nyquist Frequency](https://en.wikipedia.org/wiki/Nyquist_frequency) to see the reasons for choosing a certain sample rate.

If you want an average, feeding the signal into a suitably-sized RC filter might be a good way of finding an average voltage.


body:
Hello help needed trying to get fastLED to start and stop at specific points on the strip, i have this nice fade animation but need to split the strip intov about 3 sections and have it run at different times.

here is the mess i have made any help welcome...

```c++
#include <FastLED.h>
#define NUM_LEDS 60
#define DATA_PIN 6 //How boring and obvious!
#define COLOR_ORDER GRB //Green (G), Red (R), Blue (B)
#define CHIPSET WS2812B
#define BRIGHTNESS 60
#define VOLTS 5
#define MAX_AMPS 500 //value in milliamps

//ENOUGH NONSENSE!

CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<CHIPSET,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setMaxPowerInVoltsAndMilliamps(VOLTS, MAX_AMPS);
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.clear();
  FastLED.show();
}

void loop() {
  fadeToBlackBy(leds, NUM_LEDS, 4);      // Smaller value = longer tail
  int i = (millis()/40) % NUM_LEDS;      // How fast it goes.
  leds[i] = CRGB::White;
  FastLED.show();
}
```

Cheers
Rob

title: fastLED help - special reinforcements needed

Answers: 1

body:
Here is an example sketch that shows how to manipulate data in a sub-section of an array.

https://wokwi.com/projects/362275278547275777

The important thing to understand, is that the `FastLED.show();` is the function that does the sending of the `leds[]` array contents to the physical LED strip.

That means that you can do anything you want to the `leds[]` array, and the changes will not be visible until the `show()` function is called.

You can make changes in bits and pieces, without seeing the change increments.

This sketch also shows how to use timers to synchronize actions

```lang-c++

#include <FastLED.h>

#define CHIPSET     WS2812B
#define COLOR_ORDER     GRB         // Green (G), Red (R), Blue (B)
#define NUM_LEDS         95
#define DATA_PIN          3
#define BRIGHTNESS      255
#define VOLTS             5
#define MAX_AMPS        500         // value in milliamps

CRGB leds[NUM_LEDS];                // main LED array
CRGB test[10];                      // set up separate array for merging with main LED array
                                    // kind of a sprite
int indx = 0;

boolean tick[4] = {false, false, false, false};    // countdown timers flags

unsigned long timeInterval  [4] = {10, 20, 1, 2};  // timers load with these values
unsigned long timeCounter   [4];                   // these are the actual timers

unsigned long previousMicros = 0;

void setup() {

  Serial.begin(115200);

  FastLED.addLeds<CHIPSET,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setMaxPowerInVoltsAndMilliamps(VOLTS, MAX_AMPS);
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.clear();

  memcpy(timeCounter, timeInterval, 4 * sizeof(long));  // preload timers
}

void loop() {

  unsigned long currentMicros = micros();

  if (currentMicros - previousMicros >= 1000) {   // 1 ms tick
    for (int i = 0; i < 4; i++) {
      previousMicros = currentMicros;

      timeCounter[i]-- ;                          // keep track of 4 time intervals
      if (timeCounter[i] == 0) {
        timeCounter[i] = timeInterval[i];         // reached zero, reload counter and emit a "tick"
        tick[i] = true;
      }
    }

    // fade sections of leds[] array at different rates
    // NOTE: "&leds[0]" and "leds" both point to the beginning of the array
    fadeToBlackBy(&leds [0], 30,  3);               //  long tail
    fadeToBlackBy(&leds[30], 30, 10);               //   mid tail
    fadeToBlackBy(&leds[60], 30, 20);               // short tail
    fadeToBlackBy(&leds[90],  5,  1);               // really long tail

    if (tick[0]) {    // 10 ms tick
      tick[0] = false;
      leds[indx] = CRGB::White;                   // add the "running dot" after fades are applied
      indx++;
      if (indx > (NUM_LEDS-1)) indx = 0;
    }

    if (tick[1]) {    // 20 ms tick
      tick[1] = false;

//    the &test[0] points to the array element directly
//    it allows the choice of a starting point for the fade function

//    fadeToBlackBy( test,    3, 16);               // these two lines are the same
      fadeToBlackBy(&test[0], 3, 16);               // fade only first three elements in the array
      fadeToBlackBy(&test[3], 1, 20);               // fade only the third element in the array

      if(test[0].r < 64){                           // pixels faded enough
        test[0]= CRGB(248, 11, 130);                // reload pixels
        test[1]= CRGB(221, 245, 6);
        test[2]= CRGB(112, 16, 236);
        test[3]= CRGB(16, 236, 53);
      }
    }
 memcpy(&leds[10], test,     4 * sizeof(CRGB));    // apply 4 pixels to leds[] array
 memcpy(&leds[50], &test[0], 4 * sizeof(CRGB));    // apply 4 pixels to leds[] array
 memcpy(&leds[80], &test[1], 3 * sizeof(CRGB));    // apply 3 pixels to leds[] array

    FastLED.show();                                   // send pixel data to the LED strip
  }
}
```