body:
I was experimenting with for loops when I noticed that a simple increment loop executes faster than a decrement loop. I can't think of any reason why it should be like that. Is there something in my code that is causing the different in execution speed?

The code is as follows:

    // Global Variables
    const int spk = 7;
    const int led = 6;
    int j = 0; // counter variable

    void setup() {

      pinMode(spk, OUTPUT);
      pinMode(led, OUTPUT);
      Serial.begin(9600);
    } // end of setup

    void loop() {

      tone(spk, 300, 500); // first note with duration

      // increment loop
      for (j=0; j <= 500; j = j + 1) {
        digitalWrite(led, HIGH);
        Serial.println(j);
      } // end 1st note loop

      tone(spk, 100, 500); // second note with duration

      // decrement loop

      for (j = 500; j >= 0; j=j-1) {
        digitalWrite(led, LOW);
        Serial.print("the value is=");
        Serial.print("\t");
        Serial.println(j);
      } // end 2nd Note loop

    } // end setup

title: Difference in increment & decrement loop execution speed

Answers: 2

body:
In the code you posted, the decrement loop has two more Serial.print() statements.

Serial.print() takes a lot of time and while it's useful for debugging, it sometimes can cause additional bugs because of the extra delay it introduces if you are running time-sensitive code.

Consider for using Serial.print("the value is=\t" + itoa(j,10));

"itoa" converts an integer to an array of characters (aka string). As Juraj said, it takes another two arguments which are the buffer to store the output string and the base to which it converts the incoming number to be represented by (eg: 10 is decimal, 16 is hexadecimal). It returns a pointer to the output string which is essentially the same as the second argument but AFAIR you can omit the second argument and use it's return value.

body:
Comment out these 2 lines

    Serial.print("the value is=");
    Serial.print("\t");

And report back on the speed difference.
Why not add a reading of micros() before and after each loop and see how much difference there really is?  All time variables are unsigned long.

    startTime = micros();
    // your loop
    endTime =  micros();
    duration = endTime - startTime;
    Serial.println (" "); // line break
    Serial.print ("duration in uS = ");
    Serial.println (duration);

I edited to add some missing )s and a 2nd line break.


body:
For my school project im making an arduino speedometer for a bicycle. I will be using a reed switch sensor to get the speed. There will also be an clock and a termometer, it will be on a 16x2 lcd screen. To get the speed I will need the user to type in his bike size, in zoll. I managed to let the user tap the button until his size and then double tap the button to confirm it. Alright, fine. Now I need the same button to FORGET his last purpose. Because I want to use the same button to change the screen between speed, clock and termometer. SPEED -> tap -> CLOCK -> tap -> TEMPERATURE -> tap -> SPEED ........

I hope you get the idea. After the user picks his size, if he keeps tapping the number it would just keep on growing. So, im trying to make the button forget, or make him go trough that loop only once.

Pick your size tap tap tap double tap, thank you. And stop! I want him to do that only once and never again. I will need the same principle when the user will adjust his clock, he will have to tap to set it, save the number but reset the buttons function.

    #include <LiquidCrystal_I2C.h>
    #include <LiquidCrystal.h>
    LiquidCrystal_I2C lcd(0x27, 16,2);
    #define buttonPin 7
    int a = 16;
    int b = 0;

    void setup() {
      lcd.init();
      lcd.backlight();
      lcd.print("RADGROESSE IN");
      lcd.setCursor(0, 1);
      lcd.print("ZOLL EINGEBEN");

       // Set button input pin
       pinMode(buttonPin, INPUT);
       digitalWrite(buttonPin, HIGH );
    }
    void loop() {
       int b = checkButton();
       if (b == 1) clickEvent();
       if (b == 2) doubleClickEvent();
    }
    void clickEvent() {

       lcd.setCursor(14, 1);
        lcd.print(a);
        delay(100);
        lcd.print(" ");
        delay(100);
        a++;
        delay(100);
        if(a >= 23){
          a = 16;
          }
    }
    void doubleClickEvent() {
          b = a - 1;
          Serial.println("Button was idle for one second or more");
          lcd.clear();
          lcd.print("ZOLL = ");
          lcd.setCursor(7, 0);
          lcd.print(b);

    }

    //=================================================
    //  MULTI-CLICK:  One Button, Multiple Events

    // Button timing variables
    int debounce = 20;          // ms debounce period to prevent flickering when pressing or releasing the button
    int DCgap = 420;            // max ms between clicks for a double click event
    // Button variables
    boolean buttonVal = HIGH;   // value read from button
    boolean buttonLast = HIGH;  // buffered value of the button's previous state
    boolean DCwaiting = false;  // whether we're waiting for a double click (down)
    boolean DConUp = false;     // whether to register a double click on next release, or whether to wait and click
    boolean singleOK = true;    // whether it's OK to do a single click
    long downTime = -1;         // time the button was pressed down
    long upTime = -1;           // time the button was released

    int checkButton() {
       int event = 0;
       buttonVal = digitalRead(buttonPin);
       // Button pressed down
       if (buttonVal == LOW && buttonLast == HIGH && (millis() - upTime) > debounce)
       {
           downTime = millis();
           singleOK = true;
           if ((millis()-upTime) < DCgap && DConUp == false && DCwaiting == true)  DConUp = true;
           else  DConUp = false;
           DCwaiting = false;
       }
       // Button released
       else if (buttonVal == HIGH && buttonLast == LOW && (millis() - downTime) > debounce)
       {
               upTime = millis();
               if (DConUp == false) DCwaiting = true;
               else
               {
                   event = 2;
                   DConUp = false;
                   DCwaiting = false;
                   singleOK = false;
               }
       }
       // Test for normal click event: DCgap expired
       if ( buttonVal == HIGH && (millis()-upTime) >= DCgap && DCwaiting == true && DConUp == false && singleOK == true && event != 2)
       {
           event = 1;
           DCwaiting = false;
       }

       buttonLast = buttonVal;
       return event;
    }

Thank you! I would really appreciate it!

title: How to make an arduino button to forget his past purpose?

Answers: 2

body:
What you likely need is a state machine. The behavior of the actions depends on the state the program is currently in.

In your case, the state machine might look like this:

[![State machine][1]][1]

What does it mean?

* black circle: this is where the system powers on
* rectangle: a state
* arrow: a transition from one state to another
* green text: action

For the problematic double click action, you can see:

* it changes the state from "set size" to "speed"
* in all other cases, it does not change the state (actually it changes the state to the same state)

I always recommend drawing the state machine before implementing it. It makes mistakes much more obvious.

There are several ways to implement it. The easiest one being a `switch/case`. More advanced implementations may use object orientation. When using `switch/case`, I prefer to have one method per state, like so:

    void loop()
    {
        switch(state):
            case setsize:
                 setsize();
                 break;
            case speed:
                 speed();
                 break;
            ...
    }

If you know about function pointers, it gets even easier:

    enum State {
      setsize = 0,
      speed,
      clock,
      temperature
    };

    State state;

    void setup() {
      state = State::setsize;
    }

    typedef void (* functionPointer) ();
    functionPointer process[] = {do_setsize, do_speed, do_clock, do_temperature};
    void loop() {
      process[state]();
    }

    void do_setsize()
    {
      state = State::speed;
    }
    void do_speed()
    {
      state = State::clock;
    }
    void do_temperature()
    {
      state = State::speed;
    }
    void do_clock()
    {
      state = State::temperature;
    }

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

body:
jsotola wrote a very important term in the comments: state.

You should implement your project as a Finite State Machine (FSM), a very important and powerful, yet easy principle. You divide your program into different states. Each state contains code, that only gets executed, when the program is in this state. Depending on input events (like the user pressing the button), you do transitions between the states.

I already wrote a rather detailed answer about FSMs for [this question][1]. You can read it to get a better understanding of FSMs.

For your case I would suggest these states: `INPUT_SIZE`, `DISPLAY_SPEED`, `DISPLAY_CLOCK` and `DISPLAY_TEMPERATURE`. `INPUT_SIZE` is the initial state (which you might skip after the first power on, after you saved the size in persistent memory like EEPROM). There you execute your current button code. When you sense a double tap on the button, you change to the `DISPLAY_SPEED` state. From there on a button press to the `DISPLAY_CLOCK` state and so on.

In my linked answer I used a simple integer variable as state variable, which holds the current state. In fact it is better (easier to read), when you define an `enum` for the cases (`enum`s are actually only named integer constants):

    enum State {INPUT_SIZE, DISPLAY_SPEED, DISPLAY_CLOCK, DISPLAY_TEMPERATURE};

    State state = INPUT_SIZE;

    void loop(){
        switch(state){
            case INPUT_SIZE:
                // Button code here
                // on double tap use the following line
                state = DISPLAY_SPEED;
                break;
            case DISPLAY_SPEED:
                // code for displaying speed here
            ...
        }
    }

That is just a little template for the structure. You need to fill it with life yourself.

  [1]: https://arduino.stackexchange.com/questions/63488/wanted-to-control-2-servos-with-serial-read


body:
I am trying to convert some binary data to decimal numbers. I succeeded to convert binary to hex, but now I want to do the same with binary to decimal. I want to use bitwise operators and NO array.

See my code from binairy to hex. The incoming data is 8 bits. This code first calculates the most significant number, and then, the least significant number. This works good, but I cannot figure it out for bin to dec

The function `console_print_char` is sort of the printf function of my program.

        void console_print_hex_char(unsigned char data){
     unsigned char temp;

     if(data){
      temp = (data >> 4);
      if(temp){
       if(temp> 9) console_print_char(temp + ('A'- 10));
       else console_print_char(temp + '0');
      }
      temp = data & 0x0F;
      if(temp> 9) console_print_char(temp + ('A'- 10));
      else console_print_char(temp + '0');
     }
     else{
      console_print_char('0');
     }
    }

title: Binary to decimal using bitwise operators

Answers: 2

body:
You cannot do what you are trying to do. There is no direct correspondence between some number of bits and a decimal digit.

With hexadecimal, every 4 bits corresponds to exactly 1 hex digit. That is why hex is used for computers.

One hex digit represents exactly 4 bits. Every time you add another hex digit, you add 4 bits.

Two hex digits corresponds to exactly a byte. 00h to FFh represents a value from 0 to 255.

There is no such direct correspondence between binary and decimal. If you have 4 bits, it takes 1 or 2 decimal digits to represent it (0-15) If you have 8 bits, it takes 1, 2, or 3 decimal digits to represent it, but there are 3 digit decimal values (values > 255) that you can't represent with 8 bits.

    Binary  Hex Decimal
    0000    0   0
    0001    1   1
    0010    2   2
    0011    3   3
    0100    4   4
    0101    5   5
    0110    6   6
    0111    7   7
    1000    8   8
    1001    9   9
    1010    A   10
    1011    B   11
    1100    C   12
    1101    D   13
    1110    E   14
    1111    F   15

You simply cannot convert a binary number to decimal using bit shifting and masking.

As @Kwasmich says in their answer, the closest you're likely to come would be to convert your binary value to BCD (Binary coded decimal) where each 4 bits holds a decimal digit. You could convert THAT to decimal character output using masking and shifting.

body:
here's the c++ code
```
    vector<int> b={1,0,1,0,1,0,1};
        int sum=0;
        for(int i=b.size()-1, j=0; i>=0; i--, j++){
            sum+=b[j]*(1<<i);
        }
        return sum;
```


body:
Im soldering an LCD screen to my Arduino as I don't have a breadboard and plan on it being permanent. I'm wondering how I should connect the potentiometer (to control contrast).

If I connect it as the first component in series, will this affect the main power to the LCD?

Should I use both 5v pins on the Arduino instead? (Mine has two anyway, I dont know if the official one does).

Would splitting a cable work?

Im new to electronics so sorry if the questions are stupid.

I intend to use the circuit from: https://www.arduino.cc/en/Tutorial/HelloWorld.
Thanks for any help.

title: Multiple devices on 5v pin

Answers: 0


body:
Suppose we want to save battery power, and we use sleep mode and also prevent the Arduino from hanging and use the watchdog timer.

The problem is here that when the Arduino goes to sleep the watchdog timer never (or can't be) reset again because of sleep and it will overflow over and over and reset the Arduino over and over.

So what do you suggest to solve this problem, I mean running sleep mode and watchdog timer at the same time in a code?

title: Sleep mode and watchdog at the same time

Answers: 2

body:
When you sleep the Arduino *is* locked up. So yes, the watchdog timer will time out and reset the Arduino.

But, since you're in sleep mode, it's not so much a "reboot" as a "wakeup".

The watchdog timer is one of the normal ways of waking up periodically to do things.  If you want to use the watchdog for its other "anti-lockup" purpose then you will have to arrange some other way of waking up before the watchdog is due to expire so you can "kick" it.

Or you disable the watchdog entirely before going to sleep so that the only wakeup source is whatever source you have configured. Then you can turn the watchdog on again when you wake up.

However that probably means that the watchdog is useless, since chances are you won't be awake for long enough periods for the watchdog to have any effect.

Sleeping and using the internal watchdog as a watchdog are pretty much mutually exclusive.  If you sleep, then the watchdog is a periodic wake-up source.

body:
Either set the watchdog to 8s, and setup the WDT interrupt. And deal with the fact that the MCU wakes up every 8s. You could have it go back to sleep, unless a button is pressed, or something. The extra power usage for these short wakeups is negligible in most cases.

Or disable the watchdog right before sleeping, and enable right after waking up. And hope the MCU never hangs in between.


body: I am working on a project which involves counting the drops falling in a drip chamber of a IV fluid gravity based therapy bottle(saline bottle).I am using IR trans-receiver at the drip chamber to detect a drop falling. I am using a comparator to generate a pulse when ir voltage drops below a certain threshold. The output of comparator is connected to D1 of nodemcu. The ISR is called at rising pulse of comparator .But the nodemcu calls the ISR 3 to 5 times on a single drop.what should I do?plz help.

title: I am facing a problem of firing multiple interrupts on nodemcu 1.0 on single rising edge pulse.what is problem and what are the solutions?

Answers: 1

body:
The signal is probably "bouncing" between HIGH and LOW instead of performing a clean edge, just like it happens with [buttons][1].

Two simple solutions:

 1. Hardware solution: use a schmidt-trigger instead of a comparator
 2. Software solution: define a dead-time for the signal aquisition (disable the interrupt when the desired edge has been detected and enable it again after "dead-time")

  [1]: https://www.allaboutcircuits.com/technical-articles/switch-bounce-how-to-deal-with-it/


body:
Hello i have a class and i would like to attach an interrupt inside the class and attach it to a function of the class.

    class counter{
      public:

      counter(int pin){
        Ipin=pin;
      }
      void startCounting(){
        attachInterrupt(digitalPinToInterrupt(Ipin),this.addCount,CHANGE);
      }
      void stopCounting(){
        detachInterrupt(digitalPinToInterrupt(Ipin));
      }

      void addCount(){
        count++;
      }

      private:
      int Ipin;
      unsigned long count= 0;
    };

Some what of the code above. There can be multiple intialization of this class. hopefully depending on the user uses a different pin.

There is a way arround this where the attaching of pin is done in the loop or setup and just calling a public function of the class. But to me that kinda doesn't fit the spirit of classes like a properly made library is done.

Im not very good at programming if you could teach me how it would be greatly appreciated.

title: Interrupts inside a class attaching to the function of the class

Answers: 1

body:
I have [a post about this problem](http://www.gammon.com.au/forum/?id=12983).

Basically you cannot attach a class function with attachInterrupt because of the hidden "this" pointer which needs to be supplied to a (non-static) class function, where "this" is the particular instance of the class. You can work around it like this:

<!-- language: lang-c++ -->

    class myClass
      {
      static volatile bool switchChanged;  // declare

      public:

      void begin ()
        {
        pinMode (2, INPUT_PULLUP);
        attachInterrupt (0, switchPressed, CHANGE);
        }  // end of myClass::begin

      static void switchPressed ()
        {
        switchChanged = true;
        }  // end of myClass::switchPressed

      };  // end of class myClass

    volatile bool myClass::switchChanged;  // define

    myClass foo;  // make an instance of myClass

    void setup ()
      {
      foo.begin ();
      }  // end of setup

    void loop ()
      {
      // whatever
      }  // end of loop

But that isn't great because, as you observed, you are really downgrading the class to use a static boolean.

---

Another way of doing it is to write "glue" routines, like this:

    class myClass
      {
      volatile bool switchChanged;

      static myClass * instances [2];

      static void switchPressedExt0 ()
        {
        if (myClass::instances [0] != NULL)
          myClass::instances [0]->switchPressed ();
        }  // end of myClass::switchPressedExt0

      static void switchPressedExt1 ()
        {
        if (myClass::instances [1] != NULL)
          myClass::instances [1]->switchPressed ();
        }  // end of myClass::switchPressedExt1

      public:

      void begin (const byte whichPin)
        {
        pinMode (whichPin, INPUT_PULLUP);
        switch (whichPin)
          {
          case 2:
            attachInterrupt (0, switchPressedExt0, CHANGE);
            instances [0] = this;
            break;

          case 3:
            attachInterrupt (1, switchPressedExt1, CHANGE);
            instances [1] = this;
            break;

          } // end of switch
        }  // end of myClass::begin

      void switchPressed ()
        {
        switchChanged = true;
        }

      };  // end of class myClass

    myClass * myClass::instances [2] = { NULL, NULL };

    // instances of our class
    myClass foo;
    myClass bar;

    void setup ()
      {
      foo.begin (2);   // pin D2
      bar.begin (3);   // pin D3
      }  // end of setup

    void loop ()
      {
      // whatever
      }  // end of loop

That's still not a great solution, but it might give you some ideas.

---

Your fundamental problem is that classes, by their nature, can be instantiated many times, however you only have a small, fixed, number of interrupts on the microprocessor.


body:
I want to create some buzzers connected via bluetooth for a quiz show. I got several ESP32. One of them is the master (BLE Server), the other ESP32s are the buzzers (BLE Clients) with one big button and some LEDs each. The master sends commands ("turn on", "turn off", "you are number x") to all the buzzers and receives when one of them gets pressed.

The code on both sides works for up to 4 clients, but I can't connect more than 4 BLE clients to the BLE server.
I found and changed the ```CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN``` and ```CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF``` in ```sdkconfig.h``` at ```C:\Users\MyName\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\tools\sdk\include\config```.

This seems to be the right place, because both values originally were 3 and then only three clients could connect. The fourth client was rejectet (got a ```false``` on ```pClient->connect(myDevice);```). When I updated both numbers to 4, the fourth client could connect and could receive the notifications from the server.

Then I changed these two numbers to 8, because I potentially want to connect even more buzzers. But the 5th buzzer could not connect. It got a ```true``` on ```pClient->connect(myDevice);```, but it would not receive any notifications from the server. A few seconds later it starts looking for a server again. The server also does not recognize the 5th client (for client 1 to 4 the server prints ```Device connected. Now there are x devices connected.```, but not so for the 5th client)

This is my servers code
```
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>

#define DEBUG
#define VERSION "0.1"

#define BUZZER_SERVICE_UUID "a2066d3e-d566-42bd-9d64-9bf3ae53b504"
#define COMMAND_CHAR_UUID   "e7adc44d-a04e-46b1-aa4b-ded61bc3b0a8"
#define RESPONSE_CHAR_UUID  "e7adc44d-a04e-46b1-aa4b-ded61bc3b0a9"

#define PIN_BUTTON_ARM 23
#define PIN_BUTTON_DISARM 22

BLEServer* pServer = NULL;
BLECharacteristic* pCommandCharacteristic = NULL;
BLECharacteristic* pResponseCharacteristic = NULL;
int deviceConnected = 0;
bool oldDeviceConnected = false;

bool armPressed = false;
bool disarmPressed = false;

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer)
    {
  deviceConnected++;
  BLEDevice::startAdvertising();
  #ifdef DEBUG
  Serial.print("Device connected. Now there are ");
  Serial.print(deviceConnected);
  Serial.println(" devices connected.");
  #endif
    };

    void onDisconnect(BLEServer* pServer)
    {
  deviceConnected--;
  pServer->startAdvertising(); // restart advertising
  #ifdef DEBUG
  Serial.print("Device disconnected. Now there are ");
  Serial.print(deviceConnected);
  Serial.println(" devices connected.");
  #endif
    };
};

class MyCharCallbacks: public BLECharacteristicCallbacks
{
    void onWrite(BLECharacteristic *pCharacteristic)
    {
  std::string rxValue = pCharacteristic->getValue();
  Serial.print(">>> ");
  Serial.println(rxValue.c_str());

  if (rxValue.length() > 0)
  {
   //TODO
  }

    }
};

void setup()
{
 #ifdef DEBUG
 Serial.begin(115200);
 Serial.println("\n\n--------------");
 Serial.println("BUZZER HUB");
 Serial.println("--------------");
 Serial.print("VERSION: ");
 Serial.println(VERSION);
 Serial.println("--------------");
 #endif

 pinMode(PIN_BUTTON_ARM, INPUT_PULLUP);
 pinMode(PIN_BUTTON_DISARM, INPUT_PULLUP);

 BLEDevice::init("BuzzerHub");
 pServer = BLEDevice::createServer();
 pServer->setCallbacks(new MyServerCallbacks());

 BLEService *pService = pServer->createService(BUZZER_SERVICE_UUID);

 // Create a BLE Characteristic and a BLE Descriptor for sending the commands
 pCommandCharacteristic = pService->createCharacteristic(COMMAND_CHAR_UUID, BLECharacteristic::PROPERTY_NOTIFY);
 pCommandCharacteristic->addDescriptor(new BLE2902());

 // Create a BLE Characteristic and a BLE Descriptor for receiving the responses
 pResponseCharacteristic = pService->createCharacteristic(RESPONSE_CHAR_UUID, BLECharacteristic::PROPERTY_WRITE);
 pResponseCharacteristic->addDescriptor(new BLE2902());
 pResponseCharacteristic->setCallbacks(new MyCharCallbacks());

 //Start the service
 pService->start();

 BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
 pAdvertising->addServiceUUID(BUZZER_SERVICE_UUID);
 pAdvertising->setScanResponse(true);
 pAdvertising->setMinPreferred(0x06);
 BLEDevice::startAdvertising();

 #ifdef DEBUG
 Serial.println("BLE is now advertising");
 #endif
}

void loop()
{
 if(digitalRead(PIN_BUTTON_ARM) == LOW)
 {
  if(!armPressed) //On pressing the button
  {
   armBuzzer();
   delay(100); //Debounce
  }
  armPressed = true;
 }
 else
 {
  if(armPressed) //On releasing the button
  {
   delay(100); //Debounce
  }
  armPressed = false;
 }

 if(digitalRead(PIN_BUTTON_DISARM) == LOW)
 {
  if(!disarmPressed) //On pressing the button
  {
   disarmBuzzer();
   delay(100); //Debounce
  }
  disarmPressed = true;
 }
 else
 {
  if(disarmPressed) //On releasing the button
  {
   delay(100); //Debounce
  }
  disarmPressed = false;
 }
}

void armBuzzer()
{
 if (deviceConnected)
 {
  #ifdef DEBUG
  Serial.println("<<< ARM");
  #endif
        pCommandCharacteristic->setValue("ARM");
        pCommandCharacteristic->notify();
        //delay(3); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms
    }
}

void disarmBuzzer()
{
 if (deviceConnected)
 {
  #ifdef DEBUG
  Serial.println("<<< DISARM");
  #endif
        pCommandCharacteristic->setValue("DISARM");
        pCommandCharacteristic->notify();
        //delay(3); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms
    }
}
```
And this is my clients BLE part of the code (there is more, but that got nothing to do with BLE)
```
// The buzzer service we wish to connect to.
static BLEUUID buzzerServiceUUID("a2066d3e-d566-42bd-9d64-9bf3ae53b504");
// The characteristic of the buzzer service that is there for receiving commands from the hub.
static BLEUUID buzzerCommandCharUUID("e7adc44d-a04e-46b1-aa4b-ded61bc3b0a8");
// The characteristic of the buzzer service that is there for sending commands to the hub.
static BLEUUID buzzerResponseCharUUID("e7adc44d-a04e-46b1-aa4b-ded61bc3b0a9");

static BLERemoteCharacteristic* pCommandCharacteristic;
static BLERemoteCharacteristic* pResponseCharacteristic;
static BLEAdvertisedDevice* myDevice;
String message;
bool newMessage;

static boolean doConnect = false;
static boolean connected = false;

static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify)
{
 #ifdef DEBUG
 /*
    Serial.print("Notify callback of data length ");
    Serial.println(length);
    Serial.print("data: ");
    Serial.println((char*)pData);
    */
    #endif
    message = "";
    for(int i = 0; i < length; i++)
    {
     message += (char)pData[i];
    }
    message += '\0';
    newMessage = true;
}

class MyClientCallback : public BLEClientCallbacks {
 void onConnect(BLEClient* pclient)
 {
  connected = true;
  setMiddleLed(0,255,0);
  #ifdef DEBUG
  Serial.println("onConnect");
  #endif
 }

 void onDisconnect(BLEClient* pclient)
 {
  connected = false;
  setMiddleLed(255,0,0);
  updatePattern = false;
  #ifdef DEBUG
  Serial.println("onDisconnect");
  #endif
 }
};

//Scan for BLE servers and find the first one that advertises the service we are looking for.
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks
{
 //Called for each advertising BLE server.
 void onResult(BLEAdvertisedDevice advertisedDevice)
 {
  #ifdef DEBUG
  Serial.print("Advertised Device found: ");
  Serial.println(advertisedDevice.toString().c_str());
  #endif

  // We have found a device, let us now see if it contains the service we are looking for.
  if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(buzzerServiceUUID)) // Found our server
  {
   BLEDevice::getScan()->stop();
   myDevice = new BLEAdvertisedDevice(advertisedDevice);
   doConnect = true;
  }
 }
};

bool connectToServer()
{
 #ifdef DEBUG
    Serial.print("Connecting to ");
    Serial.println(myDevice->getAddress().toString().c_str());
    #endif

    //Create Client
    BLEClient*  pClient  = BLEDevice::createClient();
    pClient->setClientCallbacks(new MyClientCallback());

    // Connect to the remote BLE Server.
    bool ok = pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
    if (!ok)
    {
     #ifdef DEBUG
  Serial.print("Failed to connect to address: ");
  Serial.println(myDevice->getAddress().toString().c_str());
  #endif
  pClient->disconnect();
  return false;
    }

    // Obtain a reference to the service we are after in the remote BLE server.
    BLERemoteService* pRemoteService = pClient->getService(buzzerServiceUUID);
    if (pRemoteService == nullptr)
    {
     #ifdef DEBUG
  Serial.print("Failed to find our service UUID: ");
  Serial.println(buzzerServiceUUID.toString().c_str());
  #endif
  pClient->disconnect();
  return false;
    }

    // Obtain a reference to the characteristic in the service of the remote BLE server.
    pCommandCharacteristic = pRemoteService->getCharacteristic(buzzerCommandCharUUID);
    if (pCommandCharacteristic == nullptr)
    {
     #ifdef DEBUG
  Serial.print("Failed to find command characteristic UUID: ");
  Serial.println(buzzerCommandCharUUID.toString().c_str());
  #endif
  pClient->disconnect();
  return false;
    }

    // Obtain a reference to the characteristic in the service of the remote BLE server.
    pResponseCharacteristic = pRemoteService->getCharacteristic(buzzerResponseCharUUID);
    if (pResponseCharacteristic == nullptr)
    {
     #ifdef DEBUG
  Serial.print("Failed to find response characteristic UUID: ");
  Serial.println(buzzerResponseCharUUID.toString().c_str());
  #endif
  pClient->disconnect();
  return false;
    }

    //Register the notification
    if(pCommandCharacteristic->canNotify()) pCommandCharacteristic->registerForNotify(notifyCallback);

    return true;
}

void setupBle()
{
 String name = "Buzzer" + String(dipNumber);
 BLEDevice::init(name.c_str());

 scanForServer();
}

void scanForServer()
{
 #ifdef DEBUG
 Serial.println("Scanning for Server...");
 #endif

 setMiddleLed(0,0,255);
 updatePattern = false;

 // Retrieve a Scanner and set the callback we want to use to be informed when we
 // have detected a new device.  Specify that we want active scanning and start the
 // scan to run for 5 seconds.
 BLEScan* pBLEScan = BLEDevice::getScan();
 pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
 pBLEScan->setInterval(1349);
 pBLEScan->setWindow(449);
 pBLEScan->setActiveScan(true);
 pBLEScan->start(5, false);
}

void loopBle()
{
 // If the flag "doConnect" is true then we have scanned for and found the desired
 // BLE Server with which we wish to connect.  Now we connect to it.
 if (doConnect == true)
 {
  if (connectToServer())
  {
   #ifdef DEBUG
   Serial.println("Connected to server.");
   #endif
  }
  else
  {
   #ifdef DEBUG
   Serial.println("Failed to connect to server.");
   #endif
  }
  doConnect = false;
 }

 if(!connected)
 {
  delay(100);
  setMiddleLed(255,0,0);
  delay(900);
  scanForServer();
 }
}

void sendData(String stringToSend)
{
 // Only send when connected
 if (connected)
 {
  //Set the characteristic's value to be the array of bytes that is actually a string.
  pResponseCharacteristic->writeValue(stringToSend.c_str(), stringToSend.length());
  #ifdef DEBUG
  Serial.print("<<< ");
  Serial.println(stringToSend);
  #endif
 }
 else
 {
  #ifdef DEBUG
  Serial.println("Can't Send because not connected");
  Serial.print("XXX ");
  Serial.println(stringToSend);
  #endif
 }
}
```

How can I connect more clients to my BLE server? What is the maximum number?

Thanks for your help!

title: Connect more than 4 BLE clients to ESP32 BLE Server

Answers: 0


body:
**EDIT DOWNSTAIRS:**

Hello beautiful people of the internet! How are you smart people doing with all that's going on these days. Okay so the title says it pretty much. I've got a code and inside of my if's I have added something that lets me see the data from the sensor in percentage on my LCD. It works but it just stays at the number it read when it went on that mode. How do I make it so it starts "updating" automatically.
Sooo I am talking about this part mostly (and other exactly like it)

        if (whichPlant == 2) {
          lcd.setRGB(plant3R, plant3G, plant3B);
          lcd.clear();
           lcd.display();
          lcd.print("Orchid");// print the results to the LCD Display:
          sensorValue = analogRead(waterSensorPin);// read the analog in value:
          sensorValue = map(sensorValue, 0, 750, 0, 100);
          lcd.setCursor(0, 1);
          lcd.print(sensorValue);
          lcd.print("% Enough water");
          Serial.println(sensorValue);
        }

And here is my entire code if you're interested

    #include <Servo.h>

    #include <Wire.h>
    #include "rgb_lcd.h"
    rgb_lcd lcd;

    const int numberOfPlants = 4;
    const int noPlant = -1;  // index meaning no plant is being monitored

    const int plant1R = 0;
    const int plant1G = 0;
    const int plant1B = 255;
    const int zeroR = 0;
    const int zeroG = 0;
    const int zeroB = 0;
    const int plant2R = 0;
    const int plant2G = 255;
    const int plant2B = 0;
    const int plant3R = 255;
    const int plant3G = 0;
    const int plant3B = 0;
    const int plant4R = 255;
    const int plant4G = 0;
    const int plant4B = 255;

    // Pinout.
    const int waterSensorPin = A1;
    const int buttonPin = 2;
    const int servoPin = 5;
    const int ledPins[numberOfPlants] = {12, 11, 10, 9};

    // Moisture ranges for the different plants.
    const int moistureMinima[numberOfPlants] = {  0,   0,   0,   0};
    const int moistureMaxima[numberOfPlants] = {195, 682, 750, 950};

    // Servo holding the indicator needle.
    Servo indicator;
    int sensorValue = 0; // value read from the Soil Moisture
    void setup() {
      lcd.begin(16, 2);
      Serial.begin(9600);
      pinMode(waterSensorPin, INPUT);
      pinMode(buttonPin, INPUT);
      for (int ledNo = 0; ledNo < numberOfPlants; ledNo++) {
        pinMode(ledPins[ledNo], OUTPUT);
      }
      indicator.attach(servoPin);
    }

    void loop() {
      // Which plant are we currently monitoring?
      static int whichPlant = noPlant;
      // Switch to next plant on button press.
      if (digitalRead(buttonPin) == HIGH) {
        if (whichPlant != noPlant) {
          digitalWrite(ledPins[whichPlant], LOW);  // turn off previous LED
        }
        ++whichPlant;
        if (whichPlant == numberOfPlants) {
          whichPlant = noPlant;
        } else {
          digitalWrite(ledPins[whichPlant], HIGH);  // turn on current LED
        }
        if (whichPlant == 3) {

          digitalWrite(10, HIGH);  // turn off previous LED
          digitalWrite(12, HIGH);  // turn off previous LED
          lcd.setRGB(plant4R, plant4G, plant4B);
          lcd.clear();
           lcd.display();
          lcd.print("Swamp Plant");// print the results to the LCD Display:
          sensorValue = analogRead(waterSensorPin);// read the analog in value:
          sensorValue = map(sensorValue, 0, 950, 0, 100);
          lcd.setCursor(0, 1);
          lcd.print(sensorValue);
          lcd.print("% Enough water");
          Serial.println(sensorValue);
          delay(500);  // crude debouncing
        }
        if (whichPlant == 2) {
          lcd.setRGB(plant3R, plant3G, plant3B);
          lcd.clear();
           lcd.display();
          lcd.print("Orchid");// print the results to the LCD Display:
          sensorValue = analogRead(waterSensorPin);// read the analog in value:
          sensorValue = map(sensorValue, 0, 750, 0, 100);
          lcd.setCursor(0, 1);
          lcd.print(sensorValue);
          lcd.print("% Enough water");
          Serial.println(sensorValue);
        }
        if (whichPlant == 1) {
          lcd.setRGB(plant2R, plant2G, plant2B);
         lcd.clear();
          lcd.display();
          lcd.print("Sunflower");// print the results to the LCD Display:
          sensorValue = analogRead(waterSensorPin);// read the analog in value:
          sensorValue = map(sensorValue, 0, 682, 0, 100);
          lcd.setCursor(0, 1);
          lcd.print(sensorValue);
          lcd.print("% Enough water");
          Serial.println(sensorValue);
        }
        if (whichPlant == 0) {
          lcd.setRGB(plant1R, plant1G, plant1B);
         lcd.clear();
          lcd.display();
          lcd.print("Orchid");// print the results to the LCD Display:
          sensorValue = analogRead(waterSensorPin);// read the analog in value:
          sensorValue = map(sensorValue, 0, 195, 0, 100);
          lcd.setCursor(0, 1);
          lcd.print(sensorValue);
          lcd.print("% Enough water");
          Serial.println(sensorValue);
        }

      }
      if (whichPlant == noPlant) {
        digitalWrite(10, LOW);  // turn off previous LED
        digitalWrite(12, LOW);  // turn off previous LED
        lcd.clear();
        lcd.noDisplay();
        lcd.setRGB(zeroR, zeroG, zeroB);

      }
      // Report the moisture level of this plant.
      if (whichPlant != noPlant) {
        int sensorValue = analogRead(waterSensorPin);
        int position = map(sensorValue,
                           moistureMinima[whichPlant], moistureMaxima[whichPlant], 180, 0);
        indicator.write(constrain(position, 0, 180));
        Serial.println(sensorValue);
        delay(500);

      }
      // added 14-02 to make sure servo pointer goes back to start after reading last reading from waterSensor
      if (whichPlant == noPlant) {
        int sensorValue = analogRead(waterSensorPin);
        int position = map(sensorValue,
                           moistureMinima[whichPlant], moistureMaxima[whichPlant], 180, 0);
        indicator.write(constrain(position, 180, 180));
        delay(500);

      }

      //gemaakt door Sinan van Noppen
    }

and if you have any suggestions or you have a go on making my code better, more DRY I would be honoured and appreciate it :)

**EDIT:** (just changed the place of the if whcihplant == 3 etc.)

    #include <Servo.h>

    #include <Wire.h>
    #include "rgb_lcd.h"
    rgb_lcd lcd;

    const int numberOfPlants = 4;
    const int noPlant = -1;  // index meaning no plant is being monitored

    const int plant1R = 0;
    const int plant1G = 0;
    const int plant1B = 255;
    const int zeroR = 0;
    const int zeroG = 0;
    const int zeroB = 0;
    const int plant2R = 0;
    const int plant2G = 255;
    const int plant2B = 0;
    const int plant3R = 255;
    const int plant3G = 0;
    const int plant3B = 0;
    const int plant4R = 255;
    const int plant4G = 0;
    const int plant4B = 255;

    // Pinout.
    const int waterSensorPin = A1;
    const int buttonPin = 2;
    const int servoPin = 5;
    const int ledPins[numberOfPlants] = {12, 11, 10, 9};

    // Moisture ranges for the different plants.
    const int moistureMinima[numberOfPlants] = {  0,   0,   0,   0};
    const int moistureMaxima[numberOfPlants] = {195, 682, 750, 950};

    // Servo holding the indicator needle.
    Servo indicator;
    int sensorValue = 0; // value read from the Soil Moisture
    void setup() {
      lcd.begin(16, 2);
      Serial.begin(9600);
      pinMode(waterSensorPin, INPUT);
      pinMode(buttonPin, INPUT);
      for (int ledNo = 0; ledNo < numberOfPlants; ledNo++) {
        pinMode(ledPins[ledNo], OUTPUT);
      }
      indicator.attach(servoPin);
    }

    void loop() {
      // Which plant are we currently monitoring?
      static int whichPlant = noPlant;
      sensorValue = analogRead(waterSensorPin);// read the analog in value:

      // Switch to next plant on button press.
      if (digitalRead(buttonPin) == HIGH) {
        if (whichPlant != noPlant) {
          digitalWrite(ledPins[whichPlant], LOW);  // turn off previous LED
        }
        ++whichPlant;
        if (whichPlant == numberOfPlants) {
          whichPlant = noPlant;
        } else {
          digitalWrite(ledPins[whichPlant], HIGH);  // turn on current LED
        }

      }
      if (whichPlant == noPlant) {
        digitalWrite(10, LOW);  // turn off previous LED
        digitalWrite(12, LOW);  // turn off previous LED
        lcd.clear();
        lcd.noDisplay();
        lcd.setRGB(zeroR, zeroG, zeroB);

      }
        if (whichPlant == 3) {

          digitalWrite(10, HIGH);  // turn off previous LED
          digitalWrite(12, HIGH);  // turn off previous LED
          lcd.setRGB(plant4R, plant4G, plant4B);
          lcd.clear();
          lcd.display();
          lcd.print("Swamp Plant");// print the results to the LCD Display:
          sensorValue = map(sensorValue, 0, 950, 0, 100);
          lcd.setCursor(0, 1);
          lcd.print(sensorValue);
          lcd.print("% Enough water");
          Serial.println(sensorValue);
          delay(500);  // crude debouncing
        }
        if (whichPlant == 2) {
          lcd.setRGB(plant3R, plant3G, plant3B);
          lcd.clear();
          lcd.display();
          lcd.print("Orchid");// print the results to the LCD Display:
          sensorValue = map(sensorValue, 0, 750, 0, 100);
          lcd.setCursor(0, 1);
          lcd.print(sensorValue);
          lcd.print("% Enough water");
          Serial.println(sensorValue);
        }
        if (whichPlant == 1) {
          lcd.setRGB(plant2R, plant2G, plant2B);
          lcd.clear();
          lcd.display();
          lcd.print("Sunflower");// print the results to the LCD Display:
          sensorValue = map(sensorValue, 0, 682, 0, 100);
          lcd.setCursor(0, 1);
          lcd.print(sensorValue);
          lcd.print("% Enough water");
          Serial.println(sensorValue);
        }
        if (whichPlant == 0) {
          lcd.setRGB(plant1R, plant1G, plant1B);
          lcd.clear();
          lcd.display();
          lcd.print("Cactus");// print the results to the LCD Display:
          sensorValue = map(sensorValue, 0, 195, 0, 100);
          lcd.setCursor(0, 1);
          lcd.print(sensorValue);
          lcd.print("% Enough water");
          Serial.println(sensorValue);
        }

      // Report the moisture level of this plant.
      if (whichPlant != noPlant) {
        int sensorValue = analogRead(waterSensorPin);
        int position = map(sensorValue,
                           moistureMinima[whichPlant], moistureMaxima[whichPlant], 180, 0);
        indicator.write(constrain(position, 0, 180));
        Serial.println(sensorValue);
        delay(500);

      }
      // added 14-02 to make sure servo pointer goes back to start after reading last reading from waterSensor
      if (whichPlant == noPlant) {
        int sensorValue = analogRead(waterSensorPin);
        int position = map(sensorValue,
                           moistureMinima[whichPlant], moistureMaxima[whichPlant], 180, 0);
        indicator.write(constrain(position, 180, 180));
        delay(500);

      }

      //gemaakt door Sinan van Noppen
    }

title: How to get my LCD contentiously updating with data from sensor?

Answers: 0


body:
I'm sure I'm doing something stupid here, but the code below is supposed to write the test hex values to a I2C EEPROM, however when I attempt to read the EEPROM it has the wrong values.  Directly calling something like Wire.write(0xab) will write the 0xab as expected, so I know the EEPROM is being written to properly, just something seems to be getting lost in translation when writing test[counter++]
.
```
#include <Wire.h>

const byte test[] PROGMEM = {
  0x80, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x80,
  0x7f, 0x7f, 0x81, 0x7f, 0x7e, 0x81, 0x80, 0x7f, 0x7f, 0x7f, 0x80, 0x7e,
  0x7e, 0x81, 0x7e, 0x7c, 0x7f, 0x7f, 0x7d, 0x7c, 0x7f, 0x7f, 0x80, 0x7e
};

unsigned int test_len = 36;

#define EEPROM_ADR 0x50

void setup()
{
  Wire.begin();

  int counter = 0;

  Wire.beginTransmission(EEPROM_ADR);

  Wire.write((int)(0x0 >> 8)); //msb
  Wire.write((int)(0x0 & 0xFF)); //lsb

  while (counter < test_len)
  {
    Wire.write(test[counter++]); //using page buffering to write the entire array
  }

  Wire.endTransmission();
}
```

The results look something like: 0x00 0x00 0x08 0x00 0x00 0x00 0x01 etc..

title: Reading PROGMEM results in an incorrect hex value

Answers: 1

body: I needed to either remove PROGMEM from the array or use pgm_read_byte to read the array.


body:
This may be a dumb question but i would like to know what this part is. Anyone who knows?[![enter image description here][1]][1]

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

title: Part identification

Answers: 1

body:
This looks like something out of an Arduino n-part “sensor kit”. It’s hard to tell because the quality of the image is not very good.

My guess is, this is an analog temperature sensor, like [in this link](https://www.instructables.com/id/Arduino-37-in-1-Sensors-Kit-Explained/), part number 18. You can also find an example sketch there.


body:
In part of a code used with UNO, I want to send number A and number B at once as A,B to the Arduino board if there is carriage return. So at the moment in HyperTerminal when I type: 100,0.5 the Arduino board immediately reacts x becomes 100 and n becomes 0.5. Following parts are related to reading with serial event:

    void loop() {

          if (stringComplete){

          delay(1000);
          Mwrite(level);
          sendFrequency(n);
          delay(100);

          stringComplete = false;

       }
    }

and in serial event:

    void serialEvent() {

         while (Serial.available()) {

         slevel  = Serial.readStringUntil(',');
         Serial.read(); //next character is comma, so skip it using this
         x = Serial.readStringUntil(',');

         level = slevel.toInt();
         n = x.toDouble();
         stringComplete = true;
      }
    }

But what I want to do is, I want the board only read the serial data only if I hit carriage return. So I should type 100,1 and then I should also hit carriage return for Arduino to react to the serial data.

How can this code be modified to achieve that?

title: How to modify this code to use serial event to act after carriage return?

Answers: 1

body:
There are multiple ways you can solve it. The easiest way to do it is by just adding one more line in your code.

    static bool stringComplete = false;
    String x;
    String slevel;
    static int level;
    static int n;

    void setup()
    {
      Serial.begin(9600);
    }

    void loop()
    {
      if (stringComplete)
      {
        Serial.println(level);
        Serial.println(n);
        stringComplete = false;
      }
    }

    void serialEvent()
    {
      while(Serial.available())
      {
        slevel  = Serial.readStringUntil(',');

        //Serial.read(); // <-- You don't need this line. readStringUntil() will read ','

        x = Serial.readStringUntil(',');

        level = slevel.toInt();
        n = x.toDouble();
        Serial.readStringUntil('\r'); // <--------- Add this line
        stringComplete = true;
      }
    }

But this is not probably the right way to do it. First, ***serialEvent()*** executes in between ***loop()*** i.e. this is what it looks like:

    while(1)
    {
        loop();
        serialEvent();
    }

So, it is not like that the function will get called during a serial event. It just gets executed right after ***loop()***. Also ***readStringUntil()*** has a timeout (default: 1s). So if your 'until' character doesn't show up within one second of the function call, it will return with whatever it has. To test this, just type one character on your HyperTerminal and wait at least for a second, and see the output.<br>

Ideally, this is how you should handle the serial's incoming byte:

 - Check if there is serial byte available to read
 - If there is, read one byte and save it in a buffer/string. (I'm not really a fan of **String** variables, but in the example, I will use String because you were using a **String**)
 - If the byte you just read is delimiter (e.g. CR or '\r'), indicate the main loop that string is complete.
 - In the main loop parse the whole string.

So this is how the code looks like with above-mentioned points:

    static bool stringComplete = false;
    String x;
    String slevel;
    static int level;
    static int n;
    String rxString = "";

    void setup()
    {
      Serial.begin(9600);
    }

    void loop()
    {
      if (stringComplete)
      {
        // Parse the rxString
        int index1 = rxString.indexOf(',');             // finds location of first ,
        slevel = rxString.substring(0, index1);         // captures first data String
        int index2 = rxString.indexOf(',', index1 + 1); //finds location of second ,
        x = rxString.substring(index1 + 1, index2);     //captures second data String

        level = slevel.toInt();
        n = x.toDouble();

        Serial.println(level);
        Serial.println(n);

        // Reset the string
        rxString = "";
        stringComplete = false;
      }
    }

    void serialEvent()
    {
      while(Serial.available())
      {
        // get the new byte:
        char inChar = (char)Serial.read();
        // add it to the rxString:
        rxString += inChar;
        // if the incoming character is a carriage return, indicate main loop
        if (inChar == '\r')
        {
          stringComplete = true;
        }
      }
    }


body:
I saw some projects with DHT11, some connect it with analog pin, others connect with digital pin.

Is there any difference / advantage connecting to the analog?

title: DHT11 analog or digital?

Answers: 1

body:
The DHT11 is a digital component with its own digital communication protocol.

Analog pins can be used for either analog input *or* digital input and output.

You can use a digital device like the DHT11 on *any* pin, whether it is labelled analog or digital (except on a couple of boards which have a few analog-only pins).


body:
I am trying get the rotation value from MPU6050. I am using an Arduino Uno board.

My connections are:

    MPU6050  Arduino

    VCC    ->  5V
    GND    ->  GND
    SCL    ->  A5
    SDA    ->  A4
    INT    ->  2

The code I am using is:

    #include <MPU6050_tockn.h>

    #include <Wire.h>

    MPU6050 mpu6050(Wire);

    void setup() {

      Serial.begin(9600);

      Wire.begin();

      mpu6050.begin();

      mpu6050.calcGyroOffsets(true);

    }

    void loop() {

      mpu6050.update();

      Serial.print("angleX : ");

      Serial.print(mpu6050.getAngleX());

      Serial.print("\tangleY : ");

      Serial.print(mpu6050.getAngleY());

      Serial.print("\tangleZ : ");

      Serial.println(mpu6050.getAngleZ());

      delay(4000);

    }

On my serial monitor I am always getting -35.26, 35.26, -0.0 values. What should I do?

title: MPU6050 stuck on same values while getting the angle as output

Answers: 0


body:
The following blink program runs fine on my Attiny85 SparkFun Tiny AVR programmer board. It produces 5 short blinks and then stops.

It also works fine when I change r16 to any one of the registers r17, r21 or r29. But trying with any other register gives either no blink at all (r19, r20, r23, r25, r26, r27, r28, r31) or indefinite blinks (r18, r22, r24, r30).

Can anyone explain?

    int ledPin = 0;

    void setup() {

      pinMode(ledPin, OUTPUT);

      asm("ldi r16, 5");
      asm("blink:");
      digitalWrite(ledPin, HIGH);
      delay(500);
      digitalWrite(ledPin, LOW);
      delay(500);
      asm("dec r16");
      asm("brge blink");
    }

    void loop() {
    }

title: Why does my ATtiny85 blink program only work with 4 out of the 16 registers?

Answers: 2

body: Solved it myself! The high-level command "delay(500)" destroys the register contents. Saving the register (using push/pop) while doing delay() solves this issue. (Btw, is should be "brpl" and not "brge".)

body:
As you discovered, calling a function may clobber some registers. To be precise, the [avr-gcc documentation][1] says:

> Call-Used Registers
>
> The call-used or call-clobbered general purpose registers (GPRs) are registers that might be destroyed (clobbered) by a function call.
>
> R18–R27, R30, R31
> These GPRs are call clobbered. An ordinary function may use them without restoring the contents. Interrupt service routines (ISRs) must save and restore each register they use.
>
> Call-Saved Registers
>
> R2–R17, R28, R29
> The remaining GPRs are call-saved, i.e. a function that uses such a registers must restore its original content. This applies even if the register is used to pass a function argument.

Now, an interesting detail here is that according to the documentation, one would expect R28 to work. Maybe that's not clobbered by the called procedure, but by your local procedure (mixing assembly and C in nontrivial amounts is a difficult
task for precisely this reason).

  [1]: https://gcc.gnu.org/wiki/avr-gcc#Call-Used_Registers


body:
In my project i have a function which i only need to execute if the current time is between given 2 times. Note that the time is fetched from RTC so its 24hr. For example if current time is 23:00,start time is 20:00 and end time is 5:00 the function must execute and not execute otherwise.
```
if((fromhour>=now.hour() && fromminute>=now.minute()) || (tohour>=now.hour() && tominute>=now.minute()))
{
     //Call function
}
```
I tried this code but not working as expected. please give a solution for this problem.

title: I need to happen a process between 2 given times in Arduino

Answers: 0


body:
```
#include <ESP8266WiFi.h>
#include <FirebaseArduino.h>

//Firebase settings
#define FIREBASE_HOST "..........firebaseio.com/"     //cant share
#define FIREBASE_AUTH "..............."               //cant share

//Wi-Fi settings
#define WIFI_SSID "kello"
#define WIFI_PASSWORD "8888"

//Define trigger and echo digital pins
const int trigPin = 4;
const int echoPin = 3;

// The amount of time the ultrassonic wave will be travelling for
long duration = 0;
// Define the distance variable
double distance = 0;

void setup()
{
     Serial.begin(9600);
    // Connect to Wi-Fi
    Serial.print("Wi-Fi...");
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    Serial.print("Connecting...");
    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.print(".");
        delay(500);
    }
    Serial.println();
    Serial.print("Connected to: ");
    Serial.println(WiFi.localIP());

    Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);

    // Ultrasonic sensor, set echo as Input and trigger as Output
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);

}

void loop()
{

    getDistance();
    // Prints the distance value to the serial monitor
    Serial.print("Distance: ");
    Serial.println(distance);

    delay(500);
}

void getDistance()
{
    // Clear trigPin
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);

    // trigPin HIGH por 10ms
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    //Reads echoPin, returns the travel time of the sound wave in ms
    duration = pulseIn(echoPin, HIGH);

    // Calculating the distance, in centimeters, using the formula described in the first section.
    distance = duration * 0.034 / 2;

    // Sends the distance value to Firebase
    Firebase.setFloat("distance", distance);

}
```
I am a computer graduate so i do not have much knowledge about nodemcu. I saw some documentations about nodemcu. I want to show the data obtained by the ultrasonic distance sensor in the realtime database of firebase. But i am not able to figure out why i am not able to get output of **serial.println(distance)** in the com5 window even though the code compiles successfully .
This is what i get when running the program
```
Executable segment sizes:

IROM   : 330560          - code in flash         (default or ICACHE_FLASH_ATTR)

IRAM   : 27760   / 32768 - code in IRAM          (ICACHE_RAM_ATTR, ISRs...)

DATA   : 1408  )         - initialized variables (global, static) in RAM/HEAP

RODATA : 2044  ) / 81920 - constants             (global, static) in RAM/HEAP

BSS    : 25160 )         - zeroed variables      (global, static) in RAM/HEAP

Sketch uses 361772 bytes (34%) of program storage space. Maximum is 1044464 bytes.
Global variables use 28612 bytes (34%) of dynamic memory, leaving 53308 bytes for local variables. Maximum is 81920 bytes.
esptool.py v2.8
Serial port COM5
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: ec:fa:bc:c1:44:d2
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 365920 bytes to 264395...

Writing at 0x00000000... (5 %)
Writing at 0x00004000... (11 %)
Writing at 0x00008000... (17 %)
Writing at 0x0000c000... (23 %)
Writing at 0x00010000... (29 %)
Writing at 0x00014000... (35 %)
Writing at 0x00018000... (41 %)
Writing at 0x0001c000... (47 %)
Writing at 0x00020000... (52 %)
Writing at 0x00024000... (58 %)
Writing at 0x00028000... (64 %)
Writing at 0x0002c000... (70 %)
Writing at 0x00030000... (76 %)
Writing at 0x00034000... (82 %)
Writing at 0x00038000... (88 %)
Writing at 0x0003c000... (94 %)
Writing at 0x00040000... (100 %)
Wrote 365920 bytes (264395 compressed) at 0x00000000 in 23.4 seconds (effective 125.3 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
```

[![Here is the serial window after executing][1]][1]

Is the ultrasonic sensor not getting enough power supply as nodemcu is connected to my laptop?
Please help me out and let me know if more information is required.

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

title: not able to figure out what is wrong with my nodemcu code

Answers: 1

body:
Your `echoPin` Is defined as `3`. GPIO3 of the NodeMCU is also the “RX” pin needed for serial communication to the host. This might explain why you don’t see any output. You should change it to a different pin (for example pin 5 / D1 is a safe choice).

Each pin on the NodeMCU has a “GPIO” number (which is just the pin number as defined by the ESP8266 architecture) and a corresponding “Dx” designation (which is usually marked on the NodeMCU board).

Which GPIO pin corresponds to which which “D” pin is shown in pinout diagrams, like the one [here](https://randomnerdtutorials.com/esp8266-pinout-reference-gpios/). Scroll to the NodeMCU 12-E pinout.

Some of the safest pins to use are:

 - Pin 5 (D1)
 - Pin 4 (D2)
 - Pin 12 (D6)
 - Pin 13 (D7)
 - Pin 14 (D5)

Some of the other pins could also be used, but have some restrictions, as you can see on the page I linked to.

Note that pins 12-14 are used for SPI and pins 4 and 5 are (normally) used for (software) I2C. If you want to control hardware that uses these protocols, these are the default pins it uses.


body:
I have recently purchased an Arduino Nano 33 IOT together with two sensors:

 - Adafruit SHT31-D (https://learn.adafruit.com/adafruit-sht31-d-temperature-and-humidity-sensor-breakout)
 - Adafruit SGP30 (https://learn.adafruit.com/adafruit-sgp30-gas-tvoc-eco2-mox-sensor/)

However, so far I have not succeeded in reaching any of these two sensors. For example I connect the SHT31 sensor like this:

 - +3.3V to Vin
 - GND to GND
 - A4 to SDA
 - A5 to SCL

I have tried the default Adafruit  SHT31-D example without success, the program appears to hang. I have tried a standard I2C scanner but it does not find any devices with the sensor connected. When the sensor is disconnected, it does find two devices (the IMU and something else I guess).

I believe there is something funky going on with the I2C connection of the internal sensors and the external ones but I have no idea how to troubleshoot this issue. I read some stuff about TwoWire (extern TwoWire Wire1; after the #include) but I am having a hard time figuring out if this is what I need and how to implement it.

I found these topics myself:

https://forum.arduino.cc/index.php?topic=639188.0

https://forum.arduino.cc/index.php?topic=658967.0

edit: I haven't had success dealing with these issues so far and I am still looking for some help with my problems!

title: Unable to find/connect I2C devices (SHT31 & SGP30)

Answers: 3

body:
one can code an I2C sensor (I'm using a SHT31) using custom GPIO ports like so:

    //I2C Bus Pins
    #define SDA 8
    #define SCL 9

    #include "Adafruit_SHT31.h"
    TwoWire I2Cbus = TwoWire(0);
    Adafruit_SHT31 sht31 = Adafruit_SHT31(&I2Cbus);

    void setup(){
      Serial.begin(115200);            // USB communication with Serial Monitor
      Serial.print("Starting serial...");

      Serial.print("Starting SHT31...");
      startSHT();
    }

     // ********************************************************
     void startSHT(){
      I2Cbus.begin(SDA, SCL, 100000ul);
      if (! sht31.begin(0x44)) { // Set to 0x45 for alternate i2c addr
         Serial.println("Couldn't find SHT31");
    while (1)
    delay(1);
      }
    }

body:
I had a similar problem, but the fix turned out to be simple. All the tutorials for SHT3x sensors say to connect the VIN to the 3.3V GPIO. I checked using a test meter, the SHT3x was getting voltage but numerous SH3x libraries didn't seem to work, and a couple of I2C sketches also found nothing. So I tried moving the VIN lead to the 5V GPIO pin - it works perfectly. Perhaps my USB connection lacks enough power, or perhaps my SHT3x needs 5V. Either way it
works - happy now !

body: Without a schematic I will take a SWAG" For I2C to work it needs a pull up resistor for SCL another for SDA. Both are open drain/collector outputs neither of which can drive a + (logic 1) on the bus.


body:
I am using ESP32....the max Pwm signal of it is 3.3V...And I have to control two motors speed by TB6612FNG motor driver...when i was using Arduino.. The arduino can send max 5V Pwm signal to the motor drivers PWM pin.. And the motor runs at the exact speed...but now i have to use ESP32..which sends 3.3V and the motors slow down..

So what should I do to convert the ESP32's PWM signal to 5v and according If i change the PWM value at the program..the output will also change similarly as Arduino??
Please help me

title: Converting the 3.3V PWM signal to 5V PWM signal

Answers: 1

body:
Looking at [TB6612FNG][1] datasheet i read

> Logic supply voltage (VCC) can be in the range of 2.7--5.5VDC

So, if you supply 3.3V to VCC all should be ok, if the motors themselves get enough power (via VM)

  [1]: https://www.sparkfun.com/products/14451


body:
I'm Trying to control a pin "D1" from HTTP API everything was working fine but when i'm going to change the data from server it's done on the server but on device it's takes so long time almost 20 minutes i also checked the Serial Monitor the data is not updating please help me.

My Device: Node MCU V3,

Here is my code:

```
/**
   BasicHTTPClient.ino

    Created on: 24.05.2015

*/

#include <Arduino.h>

#include <Arduino_JSON.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#include <ESP8266HTTPClient.h>

#include <WiFiClient.h>

ESP8266WiFiMulti WiFiMulti;

void setup() {

  Serial.begin(115200);
  // Serial.setDebugOutput(true);

  Serial.println();
  Serial.println();
  Serial.println();

  pinMode(D1, OUTPUT);

  for (uint8_t t = 4; t > 0; t--) {
    Serial.printf("[SETUP] WAIT %d...\n", t);
    Serial.flush();
    delay(1000);
  }

  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP("Maruf Hasan", "marufhasan");

}

void loop() {
  // wait for WiFi connection
  if ((WiFiMulti.run() == WL_CONNECTED)) {

    WiFiClient client;

    HTTPClient http;

    Serial.print("[HTTP] begin...\n");
    if (http.begin(client, "http://marufhasan.net/api/test.txt")) {  // HTTP

      Serial.print("[HTTP] GET...\n");
      // start connection and send HTTP header
      int httpCode = http.GET();

      // httpCode will be negative on error
      if (httpCode > 0) {
        // HTTP header has been send and Server response header has been handled
        Serial.printf("[HTTP] GET... code: %d\n", httpCode);

        // file found at server
        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          String response = http.getString();
          //Converting response object;
          Serial.println(response);
          JSONVar myObject = JSON.parse(response);

          if (JSON.typeof(myObject) == "undefined") {
            Serial.println("Parsing input failed!");
          }else{
            if (myObject.hasOwnProperty("status")) {
              String status = (const char*) myObject["status"];

              if(status=="on"){
                    Serial.println("ON");
                    digitalWrite(D1, HIGH);
              }else{
                    Serial.println("OFF");
                    digitalWrite(D1, LOW);
              }

            }
          }
        }
      } else {
        Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
      }

      http.end();
    } else {
      Serial.printf("[HTTP} Unable to connect\n");
    }
  }

  delay(5000);
}
```

title: ESP 8266 HTTP Client Data is not changing correctly

Answers: 0


body:
I want to make the PIRs to stay on for about 1 minute. I've found the code that can do so for 1 PIR, but I dont know how to apply the code for 3 PIRs.

Here is the code for 1 PIR with timer using `millis`:

    int ledPin = 8;
    int pirPin = 3;

    unsigned long piron;
    //the time we give the sensor to calibrate (10-60 secs according to the datasheet)
    int calibrationTime = 10;

    int off;
    int on;
    const int LDR = A0;
    int ldrStatus;

    unsigned long currentMillis =( millis()/1000 ) / 60;

    /////////////////////////////
    //SETUP
    void setup(){
      Serial.begin(9600);
      pinMode(pirPin, INPUT);
      pinMode(ledPin, OUTPUT);
      digitalWrite(pirPin, LOW);

      //give the sensor some time to calibrate
      Serial.print("calibrating sensor ");
        for(int i = 0; i < calibrationTime; i++){
          Serial.print(".");
          delay(1000);
          }
        Serial.println(" done");
        Serial.println("SENSOR ACTIVE");
        delay(50);
      }

    ////////////////////////////
    //LOOP
    void loop()

    {
    ldrStatus = analogRead (LDR);
    if (ldrStatus <= 700)     // variable reading(ldrStatus) according to ldr
                              // the higher reading(ldrStatus), the dimmer light
                              // the lower the reading(ldrStatus), the brighter light

    {
    analogRead (pirPin) == off;

    Serial.println ("Its SUNNY DAY !!!");
    digitalWrite(ledPin, LOW);

    }

    if (ldrStatus >= 700)
    {
    Serial.println ("Its DARK already");

        if(digitalRead(pirPin) == HIGH){
           digitalWrite (ledPin, HIGH);
         piron = ( millis()/1000 ) / 60;
      }

      if ((currentMillis - piron) > 1) {
        digitalWrite(ledPin, LOW);

      }

        }
    }
    `

    and here is the code for 3 PIRs without the timer

        int calibrationTime = 10;

    int pirPin = 3;
    int ledPin = 8;

    int pirPin1 = 4;
    int ledPin1 = 9;

    int pirPin2 = 5;
    int ledPin2 = 10;

    int ledPin3 = 11;

    int off;
    int on;
    const int LDR = A0;
    int ldrStatus;

    /////////////////////////////
    //SETUP
    void setup(){
      Serial.begin(9600);
      pinMode(pirPin, INPUT);
      pinMode(ledPin, OUTPUT);
      digitalWrite(pirPin, LOW);

       pinMode(pirPin1, INPUT);
      pinMode(ledPin1, OUTPUT);
      digitalWrite(pirPin1, LOW);

       pinMode(pirPin2, INPUT);
      pinMode(ledPin2, OUTPUT);
      digitalWrite(pirPin2, LOW);

     pinMode (ledPin3, OUTPUT);

      //give the sensor some time to calibrate
      Serial.print("calibrating sensor ");
        for(int i = 0; i < calibrationTime; i++){
          Serial.print(".");
          delay(1000);
          }
        Serial.println(" done");
        Serial.println("SENSOR ACTIVE");
        delay(50);
      }

    ////////////////////////////
    //LOOP
    void loop()
    {
    ldrStatus = analogRead (LDR);
    if (ldrStatus <= 700)     // variable reading(ldrStatus) according to ldr
                              // the higher reading(ldrStatus), the dimmer light
                              // the lower the reading(ldrStatus), the brighter light

    {
    analogRead (pirPin) == off;
    analogRead (pirPin1) == off;
    analogRead (pirPin2) == off;
    Serial.println ("Its SUNNY DAY !!!");
    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, LOW);
    digitalWrite(ledPin3, LOW);
    }

    if (ldrStatus >= 700)
    {
    Serial.println ("Its DARK already");
    digitalWrite(ledPin3, HIGH);

        if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == LOW){
          digitalWrite (ledPin, HIGH);
          digitalWrite(ledPin1, LOW);
          digitalWrite(ledPin2,LOW);
        }

        if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == LOW){
          digitalWrite (ledPin1, HIGH);
          digitalWrite (ledPin, LOW);
          digitalWrite(ledPin2,LOW);

    }
       if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == HIGH){
          digitalWrite (ledPin2, HIGH);
          digitalWrite (ledPin1, LOW);
          digitalWrite (ledPin, LOW);

       }

         if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == LOW){
        digitalWrite (ledPin1, HIGH);
        digitalWrite (ledPin, HIGH);
        digitalWrite (ledPin2, LOW);

    }

         if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == HIGH){
          digitalWrite (ledPin, HIGH);
          digitalWrite (ledPin2, HIGH);
          digitalWrite (ledPin1, LOW);
         }

         if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == HIGH){
         digitalWrite (ledPin2, HIGH);
         digitalWrite (ledPin1, HIGH);
         digitalWrite (ledPin, LOW);
         }

        if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == HIGH){
          digitalWrite (ledPin2, HIGH);
          digitalWrite (ledPin1, HIGH);
          digitalWrite (ledPin, HIGH);

        }

         if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == LOW){
          digitalWrite (ledPin2, LOW);
          digitalWrite (ledPin1, LOW);
          digitalWrite (ledPin, LOW);
         }

    }

    }

title: How do I put timers by using millis on 3 PIR sensors?

Answers: 1

body:
This is not a complete answer, but an idea of how to accomplish the task.

I just typed it in without testing the code.

Use arrays to hold variables. That way a loop can be used to service the three sensors and the three LEDs..

    for (i = 0; i<3; i++) {
       currentTime = millis();                             // save current millis() value

       if (digitalRead(pirPin[i]) == HIGH) {               // check if PIR is detecting motion
          trigTime[i] = millis();                          // save trigger time
          trig[i]     = true;                              // set a state variable that indicates
       }                                                   //   that a trigger happened

       if (trig[i]) {                                      // if trigger happened
          if (currentTime - trigTime[i] < 50000) {         // is it less than 50 sec since last motion?
             digitalWrite (ledPin[i], HIGH);
          }
          else {
             trig[i] = false;                              // 50 second timer ran out
             digitalWrite (ledPin[i], LOW);
          }
       }
    }


body:
I have spent a little over 2 hours trying to debug this code. All I did was combine a section of code to write to the SD card. Both of the codes work fine on their own. I can't figure this one out. I am hoping fresh eyes can spot the error. I am using a Arduino Nano with a Robot-Deek data logger board. Pin 10 is used for the data logger. I was using a DTH11 but switched to a LM35, both codes worked with LM35.
```
#include "RTClib.h"
#include <SD.h>
#include <SPI.h>
#define sample 500
#define current_ms millis()
RTC_DS1307 rtc;
File myFile;
int inPin = 0;   //analog in
float val;       //where to store info from inPin reading
int pinRed = A3;  //output of red led
float tempin = A5;  //input of temp sensor
float tempf;     // variable to hold temp in Fahrenheit
float vout;      // variable to hold voltage from sensor
int array1[sample];  //creates an array with number of elements equal to "sample"
unsigned long averaging;  //the program uses this variable to store the sum of each array it makes
int pinCS = 10;   // write to SD card
float last_dht11_reading_ms = 1;
DateTime now = rtc.now();
#define DHT11_SAMPLE_DELAY 500

void setup() {

  Serial.begin(9600);
  delay(500);//Delay to let system boot
  SD.begin();
  pinMode(pinCS, OUTPUT);
  pinMode(tempin, INPUT);
  Serial.println("Volt and Temperature\n\n");
Serial.println("middle the setup loop");
 // SD Card Initialization
  if (SD.begin())
  {
    Serial.println("SD card is ready to use.");
    File myFile = SD.open("Datalog.csv",FILE_WRITE);
    if (myFile) {
      myFile.println("Time, Temp, Volt");
      myFile.close();
    }
  } else
  {
    Serial.println("SD card initialization failed");
    return;
  }
  rtc.begin();
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}//end "setup()"

void loop() {

  for (int i = 0; i < sample; i++) {         //this code tells the program to fill each element in the array we made with
    array1[i] = analogRead(inPin);           //information from the antenna wire coming out of the Arduino
    averaging += array1[i];                  //more information about for loops http://arduino.cc/en/Reference/For
  }                                          //the averaging line is simply saying: add averaging to whatever is in array position i
                                             //averaging += array[i] is the same as averaging = averaging + array[i]

  val = averaging / sample;                  //here the program takes the sum of all numbers in array1, and divides by the number of elements "sample"
  val = constrain(val, 0, 100);              //this constrains the variable value to between two numbers 0 and 100
  val = map(val, 0, 100, 0, 255);           //for more information about constrain http://arduino.cc/en/Reference/Constrain
  analogWrite(pinRed, val*20);                  //the map statement tells the program to map out 0-100 to 0-255
  averaging = 0;                                 //this line of code sets averaging back to zero so it can be used again
Serial.println("past the emf loop");

  if ( (current_ms - last_dht11_reading_ms) > DHT11_SAMPLE_DELAY ) {
    vout = analogRead(tempin);                //read LM35 output
    float mv = (vout/1024)*5000;              // conversion to mV
    float celc = mv/10;                       // convert to C
    float tempf = ((celc*9)/5 + 32)/10;       // convert to F
    myFile = SD.open("Datalog.csv", FILE_WRITE);      //open datalog file on SD card

  if (myFile) {                              //write to the SD card time, tempf and val
    myFile.print(now.hour());
    myFile.print(":");
    myFile.print(now.minute());
    myFile.print(":");
    myFile.print(now.second());
    myFile.print(",");
    myFile.print(tempf);
    myFile.print(",");
    myFile.println(val);
    myFile.close(); // close the file;    // close the file
    last_dht11_reading_ms = current_ms;
  }
Serial.println("past the logger loop");
  //delay(1000);//Wait 1 seconds before accessing sensor again.

}
}
// end loop()
```

title: Combined code and nothing works. Head scratcher for sure

Answers: 1

body:
```DateTime now = rtc.now();```
Does not belong above void setup()
4hours to troubleshoot this little mistake.


body:
when i execute the python script, the arduino response but the code between the if(Serial.available()) not responding.

python script

     import  time, serial
     arduino = serial.Serial('COM7', 9600)
     time.sleep(2)
     while True:
        arduino.write(str(input("1")))                  # write position to serial port
        # and the pysthon script cant read the code below this line
        reachedPos = str(arduino.readline())            # read serial port for arduino echo
        data.append(reachedPos)
        arduino.close()

arduino script

     #include <Servo.h>
     Servo servo;
     int angle = 0;
     String in;
     int pos = 1;

    void setup() {
     servo.attach(7);
     Serial.begin(9600);
     servo.write(0);

    }

    void loop() {
    if(Serial.available())  // if data available in serial port
    {
    in = Serial.readStringUntil('\n');
    Serial.print(in);
    pos = in.toInt();
      if(pos == 1){
    if(angle == 0){
      servo.write(180);
      delay(10);
      angle = 180;
      delay(1000);
    }

    if(angle == 180){
      servo.write(0);
      delay(10);
      angle = 0;
      delay(1000);
    }}
    }
    }

What is the problem?
Te arduino code works fine

title: serial problem with python to arduino

Answers: 0


body:
i have one code with delay pleas help me remove the delay i will using this code in air cooler with some sensors delay stop working sensors

    void startCycle(int cycleTimeInMinutes, const char *type) {
      lcd.clear();
      const char *topRow[1] = { type };
      printTopRow(topRow, 1, 5);

      cool1(true);

      for (int cycleTimeLeft = cycleTimeInMinutes; cycleTimeLeft > 0; cycleTimeLeft--) {
        char buffer[2];
        const char *bottomRow[3] = { itoa(cycleTimeLeft, buffer, 10), "Minutes"};
        printBottomRow(bottomRow, 3, 6);
        delay(60000);
      }
      cool1(false);
    }

title: arduino cont down timer in minutes with out using delay

Answers: 0


body:
Can someone tell me why "XTronical graphical Pulse and Oxygen monitor Displays"
https://www.xtronical.com/colour-ecg-monitor/
works perfectly on an old Nano or an Uno and doesn't work on the new Nano Every
even with Registers emulation: "ATMEGA328" ?

Is the Nano Every a "BAD BUY" ?

I very much welcome an explanation.
JFT

title: Why this program works on an old Nano and doesn't work on Nano Every

Answers: 0


body:
I have a few pic chips, mainly pic16f72 and pic16f73 on old ups circuits, realized they are not that bad. Their adc capabilities are my point of focus.

I have an esp32 (my first mcu) and i am very disappointed mainly because its adc being crap, I did some research on programming pic chips, some could be programmed via an arduino but my chips were not mentioned anywhere. I wanna program them via my esp32..

Is there a way to program them via arduino (esp32 in my case)? I can build some basic circuits but diy pic programmers require a preprogrammed pic chip which I can't produce if I can't program one already.

title: Programming pic microchip

Answers: 2

body:
It seems, that you are talking about 2 different things:

- The programming/burning of the PIC can be done via an Arduino (so you don't need to build a complex PIC programmer circuit). It is irrelevant, what microcontroller type is on the programmer, as long as the programmer speaks ISP (the programming protocol). So even, when your specific PIC is not mentioned at your found sites, it should work nonetheless. The connections are every time the same, though of your specific PIC the used pin functions might be on other pins (consult the datasheet for this).

- An Arduino project - meaning the sketch/program, that was written for a normal Arduino, is normally not easily reusable. PICs are different microcontrollers with different hardware, so you need to port those projects to your specific microcontroller, which might involve extensive changes. When you have an Arduino Project, that was directly written for your PIC, then you can reuse it. (Be sure to install the correct core for your PIC in the Arduino IDE)

body:
For PIC32 you need [chipKIT](https://chipkit.net).  Not all chips are supported, but most of the PIC32MX and PIC32MZ chips are. Which exact PIC32 chip(s) do you have?

You will need to install a [bootloader](https://github.com/chipKIT32/PIC32-avrdude-bootloader), for which you will need a programmer. It is possible to build a programmer using an Arduino, though TBH I'd just pick up a cheap PICkit2 clone from China.

As for the 8-bit PICs, no, they can't be programmed like an Arduino, simply because there is no open source C++ compiler available.


body:
I've been trying, just out of curiosity, to write my own function that generates a PWM signal, just like `analogWrite()`, and to make it light up an LED. Here's my attempt so far:

    const int pin = 3;
    int cycle = 2; // analogWrite() outputs a 498 Hz signal, so each cycle has approximately 2ms

    int duty = 0.5; // for a 50% duty cycle

    void setup() {
      Serial.begin(9600);
      pinMode(pin,OUTPUT);
    }

    void loop() {
      digitalWrite(pin,HIGH);
      delay(cycle*duty);
      digitalWrite(pin,LOW);
      delay(cycle*(1-duty));
    }

The LED does light up, but very dimly, as shown below:

[![LED brightness with my code][1]][1]

However, when using `analogWrite()` with a 50% duty cycle to achieve the same result, the LED shines much brighter:

[![LED brightness with analogWrite(pin,128)][2]][2]

Is there something wrong with my code, or is there a special reason why more power is dissipated with `analogWrite()`?

  [1]: https://i.stack.imgur.com/ik8e8.jpg
  [2]: https://i.stack.imgur.com/uNb9x.jpg

title: "Manually" generating a PWM signal

Answers: 1

body:
You need to review your code and also the capabilities of the Arduino UNO.

 - `int` declares an integer.  So `int duty = 0.5;` is going to get rounded to either 0 1.
 - `delay(0);` also will not work.  The instruction will simply get skipped. Likely the reason why you get a brighter LED. Try to use `delayMicroseconds();` if you need shorter time but the minimum delay you can have is 4 us for Arduino UNO.
 - If you are using times as short as 2 us, then from the above comment the `delayMicroseconds();` function is not going to be sufficient.  Also, you should consider the loop overhead, which will be a few microseconds.

All in all this is not a great method.  If you do want to create your own PWM signals, it is much better to use the hardware timers.  For example [this tutorial on the Arduino website.][1]  You should also be able to find posts about hardware timers on Arduino SE.

  [1]: https://playground.arduino.cc/Code/Timer1/


body:
As of right now, I'm attempting to build a voice recognition system that will respond to what I say accordingly. I have been scouring as to how to retrieve the signature from the voice recognition module's library.

This is my result:
![Picture taken from the Serial Monitor in Arduino IDE](https://i.stack.imgur.com/XLRQF.jpg)

My arduino code that produced the result is below:
```
#include <SoftwareSerial.h>
#include "VoiceRecognitionV3.h"

VR myVR(2,3);

uint8_t record[7];
uint8_t buf[64];

#define onRecord (0)
#define offRecord (1)

void printSignature (uint8_t *buf, int len) {
  int i;
  for(i = 0; i < len; i++) {
    if(buf[i] > 0x19 && buf[i] < 0x7F) {
      Serial.write(buf[i]);
  } else {
      Serial.print("[");
      Serial.print(buf[i], HEX);
      Serial.print("]");
    }
  }
}

void printVR(uint8_t *buf)
{
  Serial.println("VR Index\tGroup\tRecordNum\tSignature");

  Serial.println(buf[2], DEC);
  Serial.println("\t\t");

  Serial.print(buf[2], DEC);
  Serial.print("\t\t");

  if(buf[0] == 0xFF){
    Serial.print("NONE");
  }
  else if(buf[0]&0x80){
    Serial.print("UG ");
    Serial.print(buf[0]&(~0x80), DEC);
  }
  else{
    Serial.print("SG ");
    Serial.print(buf[0], DEC);
  }
  Serial.print("\t");

  Serial.print(buf[1], DEC);
  Serial.print("\t\t");
  if(buf[3] >0) {
    printSignature(buf+4, buf[3]);
  }
}

void setup() {
  myVR.begin(9600);

  Serial.begin(115200);

  if(myVR.clear() == 0) {
    Serial.println("Recognizer cleared.");
  } else {
    Serial.println("Not find VR Module");
    while(1);
  }

  if(myVR.load((uint8_t)onRecord) >= 0){
    Serial.println("onRecord loaded");
  }

  if(myVR.load((uint8_t)offRecord) >= 0){
    Serial.println("offRecord loaded");
  }
}

void loop() {
  int ret;
  ret = myVR.recognize(buf, 50);

  if(ret > 0) {
    printVR(buf);
  }
}
```

Any suggestions as to how I'd go in retrieving the signature from this module?

Edit: The module have been trained to recognize my speech saying "two" and is assigned
 the signature 'two'.

title: Is there a way to retrieve signature from the Voice Recognition module? (Elechouse Voice Recognition V3.1)\

Answers: 0


body:
I want to send 4 float numbers from Python code to an Arduino; I was trying to send it via serial and I have some problems.

**here is my Python code:**

```python
import time
import serial
import struct

data = serial.Serial('COM6', 9600, timeout=1)
time.sleep(1)

while True:
   a = str(47.256*1000)
   data.write(a.encode())
```

**Here is my Arduino code :**

```c++
String msg;

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop()
{
  if (Serial.available()) {
    msg = Serial.readString();
  }

  if (msg.toInt()>30){
    digitalWrite(13, 1);
  }
}
```
**end of code**

Thanks in advance.

My problem is that it does not work (LED does not turn on while I send data from the Python code in a while loop; when I remove the while and make it send data 1 time it works (LED turns on). Any ideas why this could be happening?

title: Can not receive data from Python code

Answers: 1

body:
It would be easier if you used Arduino <--> Python compatible libraries to ensure the communication between the two is robust and reliable. An example of such libraries would be [pySerialTransfer][1] and [SerialTransfer.h][2].

pySerialTransfer is pip-installable and cross-platform compatible. SerialTransfer.h runs on the Arduino platform and can be installed through the Arduino IDE's Libraries Manager.

Both of these libraries have highly efficient and robust packetizing/parsing algorithms with easy to use APIs.

**Example Python Script:**

    import time
    from pySerialTransfer import pySerialTransfer as txfer

    if __name__ == '__main__':
        try:
            link = txfer.SerialTransfer('COM17')

            link.open()
            time.sleep(2) # allow some time for the Arduino to completely reset

            while True:
                send_size = 0

                ###################################################################
                # Send a list
                ###################################################################
                list_ = [1, 3]
                list_size = link.tx_obj(list_)
                send_size += list_size

                ###################################################################
                # Send a string
                ###################################################################
                str_ = 'hello'
                str_size = link.tx_obj(str_, send_size) - send_size
                send_size += str_size

                ###################################################################
                # Send a float
                ###################################################################
                float_ = 5.234
                float_size = link.tx_obj(float_, send_size) - send_size
                send_size += float_size

                ###################################################################
                # Transmit all the data to send in a single packet
                ###################################################################
                link.send(send_size)

                ###################################################################
                # Wait for a response and report any errors while receiving packets
                ###################################################################
                while not link.available():
                    if link.status < 0:
                        if link.status == -1:
                            print('ERROR: CRC_ERROR')
                        elif link.status == -2:
                            print('ERROR: PAYLOAD_ERROR')
                        elif link.status == -3:
                            print('ERROR: STOP_BYTE_ERROR')

                ###################################################################
                # Parse response list
                ###################################################################
                rec_list_  = link.rx_obj(obj_type=type(list_),
                                         obj_byte_size=list_size,
                                         list_format='i')

                ###################################################################
                # Parse response string
                ###################################################################
                rec_str_   = link.rx_obj(obj_type=type(str_),
                                         obj_byte_size=str_size,
                                         start_pos=list_size)

                ###################################################################
                # Parse response float
                ###################################################################
                rec_float_ = link.rx_obj(obj_type=type(float_),
                                         obj_byte_size=float_size,
                                         start_pos=(list_size + str_size))

                ###################################################################
                # Display the received data
                ###################################################################
                print('SENT: {} {} {}'.format(list_, str_, float_))
                print('RCVD: {} {} {}'.format(rec_list_, rec_str_, rec_float_))
                print(' ')

        except KeyboardInterrupt:
            link.close()

        except:
            import traceback
            traceback.print_exc()

            link.close()

**Example Arduino Sketch:**

    #include "SerialTransfer.h"

    SerialTransfer myTransfer;

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

    void loop()
    {
      if(myTransfer.available())
      {
        // send all received data back to Python
        for(uint16_t i=0; i < myTransfer.bytesRead; i++)
          myTransfer.txBuff[i] = myTransfer.rxBuff[i];

        myTransfer.sendData(myTransfer.bytesRead);
      }
    }

Note that you can send more than just individual chars with these libraries. It is possible to transfer floats, ints, bytes, arrays, and even structs (or any combination of the like) within your program using the libraries! See the examples in [SerialTransfer.h][3] for more info

**For theory behind robust serial communication,** check out the tutorials [Serial Input Basics][4] and [Serial Input Advanced][5].

  [1]: https://github.com/PowerBroker2/pySerialTransfer
  [2]: https://github.com/PowerBroker2/SerialTransfer
  [3]: https://github.com/PowerBroker2/SerialTransfer/tree/master/examples
  [4]: https://forum.arduino.cc/index.php?topic=396450.0
  [5]: https://forum.arduino.cc/index.php?topic=662346.0


body:
I have L293D shield connected to my arduino UNO and it fills nearly all the digital pins including TX(1) and RX(0) pins.
I know this function, but as far as I know, it works for digital pins.
~~~c
SoftwareSerial NAME(Rx,Tx);
~~~

How can I set 2 analog pins as Tx and Rx? I will use them for HC-06.

title: How to send and receive data from serial using analog pins?

Answers: 0