body:
I observed that these device do very well in slave more, however, in Master mode, they only connect to themselves ( I mean other HC-05).
I have sevceral slave devices ( gamepads, GPS modules, ...)  that never get connected, thoug the HC-05 sees them through the INQ  command, & accurately returns their address, class, signal force, and their name even.
Though, I never succeeded to pair them !!
As if they were designed to be used together and never tested with other slave devices !!?


sender: user

message:
pin numbering for non-standard chips

so i replaced the mainboard in (what was) an anet a8 3d printer with a proper RAMPS setup. there was nothing wrong with it, (or at least it wasnt damaged, there are a number of severe design flaws) so i thought it might be a good start point for a remote controlled crawler/bot thing. it already has four a4988 drivers on board, plus a few mosfets and other bits which will be great for accessories (planning headlights, horn, maybe light sensor). its built around the atmega1284p, which is something of an oddball inbetween the 328 on the uno and the 2560 on the mega, but is the same product line. ive already worked out the libraries/drivers for the ch340 or whatever it is that is needed to flash code to the board,**it already has already been added to the arduino ide**, i have successfully flashed sketches to it before, but not my own. what im wondering is how to declare pins when im writing my own code. the bottom right of [this][1] schematic lists connections to the main chip, is it reasonably safe to assume that the digital pin numbers listed there can be used like the normally labeled headers on a standard board? how exactly are those numbers determined?

  [1]: https://ibb.co/5LG643b

sender: assistant

body: ok so what ive found is that pins are declared in a file, `pins_arduino.h`. for each board/chip/variant another file is added(or created, if writing your own) to the arduino hardware files. in my specific case the numbers in the graphic are consistent with those listed in the hardware file, so im good


message:
Arduino Object Oriented Programming

Can anyone send me a link tutorial about Arduino Object Oriented Programming? I want to learn Arduino, I am just a beginner.

body:
Have you programmed OOP before? For alot of projects you can get away with not knowing it.

I'll also point out that if you are just a beginner, I don't recommend starting off with OOP. Stick to simpler scripts (Trust me, OOP is a pain sometimes).

If you still INSIST on starting your arduino knowledge with OOP, look up "C++ classes" or "C++ OOP" as the default language that the arduino IDE uses is just a modified version of "C++"


body:
"Arduino" is just plain old C++ with (in some cases) bits removed and some helper functions and classes.

For the smaller (lower powered AVR for example) there is no full STL in the C++ library, and some functions are of a reduced complexity (such as no floating point support in the `printf` family of functions by default).

For OOP you don't need to know anything "Arduino" - it's just C++. Any C++ OOP tutorial will teach you what you need to know for Arduino OOP.


body:
I used OOP with C++ on an Arduino Due in an open source project.

Since I did not find any tutorila for the same the example might be helpful for You.

[https://github.com/eschlot/Box-Joint-Jig-Control][1]

  [1]: https://github.com/eschlot/Box-Joint-Jig-Control

W.r.t. the usability of OOP in embedded systems for scenarios like the above one there are plenty of good reasons to use OOP. A good example is the menu structure and the display control in the project.
Nevertheless from my experience it is important to understand the effects of automatic object creation and tentative memory reorganization to the behavior of real time systems. This is much less predictable with C++ then with plain C and can be a reason to not use OOP in any real time system.


body: http://paulmurraycbr.github.io/ArduinoTheOOWay.html really helped me understand what was happening. i had some previous oop expierence with java, but i still have a hard time using multiple files vs writing more methods in one file


message:
Is an Ultrasonic Sensor or Infrared Sensor better for measuring distance (to/from a human body)?

I'm trying to make a sensor to detect that a person is within 50cm to trigger a function. But when I use the HR-SR04 sensor, it works accurately on flat surfaces (e.g. walls, books) with a margin of error around 5cm, but not on uneven surfaces (e.g. humans) where the value randomly jumps between 0cm to 1000cm.

I was thinking whether using an IR distance sensor would be better.

body:
That depends on your requirements. An IR distance sensor will work better with different materials, since IR light is mostly reflected in very broad angles (expect for very reflective materials, like mirrors), so that uneven surfaces are also detected. But you will get a significantly worse error margin in your 50cm range. Normal IR distance sensors are just an LED and an IR photo transistor, sometime with some extra components. So the LED is lighting up and the photo transistor is measuring, how much of the IR light is coming back. The IR sensor depends also on the reflectiveness of the materials and the level of surounding IR light.

But as you don't really need to measure the distance, but just want to know, if there is an object in the range, an IR sensor might be enough. You would need to change the threshold of your IR sensor according to your needs (by experimenting with it).

All in all I think, yes, an IR sensor can give you better results for your application, though not for really measuring the distance, but only for the presence in a range with rather big error margin.


body:
I have found IR accuracy to be poor resolution (+/- a few centimeters), as it's highly dependent on the refectivity of the surface. It also frequently has very poor range (a few cm to tens of cm), depending on the emitting power of the illumination source.

I have found ultrasonics, however, even the cheap $0.99 ones you mention, to have much better resolution (+/- mm), and much better range (about 2m), depending on the code driving them. I have yet to see good non-blocking code in any library for one of these, but when I write my own non-blocking code with interrupts and basic digital signal processing, such as a median filter, I get excellent results.

So, I recommend you use ultrasonics, but it requires advanced knowledge to do it well and do it right, such as using interrupts and taking the median of every 3 to 5 samples to remove spurious results.

On very flat surfaces, such as walls, at angles 45 deg or larger, ultrasonics also do poorly, since they end up measuring the distance *including* the extra reflections off the walls, but contrary to what you experienced, on odd shaped or softer objects, such as humans, I find them to do much better. I have used ultrasonics as the means of detecting humans several times before with good results. The real secret/challenge is your code. And again, I have yet to find a library worth using, and good code on these cheap things makes a HUGE difference in results and reliability and accuracy!


message:
Frequency of Retrieving Data from Website

I have wrote a code that communicate with my website to retrieve data to power on or off a 5V relay. I'm running the code every second to make sure it is real time. Is there more efficient way to tell Arduino to get the data whenever it is changed rather than continuous GET request.

    // Send HTTP GET request
      int httpResponseCode = http.GET();

      if (httpResponseCode>0) {
        Serial.print("HTTP Response code: ");        Serial.println(httpResponseCode);        String payload = http.getString();
            StaticJsonDocument<2000> doc;             DeserializationError error = deserializeJson(doc, payload);
            if (error) {              Serial.print(F("deserializeJson() failed: "));              Serial.println(error.c_str());              return;            }

            String status = doc["status"];
            Serial.println(status);
             if ( status == "ON" ) {
               digitalWrite(ledPin, LOW);
             } else {
               digitalWrite(ledPin, HIGH);
             }
      }

body:
Your two best options would be [MQTT][1] and [WebSockets][2].

Both would open a long lived TCP connection that the ESP8266 and browser could use to transmit and receive data. Both would avoid constant polling to see if there's a new command.

MQTT requires an external broker. There are MQTT services with free tiers you could use for this or you could run one locally - [Eclipse Mosquitto][3] is a popular MQTT broker that runs nicely on a Raspberry Pi. MQTT is particularly useful for networks with multiple publishers and subscribers (it's a "pubsub" protocol) and is probably overkill if you just have a single device and endpoint.

It's easy to use MQTT from a browser using Javascript. The [Paho Javascript MQTT][4] client works well. The ESP8266 would establish a connection to the MQTT broker, subscribe to a topic name and set a callback function that would be called when data was published to that topic. The browser would also establish a connection to the MQTT broker and would publish a message to the topic when responding to events from the user.

WebSockets would allow the ESP8266 and browser to establish a full duplex connection between them. The ESP8266 would create a websocket server which the browser would connect to. The ESP8266 would check for data on the websocket during while running code in `loop()` and would assemble messages from the browser.

Either works easily if both your devices are on the same network (for instance, at home). If your browser is outside the network, it won't be able to communicate directly with the ESP8266.

MQTT has the advantage that an MQTT server located outside of the network (not one running locally on a Raspberry Pi) would allow the browser and ESP8266 to communicate with one another through it. WebSockets would require the use of a proxy server (there are modules for popular web servers like NGINX and Apache, but this requires control of the web server to configure). If you only ever want to use the browser to control the ESP8266 while they're both on the same network you don't need to worry about this.

  [1]: https://en.wikipedia.org/wiki/MQTT
  [2]: https://en.wikipedia.org/wiki/WebSocket
  [3]: https://mosquitto.org/
  [4]: https://www.eclipse.org/paho/clients/js/


message:
I am very new to Arduino and the kit tutorial just told me to wire this, I do not know how to wire it. Can Someone plz help!

[![This is the image][1]][1]

  [1]: https://i.stack.imgur.com/e6NSE.png
I can't figure out how to do this the only wires I have are Jumper Wire and M-F 20 Pin DuPont Wire.

body:
If you don't have a breadboard, get one. It's a board with lots of holes in it that you can use for experimenting.

Something like this:

[![enter image description here][1]][1]
https://www.adafruit.com/product/64?gclid=EAIaIQobChMIz9XDj9bF6wIVcuW1Ch2_kgD3EAQYAiABEgL4DvD_BwE

As Delta_G said in their comment, you could wire a circuit as simple as yours by just putting the wires from the components directly into the terminals on the Arduino, but that quickly becomes impractical. Get a breadboard and learn how to use it.

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


message:
Confuse about PROGMEM and R"====()===="

I saw the following code from <https://circuits4you.com/2018/03/10/esp8266-jquery-and-ajax-web-server/> but I could not understand it thoroughly...

I looked at the documentation of PROGMEM from this <https://www.arduino.cc/reference/en/language/variables/utilities/progmem/> but could not understand the importance in the code on why you should put your variables in flash memory instead of SRAM (the usual memory?)?

    const char MAIN_page[] PROGMEM = R"=====(
      <!DOCTYPE html>

If you click on me, I will disappear.

Click me away!

Click me too!

      circuits4you.com

    )=====";

Also, I could not understand the definition of R"====()====", what is meant by this in arduino?

body:
> why you should put your variables in flash memory instead of SRAM

Because the Arduino has only a very small amount of memory. If you have data that will never change it's better to store it in flash (of which there is much more) so as to leave the SRAM free for data that *does* change.

> Also, I could not understand the definition of R"====()====", what is meant by this in arduino?

The `R` means "Treat everything between these delimiters as a raw string".  That is, everything between `"=====(` and `)====="`. It's not an Arduino thing, but a general C++ thing ([see here](https://en.cppreference.com/w/cpp/language/string_literal)). The `=====` can be anything you like (within certain bounds) as long as it's the same at both the start and end of the string.  So you could use `R"-=(This is "text")=-"` which would assign the string `This is "text"`. It's a great way of working with long strings that may want to contain `"` as otherwise you would have to escape each and every `"` as `\"`. So the string I showed just now would otherwise have to be written as: `"This is \"text\""`, which can get very messy if there are lots of `"` in there.  The important thing to remember is that `)=====` mustn't appear in your text anywhere, so make sure it's something really obscure.


message:
Most Efficient & Cost Effective Home Automation Setup

I managed to build a system using Wemos D1 R1 connected to my website to retrieve data to power on or off a 5V relay. Now I would like to expand the project to control all my house outlet. Assuming I have, 5 rooms each of which has 5 electricity wires to control. My question is what is the best setup to achieve my goal in terms of efficiency and cost optimization. If I clone my current setup, I would be needing Wemos Module for every room that connecting separately to my Wifi and then to my server which seems too much for me. So what would you recommend?

Thoughts:
 - Can I use one single central Wemos and then communicate to each room through ESP2866 or 433MHZ RF modules.
- I would be using at least 4 channel 5V relay Module. Could it be powered using 5V in Wemos or Arduino or should be powered with adapter
- If I want to control a fridge or AC or water heater, should I need SS Relay or any relay would suffice
- if SS Relay to be used, I have read that heat sink or fan should be included, is that a must?

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

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

body:
I advice you to buy some Sonoff devices, either the basic or S20. (they are pretty cheap on AliExpress/ebay etc.) They are perfect for the job. Flash them with Tasmota, which you find on github [Tasmota][1]. Then use a RaspberryPi (or similar) as a server. Run Node-RED on this server to communicate via MQTT to all your (Sonoff) devices. Use Mosquitto as the MQTT broker.
I know this sounds like a lot, but thank me later when your done.

  [1]: https://github.com/arendst/Tasmota


message:
Error reading from PROGMEM

I was trying to run a code from this <https://circuits4you.com/2018/03/10/esp8266-jquery-and-ajax-web-server/>

I am pasting it here.

    /*
     * ESP8266 NodeMCU jQuery CDN Demo
     *
     * https://circuits4you.com
     */
    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>

    //ESP Web Server Library to host a web page
    #include <ESP8266WebServer.h>

    //---------------------------------------------------------------
    //Our HTML webpage contents in program memory
    const char MAIN_page[] PROGMEM = R"=====(
      <!DOCTYPE html>

If you click on me, I will disappear.

Click me away!

Click me too!

      circuits4you.com

    )=====";
    //---------------------------------------------------------------

    //On board LED Connected to GPIO2
    #define LED 2

    //SSID and Password of your WiFi router
    const char* ssid = "circuits4you.com";
    const char* password = "yourWiFipassword";

    //Declare a global object variable from the ESP8266WebServer class.
    ESP8266WebServer server(80); //Server on port 80

    //===============================================================
    // This routine is executed when you open its IP in browser
    //===============================================================
    void handleRoot() {
     Serial.println("You called root page");
     String s = MAIN_page; //Read HTML contents
     server.send(200, "text/html", s); //Send web page
    }
    //==============================================================
    //                  SETUP
    //==============================================================
    void setup(void){
      Serial.begin(115200);

      WiFi.begin(ssid, password);     //Connect to your WiFi router
      Serial.println("");

      //Onboard LED port Direction output
      pinMode(LED,OUTPUT);

      //Power on LED state off
      digitalWrite(LED,HIGH);

      WiFi.mode(WIFI_STA); //WiFi mode station (connect to wifi router only

      WiFi.begin(ssid, password);

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

      //If connection successful show IP address in serial monitor
      Serial.println("");
      Serial.print("Connected to ");
      Serial.println(ssid);
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());  //IP address assigned to your ESP

      server.on("/", handleRoot);      //Which routine to handle at root location. This is display page

      server.begin();                  //Start server
      Serial.println("HTTP server started");
    }
    //==============================================================
    //                     LOOP
    //==============================================================
    void loop(void){
      server.handleClient();          //Handle client requests
    }

When I deploy this to my nodemcu esp-12e, I a m getting below error

I used the exception decoder

    Exception 3: LoadStoreError: Processor internal physical address or data error during load or store
    PC: 0x4000bf64
    EXCVADDR: 0x4023d581

From the decoder it says the offending line is this one

    void handleRoot() {
     Serial.println("You called root page");
     String s = MAIN_page; //<<<<<<<<<<<<<<<<<<<<<< Error on this line
     server.send(200, "text/html", s);
    }

It looks like it cannot read from the variable in PROGMEM..

I replaced that line with this code and converting it into a string and the error was gone.

    String MAIN_page = R"=====(
      <!DOCTYPE html>

If you click on me, I will disappear.

Click me away!

Click me too!

      circuits4you.com

    )=====";

Is there something wrong in the code that I am following on how it reads the variable from the PROGMEM flash memory?

body:
You cannot assign a PROGMEM string directly to a String object. Besides, the whole concept makes no sense, since String objects store their data in RAM regardless.

If you want to use PROGMEM you need to use `const char *` not `String`.


message:
Leonardo keypresses not working with OBS

I am using an Arduino Leonardo to have hotkeys for OBS but they don't work when the OBS Studio window is not focused.

I have the Leonardo press Ctrl + Alt + Shift + F7 when I press a button connected to the Leonardo. On OBS I have Ctrl + Alt + Shift + F7 switch to a slide. When I have the OBS window focused and I press the button it works fine. But when I have another application focused it does not work. The strange thing is, is that when I press (on my keyboard) Ctrl + Alt + Shift + F7, it will switch to the slide, but when I press the button it does not work.

I am running OBS as an Administrator btw.

My code for the Leonardo is below
```
int pinA = 8;

void setup() {
    pinMode(pinA, INPUT);
}

void loop(){
digitalWrite(pinA, HIGH);
readPinA = digitalRead(pinA);
if (readPinA == 0){
    Serial.print("A\n");
    Keyboard.press(KEY_RIGHT_CTRL);
    Keyboard.press(KEY_RIGHT_ALT);
    Keyboard.press(KEY_RIGHT_SHIFT);
    Keyboard.press(KEY_F7);
    Keyboard.releaseAll();
    delay(250);
    }
}
```

body:
*Warning: the below is all supposition.*

When the OBS window is focused the OS can send keyboard events to the window. That means that it gets "The button has been pressed" messages. These are generated when the "press" events are sent from the Leonardo.

When the OBS window *isn't* focused it can't be sent those messages - so it has to manually poll the state of the keyboard to see what buttons are pressed at any one time. It can't be doing this *all* the time, so it does it periodically (but still pretty fast).

The knock-on effect is, though, that when not focused it can only see buttons that have been pressed for at least enough time for it to poll the state.

If you add a delay into your routine between the last "press" and the "release all" commands that is longer than the period between polling (no idea what that is - you'll have to experiment, but starting at around 50ms to 100ms should be adequate) you should give OBS enough time to see that the buttons are pressed before you then release them.


message:
Sparkfun OBDII - Arduino Uno Stuck at 832RPM-13Kmh

I'm working on a hobby project with Sparkfun OBDII UART + Arduino Uno + 16x2 LCD Screen, i'm trying to read my car's RPM-Speed-Coolant Temprature-Oxy Sensor on runtime.

[Product Page][1]

Wired OBDII to Arduino as:
OBD TX -> ARDUINO RX
OBD RX-> ARDUINO TX
OBD GND -> ARDUINO GND

As far as i understand OBDII board does all the job and it's just communicating with arduino through serial, they provided an example here : [Hookup Guide][2]

I don't have sparkfun serial lcd, so i've changed codes according to my lcd as follow;

    #include <SoftwareSerial.h>
    #include "DFRobot_RGBLCD.h"
    const int colorR = 255;
    const int colorG = 0;
    const int colorB = 0;
    DFRobot_RGBLCD lcd(16,2);  //16 characters and 2 lines of show
    char rxData[20];
    char rxIndex=0;
    int vehicleSpeed=0;
    int vehicleRPM=0;
    void setup()
    {
    lcd.init();
    lcd.setRGB(colorR, colorG, colorB);
    Serial.begin(9600);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Hiz: ");
    lcd.setCursor(0,1);
    lcd.print("Devir: ");
    delay(1500);
    Serial.println("ATZ");
    delay(2000);
    Serial.flush();
    }

    void loop()
    {
    Serial.println("010D");
    getResponse();
    getResponse();
    vehicleSpeed = strtol(&rxData[6],0,16);
    lcd.setCursor(4,0);
    lcd.print(vehicleSpeed);
    lcd.print(" km/h");
    delay(100);
    Serial.flush();
    Serial.println("010C");
    getResponse();
    getResponse();
    vehicleRPM = ((strtol(&rxData[6],0,16)*256)+strtol(&rxData[9],0,16))/4;
    lcd.setCursor(6,1);
    lcd.print(vehicleRPM);
    delay(100);
    }
    void getResponse(void){
      char inChar=0;
      while(inChar != '\r'){
        if(Serial.available() > 0){
          if(Serial.peek() == '\r'){
            inChar=Serial.read();
            rxData[rxIndex]='\0';
            rxIndex=0;
          }
          else{
            inChar = Serial.read();
            rxData[rxIndex++]=inChar;
          }
        }
      }
    }

with above code i believe arduino receives last rpm and speed record before i shut down the engine which is 832RPM - 13 Kmh (at this point i'm not sure if arduino receive speed value correctly because when i shut down the engine i was parked the car and speed was 0kmh), in normal case when i start the car rpm and speed value should have changed but even after started the car the value stands still,it's not changing.

I bought waveshare's USB FTDI(TTL) adapter to figure it out is this board communicate with car or pc properly, connected usb ttl as;
OBD TX -> TTL RX
OBD RX-> TTL TX
OBD GND -> TTL GND

connected to OBDII port of my car, opened tera term, connected to COM20 (ttl defined as com20 on the pc) and run below commands as suggested in their manual;

    ATZ -- resetted card successfully
    ATRV -- returned 12.4 V as it should be, which is my battery voltage
    ATSP0 -- auto find and select car's protocol it returned OK
    010C -- RPM of the car it returned 41 0C 00 00 (engine wasn't started)
    010C -- RPM of the car it returned 41 0C 10 F4 (engine started--idle RPM arround 1.000 rpm)
    010D -- speed of the car it returned 41 00 00
    010D -- speed of the car it returned 41 00 00 both value is the same because the car is not moving :)

According to above outcome the board is fine and communicating with car or pc or arduino without any problem.

But when i try with arduino when i connect the board to my car and turn my ignition to battery mode it reads rpm as 832 and speed as 13 and don't update those values even i start the engine.

What am i doing wrong?

[![enter image description here][2]][2]
[![enter image description here][3]][3]
[![enter image description here][4]][4]
[![enter image description here][5]][5]

  [1]: https://i.stack.imgur.com/JJyY9.jpg
  [2]: https://i.stack.imgur.com/Uuamb.jpg
  [3]: https://i.stack.imgur.com/SsyIA.jpg
  [4]: https://i.stack.imgur.com/ImPzf.jpg
  [5]: https://i.stack.imgur.com/n2eeV.jpg

body:
after 1 week of try i finally solved it :)

As you guys know UNO has 1 i/o serial port, and Sparkfun's OBDII board doesn't work on same i/o serial port (at least i couldn't be able to), with uno when you send a command through serial to obd board you need to wait minimum 3 seconds to send another command or car's can-bus thinks that you canceled the first command returns STOPPED error, but with MEGA it works perfectly because mega has 3 i/o serial ports. You simply define Serial(TX)-Serial1(RX) and it works perfectly with 75ms delay.

Here is the working code.

    //Set up ring buffer
    char rxData[20];
    char rxIndex = 0;
    int rpmstored = 0;

        void setup()
        {
          Serial.begin(9600); // prints to serial monitor
          Serial1.begin(9600); //Hardware serial connection to the obdii uart
          OBD_init(); //initiates obd link
          delay(3000);
        }

        void loop()
    {
    rpmstored = getRPM();
    //int mph = (int)((getSPEED() * 10000L + 5) / 16090); //convert to mph
    //  Serial.print (mph);
    Serial.print("S:");
    Serial.print (getSPEED());
    Serial.print (",");
    Serial.print("R:");
    Serial.println (getRPM());
    //Serial.print (",");
    //Serial.print("W:");
    //Serial.print (getWATERTEMP());
    //Serial.print (",");
    //Serial.print("O:");
    //Serial.print (getOILTEMP());
    //Serial.print (",");
    //Serial.print("F:");
    //Serial.print (getFUEL());
    //Serial.print (",");
    //Serial.print("V:");
    //Serial.println (getVOLT());
    delay(100);
    Serial.flush();
        }

        void OBD_init(void)
        {
          //Wait for a little while before sending the reset command to the OBD-II-UART
          delay(2000);
          //Reset the OBD-II-UART
          Serial1.print("ATZ\r");
          //Wait for a bit before starting to send commands after the reset.
          delay(2);
          OBD_read();
          Serial1.print("ATE0\r");
          OBD_read();
          //Serial1.flush();
        }

        int getRPM(void)
        {
          //Query the OBD-II-UART for the Vehicle rpm
          Serial1.flush();
          Serial1.print("010C\r");
          OBD_read();

          return ((strtol(&rxData[6], 0, 16) * 256) + strtol(&rxData[9], 0, 16)) / 4;
        }

        int getSPEED(void)
        {
          //Query the OBD-II-UART for the vehicle speed
          Serial1.flush();
          Serial1.print("010D\r");
          OBD_read();

          return strtol(&rxData[6], 0, 16);
        }

        int getOILTEMP(void)
        {
          //Query the OBD-II-UART for the vehicle speed
          Serial1.flush();
          Serial1.print("015C\r");
          OBD_read();

          return strtol(&rxData[6], 0, 16);
        }

        int getFUEL(void)
        {
          //Query the OBD-II-UART for the vehicle speed
          Serial1.flush();
          Serial1.print("012F\r");
          OBD_read();

          return strtol(&rxData[6], 0, 16);
        }

        int getVOLT(void)
        {
          //Query the OBD-II-UART for the vehicle speed
          Serial1.flush();
          Serial1.print("0142\r");
          OBD_read();

          return strtol(&rxData[6], 0, 16);
        }

        int getWATERTEMP(void)
        {
          //Query the OBD-II-UART for the Engine Coolant Temp
          Serial1.flush();
          Serial1.print("0105\r");
          OBD_read();

          return strtol(&rxData[6], 0, 16) - 40;
        }

        void OBD_read(void)
        {
          char c;
          do {
            if (Serial1.available() > 0)
            {
              c = Serial1.read();
              if ((c != '>') && (c != '\r') && (c != '\n')) //Keep these out of our buffer
              {
                rxData[rxIndex++] = c; //Add whatever we receive to the buffer
              }
            }
          } while (c != '>'); //The ELM327 ends its response with this char so when we get it we exit out.
          rxData[rxIndex++] = '\0';//Converts the array into a string
          rxIndex = 0; //Set this to 0 so next time we call the read we get a "clean buffer"

        }

I only need RPM & Speed that's why i comnented out other parameters but tested all and works perfectly.


message:
7segment display on Multi Function shield - Arduino Uno

I’ve bought [this shield ][1].
I’m looking for a way to display decimal point, without using any a designated library.
Most examples as [this one][2] shows only 0-9.

**EDIT1** update link
[Link][3]

  [1]: https://www.google.com/search?q=multi function shield&rlz=1CDGOYI_enIL782IL782&hl=he&prmd=isnv&source=lnms&tbm=isch&sa=X&ved=2ahUKEwj74tiqk8jrAhXc6OAKHeSUBbQQ_AUoAXoECAwQAQ&biw=375&bih=640&dpr=3#imgrc=lRdKBzXtX0i0tM
  [2]: https://www.google.com/amp/arduinolearning.com/code/multi-function-shield-examples.php
  [3]: http://arduinolearning.com/code/multi-function-shield-examples.php

body:
So if you click your 2nd link, it includes sample code for various sections of the multi-function shield.

One of them is titled "segment display".

If you look at that code, line 7 defines the bit patterns for each of the digits from 0 to 9:

    const byte SEGMENT_MAP[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0X80,0X90};

 If you map them out in binary, you get:

```
0xC0, 1100 0000 0
0xF9, 1111 1001 1
0xA4, 1010 0100 2
0xB0, 1011 0000 3
0x99, 1001 1001 4
0x92, 1001 0010 5
0x82, 1000 0010 6
0xF8, 1111 1000 7
0X80, 1000 0000 8
0X90 1001 0000 9
```

A 0 character has all the segments lit except the middle "cross-bar". An 8 character has ALL of the segments lit. But the bit pattern for 8 is `1000 0000`. That suggests that a 0 bit means a segment is lit, and 1 means it is off. Since the highest order bit of all of those characters is 1 (off) it suggests that the high-order bit is the decimal place bit. (It's the only bit that never changes.)

So if you replace

    const byte SEGMENT_MAP[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0X80,0X90};

with

    const byte SEGMENT_MAP[] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0X00,0X10};

You should get all the digits drawn with their corresponding decimal place lit.

I'd try that first to verify that I'm correct.

I'd then suggest writing code that reads the segments value for each digit, decides if you want a decimal place at that position, and if so, doing a bitwise AND (`&` in C/C++) on the value with 0X7F to clear the decimal bit for that character. (Remember it looks like a 0 means a given LED segment should be lit.

You could modify the function WriteNumberToSegment() to take a "lightDot" parameter, and have it change the bit if you pass TRUE (1):

```
void WriteNumberToSegment(byte Segment, byte Value, bool lightDot)
{
    digitalWrite(LATCH_DIO,LOW);
    bool bits = SEGMENT_MAP[Value]);
    if (lightDot) {
       bits &= 0x7F; //To light the decimal for this digit, clear the 0x80 bit
    }
    shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, bits);
    shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_SELECT[Segment] );
    digitalWrite(LATCH_DIO,HIGH);
}
```

(I don't remember for sure if `bool` is a valid type in Arduino C/C++. If not, just replace `bool` with `uint8` in the above.)


message:
Communication between ESP01 Arduino NANO and using External Interrupt in Arduino NANO for other than communication program same time

I have done communication between ESP01 and Arduino NANO (ATMEGA328 based). ESP pins used are GPIO-0 and GPIO2. In NANO, used D2 and D3. This program working Ok. Now I want to add external interrupt in my Arduino NANO program while continuing communication with ESP01. But I cannot use D2 and D3 because it was used by communication program. Now Arduino NANO's limit is it has only two interrupt pins which are D2 and D3. So if I use this for external interrupt program, I lose communication with ESP01. Can anybody help me to use my both task at the same time: Task1- External interrupt in Arduino Nano, Task2- Communication with ESP01. Your reply will help me to solve this issue. Thanks in advance.

body:
D2 and D3 Pins on Arduino nano support external Interrupt. Hence, you have to use one of those for the interrupt.

Since you are using `softwareSerial()` you can easily remap it to other digital pins of the Nano.

Pins from `D4-D12`can be used for communication.
You just have to change the parameters in the `softwareserial()` as below:

    SoftwareSerial mySerial(4, 5); // RX, TX;;for example

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

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


message:
Send only one packet from one ESP32 to another ESP32 without acknowledgment

I have a network consisting 10 slaves and one master. I am using ESP-NOW to send the messages between the nodes. All of the nodes are within close proximity. I do NOT need a mesh network to reach all the nodes.

ESP-NOW works amazing. It is simple to use and the library is easy to understand. **But in this project esp-now is not working for me and here is why:**

1. If the 10 slaves want to send data at the same time it does not work. With 10 nodes they can send data every 200ms. If I lower the time some nodes even crash and restart.

2. Because all nodes cannot send data at the same time I am having the master ping each node to synchronize who can send a message. The moment a slave receives a message it can reply back.

3. If one slave node sends data to the wrong peer for some reason the web server of the master node stops working. It freezes until that node is done sending data.

4. If I send a broadcast message all the nodes reply. **How can I configure esp-now so that no acknowledgment is sent back?**

5. With esp-now when you send a packet the destination node always replies with a confirmation. I want to send that confirmation once the job that the slave had to perform worked. Because I am planing to work with a lot of nodes with close proximity I want to reduce network traffic. Moreover, on esp-now if a packet is not delivered it attempts again increasing the network traffic. I only want to resend packets that are important in order to reduce network traffic.

6. esp-now limits the number of nodes you can have specially if you encrypt the messages.

**So my question is:** is there a way to instruct esp-now to NOT send an acknowledgment? Can I instruct esp-now to only send one packet regardless if it failed or not? On the NRF24L01 you can set this value with the method `setRetries`. I just want something like UDP where it is a fire and forget. I cannot use UDP because I do not want to be connected to a WiFi network.

It will be great if I could have 2 methods. One for sending a simple raw packet and another for reading those packets on another esp32. I know I will be having to do a lot of filtering on the receiving side.

------------

Edit
---

-----------

Here is a solution that works but needs improvement
-----

It is possible to send raw packets with the function `esp_wifi_80211_tx`. But still esp32 sends 5 packets when using that function! Moreover, in order to use that function you must send a wifi beacon with whatever data you want. The minimum size of a beacon packet I believe is 128 bytes. So this is a solution but not a good one.

Anyways I bellow is the code for the transmitter esp32 and the receiver esp32. The transmitter code has to be compiled with the ESP-IDF framework and NOT arduino. If I use arduino framework it compiles fine (replace main function with setup) but it does not work once I upload it to the esp32. The receiver code I compiled it using the arduino IDE.

**transmitter code (tx)**

    #include <stdio.h>

    #include "driver/gpio.h"
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"

    #include "esp_event_loop.h"
    #include "esp_system.h"
    #include "esp_event.h"
    #include "esp_wifi.h"

    #include "nvs_flash.h"
    #include "string.h"

    // pin used to flash led
    #define PIN GPIO_NUM_2

    /*
     * This is the (currently unofficial) 802.11 raw frame TX API,
     * defined in esp32-wifi-lib's libnet80211.a/ieee80211_output.o
     *
     * This declaration is all you need for using esp_wifi_80211_tx in your own application.
     */
    esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void *buffer, int len, bool en_sys_seq);

    esp_err_t event_handler(void *ctx, system_event_t *event)
    {
     return ESP_OK;
    }

    void send_raw_packet_task(void *pvParameter)
    {

     for (;;)
     {
      uint8_t dataToSend[] = { 0 } ;

      esp_wifi_80211_tx(WIFI_IF_AP, dataToSend, sizeof(dataToSend) , false);

      // turn on and off led AND wait 10 seconds
      gpio_pad_select_gpio(PIN);
      gpio_set_direction(PIN, GPIO_MODE_OUTPUT);
      gpio_set_level(PIN, 1);
      vTaskDelay(9500 / portTICK_PERIOD_MS);
      gpio_set_level(PIN, 0);
      vTaskDelay(500 / portTICK_PERIOD_MS);
     }
    }

    extern "C" void app_main(void)
    {
     nvs_flash_init();
     tcpip_adapter_init();

     wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();

     ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
     ESP_ERROR_CHECK(esp_wifi_init(&cfg));
     ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));

     // Init dummy AP to specify a channel and get WiFi hardware into
     // a mode where we can send the actual fake beacon frames.
     ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
     wifi_config_t ap_config;

     // SSID = TTTT (4 times the letter t in uppercase)
     wifi_ap_config_t x;
     x.ssid[0] = 84; x.ssid[1] = 84; x.ssid[2] = 84; x.ssid[3] = 84;
     x.ssid[4] = 0;
     x.ssid_len = 4;

     //x.password = "dummypassword"; // for some reason this does not compile
     x.password[0] = 84; x.password[1] = 84; x.password[2] = 84; x.password[3] = 84; x.password[4] = 84; x.password[5] = 84; x.password[6] = 84; x.password[7] = 84;
     x.password[8] = 0;

     x.channel = 1;
     x.authmode = WIFI_AUTH_OPEN;
     x.ssid_hidden = 0;
     x.max_connection = 4;
     x.beacon_interval = 60000;
     ap_config.ap = x;

     //ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config));
     auto res = esp_wifi_set_config(WIFI_IF_AP, &ap_config);
     if (res == ESP_OK)
     {
      printf("set esp_wifi_set_config. It worked!\n");
     }
     else
     {
      printf("It did NOT worked :/\n");
      return;
     }

     // ESP_ERROR_CHECK(esp_wifi_start());
     res = esp_wifi_start();
     if (res == ESP_OK)
     {
      printf("wifi started! It worked!\n");
     }
     else
     {
      printf("It did NOT worked :/\n");
      return;
     }

     // ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
     wifi_ps_type_t t = WIFI_PS_NONE;
     res = esp_wifi_set_ps(t);
     if (res == ESP_OK)
     {
      printf("wifi set to WIFI_PS_NONE! It worked!\n");
     }
     else
     {
      printf("It did NOT worked :/\n");
      return;
     }

     res = esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE);
     if (res == ESP_OK)
     {
      printf("wifi set channel to 1! It worked!\n");
     }
     else
     {
      printf("It did NOT worked :/\n");
      return;
     }

     // output size of bytes that we will be sending
     printf("*** Size of configuration is %i bytes. Starting task send_raw_packet_task...", (int)sizeof(ap_config));
     xTaskCreate(&send_raw_packet_task, "send_raw_packet_task", 2048, NULL, 5, NULL);
    }

**receiver code (rx)**

    #include "freertos/FreeRTOS.h"
    #include "esp_wifi.h"
    #include "esp_wifi_types.h"
    #include "esp_system.h"
    #include "esp_event.h"
    #include "esp_event_loop.h"
    #include "nvs_flash.h"

    uint8_t channel = 1;

    static void wifi_sniffer_packet_handler(void* buff, wifi_promiscuous_pkt_type_t type);
    void wifi_sniffer_packet_handler(void* buff, wifi_promiscuous_pkt_type_t type) {

        // in here esp32 will capture all wifi traffic

        auto t = (unsigned char*)buff;

        // create flag to see if packet contains "TTT"
        bool containsX = false;

        // index where the first T is located on the buffer in case it is found
        int indexWhereNameOfSsidWasFound = 0;

        // look to see if its a packet of interest
        for (int i = 45; i < 100; i++)
        {
            if (t[i] == 84 && t[i + 1] == 84 && t[i + 2] == 84)
            {
                containsX = true;

                indexWhereNameOfSsidWasFound = i;
                Serial.println(i);

                break;
            }
        }

        if (containsX == false)
            return;

        // print SSID if found
        for (int i = indexWhereNameOfSsidWasFound; i < indexWhereNameOfSsidWasFound + 20; i++)
        {
            Serial.print((int)t[i]);
            Serial.print(" ");
        }
        Serial.println();

    }

    esp_err_t event_handler(void* ctx, system_event_t* event)
    {
        return ESP_OK;
    }

    // the setup function runs once when you press reset or power the board
    void setup() {

        Serial.begin(115200);

        // delay 2 seconds so that esp32 initializes
        Serial.println("Starting...");
        vTaskDelay(2000 / portTICK_PERIOD_MS);

        // init wifi sniffer
        {
            // order of initializations matter!

            wifi_country_t wifi_country = { .cc = "IT", .schan = 1, .nchan = 13 }; // Most recent esp32 library struct

            nvs_flash_init();
            tcpip_adapter_init();

            ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));

            wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
            ESP_ERROR_CHECK(esp_wifi_init(&cfg));
            ESP_ERROR_CHECK(esp_wifi_set_country(&wifi_country)); /* set country for channel range [1, 13] */
            ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
            ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL));
            ESP_ERROR_CHECK(esp_wifi_start());

            // turn on promiscuous to capture everything
            esp_wifi_set_promiscuous(true);
            esp_wifi_set_promiscuous_rx_cb(&wifi_sniffer_packet_handler);

            // listen on channel 1
            esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
        }
    }

    void loop() {
        // empty
    }

So basically the receiver code is listening for all network trafic in promiscuous mode. Kind of like wireshark. If it sees a packet that contains the string "TTTT" it will output it.

Because there is so much wifi traffic this is way slower than esp-now. I could not figure out how to send smaller packets. Lastly when sending a packet it takes about 2 second to capture the packet. I belive esp32 stores all those packets on a queue and then latter calls the call back function.

I guess I will go back on using esp-now. **Can I modify the source code of esp-now?** I just want want to remove the part where it send the packet multiple times and also the part where it replies with an acknowledgment.

body:
I surmise that the esp32 'raw' tx isn't really that, based on the restrictions on what can be sent (data, but not QoS data, for example.)

I think that among the 5 packets you report seeing are 1.RTS, 2. CTS, 3. DATA, 4. ACK. These (at least 1,2) are necessary to avoid collision.

ESPNow sends a vendor-specific packet which doesn't (I surmise) require or follow the CTS/RTS or ACK 802.11 conventions.

Point to Point ESPNow, however, is written to expect a packet acknowledgement from the receiver, and will resend for a certain number of times until it receives one.

Broadcast ESPNow does not expect, and in fact cannot automatically receive, one of these ESPNow-specific acknowledgements.

If you need the fastest, least reliable 802.11 packet transmission, I would advise to use Broadcast ESPNow.

Having said that, you must be aware that you will not get the full collision-avoidance protections of more usual 802.11 protocol usage. You may need to provide your own ... such as listen-before-send, random exponential backoff, and who knows what else.

Seems to me that you are embarking on a wilderness adventure :)


message:
How to create a 1 hour timer with ATtiny13A microcontroller?

I want to control an AC load such that it powered on for 1 minute, then off for 1 hour, then on again for 1 min, and so on, in a loop.

I just modified the blink sketch to do:
1. Turn `A1` on
1. Then delay for 60,000 ms
1. Then turn `A1` off
1. Then delay for 3,600,000 ms (3,600 sec, or 1 hr)

...but it doesn't seem to work.

It looks like the LED connected to `A0` turns on but instead of turning off after 1 min, it turns off after 8 min 30 s.

Any suggestions?

---

I rectified the sketch. Now its takes 1 sec as actual 1 sec 1 choose 1 MHz clock in IDE.

```cpp
int ledPin =  A3;      // the number of the LED pin
int ledState = HIGH;             // ledState used to set the LED
unsigned long previousMillis = 0;        // will store last time LED was updated
unsigned long OnTime = 60000;           // milliseconds of on-time
unsigned long OffTime = 10000;          // milliseconds of off-time

void setup()
{
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  // check to see if it's time to change the state of the LED
  unsigned long currentMillis = millis();

  if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
  {
    ledState = LOW;  // Turn it off
    previousMillis = currentMillis;  // Remember the time
    digitalWrite(ledPin, ledState);  // Update the actual LED
  }
  else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
  {
    ledState = HIGH;  // turn it on
    previousMillis = currentMillis;   // Remember the time
    digitalWrite(ledPin, ledState);    // Update the actual LED
  }
}
```

then it turns on for 1 sec and then turn off for 1 sec,
then randomly turning on at 30 sec or 1 min 30 sec.
I want to make it on for 1 min every hour.

**I tried blink sketch modified as follows:**

```cpp
void setup() {
  pinMode(A3, OUTPUT);
}

void loop() {
  digitalWrite(A3, HIGH);
  delay(60000);
  digitalWrite(A3, LOW);
  delay(900000);
}
```

but it still turns on for 1 min and turns off for 1 min.

I also tried this:

```cpp
void setup() {
  pinMode(A3, OUTPUT);
}

void loop() {
  digitalWrite(A3, HIGH);
  delay(60000);
  digitalWrite(A3, LOW);
  delay(3.6e+6);
}
```

No matter what I do on time and off time always remain same.

I just wanted to know one thing: can I set 1 hour off and 1 min on timer using ATtiny13A or not?

Tried 1.2 MHz, 1 MHz, all clocks in the IDE, nothing seems to work.

body:
As the unchanged blink sketch blinks with 8.4 seconds, I think my assumption is right. The clock of the Attiny is running 8 times slower, than the code thinks.

When you have installed the Attiny core, there should be a menu entry for the clock frequency. Most likely the standard is 8MHz. But having 8MHz set does not mean, that the Attiny is using 8MHz. To choose between different clock sources and frequencies, you must change the fuses of the microcontroller (which are just some bits of special non-volatile memory in the chip, that set special hardware configuration; more information in [this question][1]). This is done, when you burn the bootloader to the chip. That's the easy version. Alternatively you can use the `avrdude` command directly to set the fuses. That's the advanced way.

Currently the fuses of your Attiny seem to be set to the 1MHz internal clock. But the compiler uses the frequency, that you have chosen in the menu, hence 8MHz internal clock. So the compiler thinks, that the chip runs at 8MHz and thus generates the timing code for this execution speed. But your chip is currently 8 times slower, than the compiler thinks.

**TL;DR:** Burn the bootloader onto the chip to let the Arduino IDE set the right fuses for your clock frequency.

  [1]: https://electronics.stackexchange.com/questions/1262/what-are-atmel-fuses


body:
The code you wrote should work as expected. If it doesn't, I suspect
there is something broken in the Arduino core you are using. However,
such a trivial task can very easily be programmed in plain C, at the
avr-libc level:

```cpp
#define F_CPU 1000000  // 1 MHz
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    DDRB |= _BV(PB3);  // PB3 as output
    for (;;) {
        PORTB |= _BV(PB3);   // PB3 high
        _delay_ms(60e3);     // 1 min
        PORTB &= ~_BV(PB3);  // PB3 low
        _delay_ms(3.6e6);    // 1 h
    }
}
```

I would compile it with:

```shell
avr-gcc -mmcu=attiny13a -Os -Wall -Wextra 1h-timer.c -o 1h-timer.elf
```

See the [Port Registers][] Arduino tutorial for the meaning of the
macros used here. You can tweak `F_CPU` to fine-tune the delays, in case
your ATtiny clock is not quite 1 MHz.

[Port Registers]: https://www.arduino.cc/en/Reference/PortManipulation


message:
What is this potentiometer for?

I am working on an anemometer project using Arduino. I don't know barely anything from Arduino and I am following [this tutorial][1].

I have some doubts on the making part. This is what I have to make: [![2]][2]

and this is the code:

````
//anemómetro con LCD
#include <LiquidCrystal.h>

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

float veloc1 = 0; // entrada A0
int tiempo = 0;
int cnt = 0;
float v1 = 0;
float v2 = 0;

void setup() {
  lcd.begin(16, 2); // Fijamos el numero de caracteres y filas
  lcd.begin(16, 2); // Fijamos el numero de caracteres y filas
  lcd.print("Anemometro EC"); // Aqui va el mensaje
  analogReference(INTERNAL);// pone como referencia interna 1.1V
}

void loop() {
  v1 = (analogRead(0)); // lectura de sensor a0
  veloc1 = (v1 * 0.190); // 0,190 corresponde a la pendiente de la curva aca deben poner el numero que calcularon
  lcd.setCursor(0, 1); // Ponte en la line 1, posicion 0
  lcd.print(veloc1); //muestra la velocidad del viento en el LCD
  lcd.setCursor(4, 1); // ponte en linea 1, posicion 5
  lcd.print("Km / h");
  lcd.setCursor(9, 1);
  lcd.print("Max");
  if (veloc1 > v2)v2 = veloc1, lcd.print (v2, 1); // muestra la velocidad maxima que alcanzo
  delay(1000);
}
````

 1. What is the potentiometer doing here? Why is it necessary?
 2. My lcd screen doesn't show anything. Does anyone knows why??

Thanks in advance.

  [1]: https://espaciodecesar.com/2017/03/25/como-medir-el-viento-muy-facil-anemometro-simple-y-con-arduino/?unapproved=5086&moderation-hash=5df410840f50fe7de9b9a5d4ab73b37e#comment-5086
  [2]: https://i.stack.imgur.com/VRyGq.png

body:
> What is the potentiometer doing here? Why is it necessary?

It's there to control the "offset voltage" of the LCD, which is what controls the contrast of the display.

> My lcd screen doesn't show anything. Does anyone knows why??

Maybe you wired it wrong. Maybe you didn't put the potentiometer in the circuit because you didn't understand what it is for. Maybe you just need to adjust the contrast by turning said potentiometer. It's hard for us to tell. By showing us what you *intended* to build and then telling us that what you *actually* built doesn't work, there is nothing we can tell you. There must be some difference between what you intended to build and what you did build, but we can't see what you built, so we can't have any clue.


message:
Static IP for ESP8266 based on gateway

I'm new to Arduino programming. I want to make my ESP8266 get a static IP address based on the gateway's IP address.

I mean if the gateway is at 192.168.0.1 then the ESP8266 should get 192.168.0.15 as a static IP address. And if the gateway is at 192.168.1.1 then it should get 192.168.1.15 as an IP address.

body:
You can either set the router to allocate a static IP address based on your ESP8266's MAC address, or go the DHCP-way first, read the gateway IP address you got, and then do a `WiFi.config()`, something roughly like this (untested):

```c++
WiFi.begin(ssid, password);
IPAddress ip = WiFi.gatewayIP();
IP[3] = 15;
IPAddress dns(8, 8, 8, 8);
WiFi.config(ip, WiFi.gatewayIP(), dns, WiFi.subnetMask());
```

It is a bit of a trick, and not pretty, and you don't get to set the DNS as provided by the DHCP, because there is no `getDNS()`, for some silly reason, hence the use of Google's DNS server.

Note that when doing this, you run the risk of setting the ESP8266's IP address to an address already taken by another device on the same router.


body:
Here is the idea that I have not implemented yet.

 1. Connect to the wifi and let the router assign the IP to it.
 2. After getting the IP from the router save that IP to eeprom
 3. Now next time you want to connect to the wifi use this code.

```
// Set your Static IP address
IPAddress local_IP(192, 168, 1, 184);
// Set your Gateway IP address
IPAddress gateway(192, 168, 1, 1);

IPAddress subnet(255, 255, 0, 0);
IPAddress primaryDNS(8, 8, 8, 8);   //optional
IPAddress secondaryDNS(8, 8, 4, 4); //optional

if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
    Serial.println("STA Failed to configure");
  }

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

```
load the saved ip, gateWay and other information saved in the eeprom before passing to wifi.config function.


message:
parallel communication simulation problem

Hi I am trying to send data(1 byte) from one arduino to another using parallel communication(a bus of 8 connections) and not using any library. However, the problem is the data gets corrupt all the time and what I am supposed to receive at receiver arduino is not what I send. The protocol that I made up is similar to uart protocol. There is ES pin and when it is low, transmission is started and when it is high, the transmission is ended. I think the problem could be related to wires that I use to connect two arduinos. There could be some noise induced that could flip bits in wires or the code is problematic. I am posting my code. Maybe you can help me get through this and help me to resolve my problem.

Sender code:

    #define ES 8 //enable sampling
    #define B0 0 //Bus 0
    #define B1 1
    #define B2 2
    #define B3 3
    #define B4 4
    #define B5 5
    #define B6 6
    #define B7 7
    const char dataToBeSent = 'C';
    bool data_bit;

    void setup() {
      pinMode(ES,OUTPUT);
      pinMode(B0,OUTPUT);
      pinMode(B1,OUTPUT);
      pinMode(B2,OUTPUT);
      pinMode(B3,OUTPUT);
      pinMode(B4,OUTPUT);
      pinMode(B5,OUTPUT);
      pinMode(B6,OUTPUT);
      pinMode(B7,OUTPUT);
      digitalWrite(ES,HIGH);
      delay(3000);
    }
    void loop() {

     digitalWrite(ES,LOW); //transmission is started
     delay(10);

     for(int i = 0 ; i<8 ; i++){
        data_bit = dataToBeSent & (0x80 >> i);
        digitalWrite(i,data_bit);
     }
      delay(10);
      digitalWrite(ES,HIGH); //end transmission
      while(true){}
    }

Receiver code:

    #define ES 8 //enable sampling
    #define B0 0 //Bus 0
    #define B1 1
    #define B2 2
    #define B3 3
    #define B4 4
    #define B5 5
    #define B6 6
    #define B7 7

    char rx_data;
    byte rx_byte= 0;
    bool rx_pin;

    void setup() {
      Serial.begin(9600);
      pinMode(ES,INPUT);
      pinMode(B0,INPUT);
      pinMode(B1,INPUT);
      pinMode(B2,INPUT);
      pinMode(B3,INPUT);
      pinMode(B4,INPUT);
      pinMode(B5,INPUT);
      pinMode(B6,INPUT);
      pinMode(B7,INPUT);
      delay(1000);

    }

    void loop() {

      byte rx_byte= 0;

      while(digitalRead(ES) == HIGH){}
      delay(15);

      for(int i = 0 ; i<8 ; i++){
        rx_pin = digitalRead(i);
        Serial.print(rx_pin);
        if(rx_pin == 1){
          rx_byte |= (0x80 >> i);
        }
      }

     rx_data = rx_byte ;

     Serial.print("Received data: ");
     Serial.println(rx_data);

     delay(15);

     while(digitalRead(ES)== HIGH){}

    }

body:
You problem is that you are only using one phase of your "ES" clock, when in fact you should be using two.

In the first phase, where ES is high, is where you set the IO pins to represent your transmitted byte. Only once that is done can you then progress to the second phase, where ES is low, to indicate to the receiver that "I have set up my outputs, it's now time for you to read them".

So your transmitted code would flow like:

1. Set ES HIGH
2. Set output pins to represent the byte
3. Set ES LOW
4. Delay
5. Set ES HIGH

If you look at any timing diagrams for any protocol there will be places where the data is being written to the bus, and places where the data is considered stable and able to be read by the receiver. It's the job of the clock signal to indicate where these points in the protocol - to *synchronise* the receiver.

For example, here is the Centronics (parallel port) protocol:

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

The data changes while nStrobe is HIGH, and only when that data is "settled" is nStrobe brought LOW to tell the receiver it can read the data. Once nStrobe is taken HIGH again the data is changed to the next byte to transmit.

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


message:
Arduino respond to input from HT12D data output

Is there a way to connect a data output pin from an HT12D to an Arduino or ESP8266-12e input pin, then sense when the data pin is activated so I can have the Arduino or ESP8266-12e do something like turn on an output pin?

body:
I am afraid I could not understand your question properly. But maybe, the answer is YES, if ...

First of all, OUTPUT pins, cannot be turned ON and turned OFF, however, you can start or stop READING that particular OUTPUT PIN based on another INPUT pin value.

If you want to connect HT12D decoder to any arduino or ESP, you must be aware to use same voltage level between IO PINS, a good approach is to use a I2C bi-directional level shifter.

    if(INPUT_PIN_VALUE >= SOME_VALUE)
    {
       digitalRead(PIN)
    }


body:
Disclaimer: In this answer I'm using ESP and Arduino interchangeably, as if they were the same. They are in context this question, but not in general.

First: According to the [datasheet of the HT12D][1], the supply voltage can be between 2.4V and 12V, so you could just provide it with the 3.3V of your ESP. That way the output pins will also run on 3.3V. Then you can simply run a wire each from an output of the chip to a digital input pin of the Arduino.

Though you then should also provide your receiver chip with 3.3V. If that is not possible, you can provide the HT12D with 5V and use simple voltage dividers on each output to break the voltage down to 3.3V. That places restrictions on the transmission speed, but I don't think, that this is relevant here, as the outputs are more meant as momentary state outputs, not data transmission outputs. In that case you connect the output of the voltage dividers to one digital input pin on the Arduino each.

**How to read the data:**

The chip will read the data from the receiver on its Din pin. When it has found a valid transmission for the used address (which is configured through the address pins), then it will pull the VT pin to HIGH and output the new data on the pins. The datasheet says:

> The HT12D, on the other hand, provides 4latch type data pins whose data remain unchanged until new data are received.

Let's imagine, that you have send the pattern `HIGH, LOW, HIGH, LOW`. The HT12D will see this as valid data and set it's outputs to this pattern. The VT pin is pulled high to show, that new valid data arrived. Now you can read this pattern into the Arduino via multiple `digitalRead()` calls, one for each output pin of the HT12D.

The surrounding code depends on your needs. For example you could just read the pins continuously again and again, every time just outputting corresponding on the data. For example like this:

    void loop(){
        if(digitalRead(HT12D_pin1)) digitalWrite(LED_pin, HIGH);
    }

Or even easier:

    void loop(){
         digitalWrite(LED_pin, digitalRead(HT12D_pin1));
    }

Or you could also read the VT pin of the HT12D and only do something, if it is HIGH. That way you only act, if there is valid data received.

---

For more info you really need to improve your question.

  [1]: https://components101.com/sites/default/files/component_datasheet/HT12D Datasheet.pdf


message:
Programming Arduino Uno R3 to trigger a relay once every 24 hours

I programmed an Arduino Uno R3 to trigger a relay once every 24 hours from the moment it is powered on.

I calculated milliseconds and used the function `delay()`.

24 hours * 60 minutes each hour * 60 second every minute * 1000 milliseconds every second

so I used :

    delay(86400000)

for 86 million and 400 thousands milliseconds.

Currently, I'm still testing it...

Will this work? If not, is there a better built-in function/library or even external library to do it?

The relay trigger doesn't have to be very accurate at the very exact time each day.

I don't need it to be very accurate, it can shift few minutes every few months or so, thats okay with me.

But how about after few months or years of use ? Will it shift the timing much?

I read somewhere about using `millis()` function
and others use an RTC (Real Time Clock) module.

I don't want to use anRTC module, I am looking for a programmatical solution.

OR will my previous method using `delay()` work for such a very high number of milliseconds?

body:
`delay()` takes an unsigned long; I think what you do will work.

When in doubt, you could always do something like this:

    for (int hours = 0; hours < 24; hours++) {
      for (int mins = 0; mins < 60; mins++) {
        for (int secs = 0; secs < 60; secs++) {
          delay(1000);
        }
      }
    }

It will be wildly inaccurate though, because the clock is inaccurate and will also drift with temperature, made worse because a resonator is used instead of a crystal.

You will get nowhere near an accuracy of a few minutes per month this way, whatever "delaying" method you use; the hardware isn't up to it.


body:
Yes, the delay() will work, as will other methods based on the millis() counter. However, delay() will make it impossible to do something else in the meantime.

Look up [Blink without delay](https://www.arduino.cc/en/tutorial/BlinkWithoutDelay) for an example of how to accomplish such a delay while being able to do other things in your code while waiting.

**Casting**

When dealing with large numbers such as your 24-hour delay, make sure to explicitly cast those numbers as `unsigned long`, or expressing them with the "UL" extension (like for example `86400000UL`). This explicitly tells C++ to expect an "unsigned long" (which in Arduino Uno terms is a 32-bit unsigned number).

In your case (with such an obviously large number), the compiler will automatically choose the right type. In other cases (for example, if you change the expression to `24*60*60*1000`), the compiler will not automatically generate an unsigned long and you need to force it by changing the first part of the expression to an unsigned long: `24UL*60*60*1000` or, alternatively `(unsigned long) 24*60*60*1000`.

**Accuracy**

The accuracy of the timing will be dependent on the type of oscillator on your particular Arduino board. Many Arduinos or their clones use a Ceramic Oscillator that generally have an accuracy of [about 0.1 to 0.5%][1], meaning a possible deviation of 43 seconds per day and as such maybe too inaccurate for your purposes. If your Arduino has a Crystal oscillator, it will be much more accurate (to something like 150ppm, meaning a maximum deviation of about 1 second per day under normal conditions).

  [1]: https://www5.epsondevice.com/en/information/technical_info/pdf/wp_20130425_material.pdf


body: You could try enclosing the Uno in a temperature controlled "oven", say a plastic enclosure with a very low power heater (even a suitable resistor might do) and thermo sensor in with it. It should reduce some of the variation in the crystal frequency.


message:
Cannot successfully implement singleton

I have spent the better part of today trying to figure out why I can't get this to work...

I have this project where, because of previous design considerations, have implemented a singleton class that initializes a bunch of separate sensors in this system that I am running.

The system was originally built for the Particle Boron, but now I am trying to make it work with the Adafruit Feather M0, so I have had to refactor several things and omit lots of lines of Particle RTOS specific things.

However, in doing this, I find that my singleton class no longer works.

**Sensors.h:**
```
.
.
.

class Sensors{

    static Sensors *instance;

public:
    static Sensors *getInstance() {
        if (!instance) {
            instance = new Sensors;
        }
        return instance;
    }

}

private:
    Sensors();

.
.
.
```

**Sensors.cpp:**

```
.
.
.

Sensors::Sensors() : dht22(DHTPIN, DHTTYPE) {
#ifdef PLATFORM_ID
    sensorLog("app.Sensors");
#endif
}

.
.
.
```

**main.ino:**
```
.
.
.

// Sensors
Sensors *Sensors::instance = nullptr;
Sensors *allSensors = allSensors->getInstance();

void setup(){

.
.
.
```

As I try to compile this with ArduinoISP, no matter what I try, I get the following error:

```
sketch/main.ino.cpp.o: in function `Sensors::getInstance()':
sketch/lib/Sensors/src/Sensors.h:23: undefined reference to `Sensors::Sensors()'
collect2: error: ld returned 1 exit status
exit status 1
[Error] Exit with code=1
```

I have tried things like changing the line
```
instance = new Sensor;
```
to
```
instance = new Sensor();
```
making the ```instance``` public, changing the Sensor constructor, but all of this to no avail. Could this be a compiler issue? Why would this work on a Particle board, but not an Adafruit Feather M0?

body:
Singletons aren't a thing in Arduino. Sure, you *could* do it, but in general you'd make a class then instantiate a global object for that class. Most often that global object is instantiated in the library itself, not the sketch.

Unless you're using an advanced chip with an RTOS (such as ESP32) and making use of the threads of that RTOS heavily there is no benefit to having a singleton.

But to answer your actual question: it's probably because you are trying to use the `Sensors()` constructor at a time before the compiler knows what the `Sensors()` constructor is. You would have to add some form of forward declaration so that the compiler knows what you mean when you talk about the `Sensors()` constructor.  In general a simple:

    class Sensors;

at near the top of your header before the class is actually defined can help in these situations;


body:
I had the same problem when referencing classes from multiple files, remember to put at the top of your header file (ending in .h) `#pragma once` on files that get referenced more than once!

Edit1: Also after you declare your class you need to specify where your static variable will be stored.
After the class declaration write:

type *Class::variable;

To declare the static variable.

For example:

    #pragma once
    //#includes

    class Screen
    {
    protected:
      static void (*StateMachineStep)(int);
      static SSOLED *oled;
      static Player *player;

    public:
      Screen() {}

    };

    void (*Screen::StateMachineStep)(int);
    SSOLED *Screen::oled;
    Player *Screen::player;

Edit2: formatting


message:
circuit breaker/fuse necessary for IoT home monitor?

In most 12v CCTV power supplies, each power cable is behind a glass fuse.  I haven't seen fuses or circuit breakers used when distributing 5v power used in IoT projects.  Is there a reason overcurrent protection is not needed in these projects?

edit:
I'm thinking specifically about fire safety.  e.g. the risk of a short circuit overheating 22awg wire run through the house?

body:
> Is there a reason overcurrent protection is not needed in these projects?

You're comparing apples and oranges.

The two systems are completely different and have different concerns.

Case in point:

* You want to burgle somewhere with CCTV installed. You can creep up on one camera unobserved.
* You know a little about electronics and figure if you cut the feed to the camera you can short out the power and blow the whole system, thus letting you wander in unobserved.

But there's fuses on each feed, so all you do is disable the *one* camera and everything else is fine, catching you red handed.

Go directly to jail. Do not pass go. Do not collect £200.

Now... do you really care that much if all your home temperature sensors lose power because of a fault in one? Probably not. And the chances of there being a fault other than from human negligence is slim. Sure, you *could* add fuses, but why add the expense? It's really not needed for such a non-critical system.

----

> edit: I'm thinking specifically about fire safety. e.g. the risk of a short circuit overheating 22awg wire run through the house?

22AWG wire has a resistance of about 53Ω per km. Say you have a loop of cable 20m long (10m there and 10m back again) and it shorted out at the far end. That's round about 1Ω.

At 5V you'd be drawing 5A of current.

If you have a really powerful power supply then it would try and supply that, and the wire would warm up - giving off about 25W of heat *over the entire length*. You might feel a bit of warmth from it.

Of course, most people would be using a smaller power supply than that for simple IoT things, so the power supply would just go "No. You're not having that!" and would die, or its internal fuse would blow. Or it would drop the voltage and get hot itself.

The chance of being able to start a fire from 5V over 22AWG from a normal power supply is pretty much zero. You're more likely going to start a fire from using a low quality power supply that itself melts and catches fire (i.e., a counterfeit Chinese phone charger).

With a very powerful power supply (tens of amps or more) and a short circuit close to the source (so low resistance) the wire will melt. Just that. It'll melt. Once melted there's no circuit, so nothing else happens. There's your fuse right there.

Once a wire has melted it doesn't continue to burn. And you don't get arcs at low voltages. It takes a lot of work to start a fire from low voltages. A lot of work and a lot of current.


message:
Trouble programming custom ATMEGA2560 board

I need some help. I copied the heart of MEGA2560 design into a new project. I have the new PCBs with blank MCUs and now I need to get things programmed. (I have an existing project that runs on a MEGA2560)

I was able to get the MEGA16U2 programmed using the procedure here: https://www.arduino.cc/en/Hacking/DFUProgramming8U2, (I loaded "Arduino-usbserial-atmega16u2-Mega2560-Rev3.hex") and it shows up in the Arduino IDE.

I got the ATMEGA2560 bootloader loaded using the Arduino-as-ISP instructions here: https://www.arduino.cc/en/Tutorial/ArduinoISP

But, now when I try to program my board with the with Arduino IDE (through the USB connection of the MEGA16U2), I just get:

```
avrdude: stk500v2_ReceiveMessage(): timeout
```

The full output of the IDE is:

```
Sketch uses 30056 bytes (11%) of program storage space. Maximum is 253952 bytes.
Global variables use 1280 bytes (15%) of dynamic memory, leaving 6912 bytes for local variables. Maximum is 8192 bytes.
/home/xxxxx/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude -C/home/xxxxx/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf -v -patmega2560 -cwiring -P/dev/ttyACM0 -b115200 -D -Uflash:w:/tmp/arduino_build_464802/yyyyy.ino.hex:i

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/home/xxxxx/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf"
         User configuration file is "/home/xxxxx/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/ttyACM0
         Using Programmer              : wiring
         Overriding Baud Rate          : 115200
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer

avrdude done.  Thank you.

An error occurred while uploading the sketch
```

I can see the RX led of the MEGA16U2 flashing, and the data at the RX pin of the ATMEGA2560 IC, indicating that data is getting to the MCU from the IDE, but there is no corresponding  TX activity.

The IDE and USB cable can program an Elegoo MEGA2560 clone with no problem.

Is this a baud rate problem? A protocol problem? What should be my next debugging step?

Thanks!

---

EDIT: Per Nick Gammon's comment, I have run his chip detector script. Here is the output:

```

Atmega chip detector.
Written by Nick Gammon.
Version 1.20
Compiled on Sep  5 2020 at 07:17:55 with Arduino IDE 10812.
Attempting to enter ICSP programming mode ...
Entered programming mode OK.
Signature = 0x1E 0x98 0x01
Processor = ATmega2560
Flash memory size = 262144 bytes.
LFuse = 0xFF
HFuse = 0xD8
EFuse = 0xFD
Lock byte = 0xCF
Clock calibration = 0x88
Bootloader in use: Yes
EEPROM preserved through erase: No
Watchdog timer always on: No
Bootloader is 8192 bytes starting at 3E000

Bootloader:

3E000: 0x0D 0x94 0x89 0xF1 0x0D 0x94 0xB2 0xF1 0x0D 0x94 0xB2 0xF1 0x0D 0x94 0xB2 0xF1

<....snipped for length....>

3FFF0: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

MD5 sum of bootloader = 0xD9 0xE6 0x6B 0x4E 0xD1 0xA6 0x11 0x2C 0x61 0x8F 0x9B 0xD5 0x5D 0x24 0xE2 0x13
Bootloader MD5 sum not known.

First 256 bytes of program memory:

00: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
10: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
20: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
30: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
40: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
50: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
60: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
70: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
80: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
90: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
A0: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
B0: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
C0: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
D0: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
E0: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
F0: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

Programming mode off.

```

body:
As per the comments your output shows that the chip is working "normally" in that it reacts to the chip detector sketch. Thus the bulk of the design/implementation is OK.

Referring to [Engbedded Atmel AVR® Fuse Calculator](https://www.engbedded.com/fusecalc/) your fuse settings means the processor is expecting an external crystal oscillator. The bootloader expects (I think) a 16 MHz crystal (with appropriate capacitors). If you have not provided this then the bootloader will be running at the wrong baud rate (so to speak) — or not at all — and not react to attempts to download it by serial programming.

If you have a different frequency crystal then you may be able to work around this by adjusting the baud rate in the boards.txt file by an appropriate scaling factor.

The chip detector sketch worked because that uses ICSP programming, which provides its own clock.


message:
Arduino Keyboard starts lower case (but it shouldn't)

So I flashed the [KeyboardMessage][1] example to my [Arduino SS Micro ATmega32U4][2].

When I open an editor and push the button, I would assume the output to be

> Zou pressed the button XX times.

(The "Z" is because I use a German keyboard)

In some editors (Arduino IDE, LibreOffice) this assumption is fulfilled.

However, in several other editors (Linux Shell, gedit), **most of the times** the output is

> zou pressed the button 1 times.

starting with a lower case "z".

I use a Debian Testing computer. The only thing I changed in the sketch was the `buttonPin` as my button is soldered to pin 11.

I noticed, that this problem doesn't occur when the button is pressed a second time shortly after the first message. To investigate this, I coded a [little sketch][3] to find the threshold.

This is what I got (in gedit)

[![output][4]][4]

As line 8 shows, even after 70 millis, the upper case start is not reliable, however, somewhere after 250 millis, the error occurs every time.

My questions are:

 1. What could be the cause for this issue?
 2. How can it be fixed (if necessary, I also welcome a workaround)?

Please tell me if you need any additional information.

[edit]
After slightly altering the script, I noticed, that the problem doesn't only occur on the start of a line, but also (although less often) later in the output. See lines 24, 31 and 52 for example

[![enter image description here][5]][5]

  [1]: https://www.arduino.cc/en/Tutorial/KeyboardMessage
  [2]: https://circuit.rocks/ss-micro-atmega32u4-arduino-compatible.html
  [3]: https://gist.github.com/speendo/c4001a6bf2fdecce148a2c1094cc10fd
  [4]: https://i.stack.imgur.com/k1I8Y.png
  [5]: https://i.stack.imgur.com/YiWd3.png

body:
I am not sure I have the answer to your problem, just a collection of
observations that hopefully steer you in the right direction.

According to your nopaste link, when you send "ON", the first four
keyboard events received by `xev` are: press(Shift\_L), press(O),
release(Shift\_L), release(o). One may notice that there is no point in
releasing the Shift key if it's going to be pressed again right away,
but let's assume that simply holding Shift is not such a useful
optimization. The detail that strikes me is that the last two events
look backwards: you usually release the letter _before_ releasing Shift.
As a result of releasing Shift first, the release event for the O key
reports lowercase "o" as a keysym. I tried this backward way of
releasing the keys on a real keyboard, but both gnome-terminal and gedit
correctly registered the uppercase letters.

Another detail apparent in the xev dump is that the two key presses
(Shit and O) happen at the exact same time. Ditto for the corresponding
key releases. Looking at the source of the Keyboard library, it appears
that both key presses are sent to the PC as a single "key report". Same
for the key releases. This is contrary to what a real keyboard does:
actuations on the Shift keys are reported immediately, irrespective of
whether other keys are actuated.

You may try to modify the Keyboard library so that the actuations on
Shift are sent in their own reports. Maybe something like this
(**warning**: completely untested):

```diff
diff --git a/src/Keyboard.cpp b/src/Keyboard.cpp
index 4a948f6..9fbf7b6 100644
--- a/src/Keyboard.cpp
+++ b/src/Keyboard.cpp
@@ -239,6 +239,7 @@ size_t Keyboard_::press(uint8_t k)
   }
   if (k & 0x80) {      // it's a capital letter or other character reached with shift
    _keyReport.modifiers |= 0x02; // the left shift modifier
+   sendReport(&_keyReport);  // send the shift key by itself
    k &= 0x7F;
   }
  }
@@ -270,6 +271,7 @@ size_t Keyboard_::press(uint8_t k)
 size_t Keyboard_::release(uint8_t k)
 {
  uint8_t i;
+ bool has_shift = false;
  if (k >= 136) {   // it's a non-printing key (not a modifier)
   k = k - 136;
  } else if (k >= 128) { // it's a modifier key
@@ -281,7 +283,7 @@ size_t Keyboard_::release(uint8_t k)
    return 0;
   }
   if (k & 0x80) {       // it's a capital letter or other character reached with shift
-   _keyReport.modifiers &= ~(0x02); // the left shift modifier
+   has_shift = true;
    k &= 0x7F;
   }
  }
@@ -295,6 +297,10 @@ size_t Keyboard_::release(uint8_t k)
  }

  sendReport(&_keyReport);
+ if (has_shift) {
+  _keyReport.modifiers &= ~(0x02); // the left shift modifier
+  sendReport(&_keyReport);   // release shift after releasing the letter
+ }
  return 1;
 }

```

Alternatively, as suggested by @jstola in a comment, you may try to
press the Shift key by itself. Maybe you don't need to care about the
key release, or about any character but the first one (as it is the only
one that seems to cause problems). A minimal workaround to try would be:

```cpp
Keyboard.press(KEY_LEFT_SHIFT);
Keyboard.println("ON");
```


message:
Powering an esp32cam by a battery

I have an [esp32cam](https://www.aliexpress.com/item/32994222661.html?src=google&albch=shopping&acnt=494-037-6276&isdl=y&slnk=&plac=&mtctp=&albbt=Google_7_shopping&aff_platform=google&aff_short_key=UneMJZVf&&albagn=888888&albcp=9441019410&albag=95283287465&trgt=296904914040&crea=en32994222661&netw=u&device=c&albpg=296904914040&albpd=en32994222661&gclid=Cj0KCQjw7sz6BRDYARIsAPHzrNIBCyBnIv8PYFNA9XixKB9zNyEYuIYPcMHwMwKJoxjWxvYwV5oM4tIaAp8oEALw_wcB&gclsrc=aw.ds) that I've [programmed and powered via an FTDI connected to a computer's USB](https://dronebotworkshop.com/esp32-cam-intro/). Now that this stage is over, I'd like to run it portably, using some sort of battery.

The esp32cam has a 5V input (also a 3.3V input which word is should be avoided because it causes brownout). I'm wondering if it's possible to power it (for a short period) using a 7.3V, 9V or 12.3V battery. All the datasheets I've seen seem to specify the input range is 5V, but, for the esp32 (non-cam version), [unregulated 5V-12V seems to permissible](https://techexplorations.com/guides/esp32/begin/power/). Is this true for the esp32cam? Also, what is the right way to search for this?

body:
The official ESP32-CAM has a AMS1117 voltage regulator that creates the 3.3V for the ESP.

The AMS1117 has an Absolute Maximum Input Voltage of 15V. It has a Dropout Voltage of 1.1-1.3V.

So you should stay above 4.6V to be on the safe side.

Since it's a linear voltage regulator, using a higher voltage battery has no advantage, as the "excess voltage" is converted to heat. It could even damage the regulator if too much heat is created.

You should pick the battery with the lowest voltage that still produces 4.6V when almost empty. So you could use the 7.3V battery you indicated. I'm assuming this is a 2-cell Li-ion battery, that has a voltage of 8.4V when full, and around 6V when empty. Which nicely fits your requirements.


message:
How to break out the due power supply and USB connectors?

I am planning a build with my own enclosure for the arduino due. As an alternative i would like to bypass the power jack and usb port that are factory soldered onto the board, in order to use jacks mounted on the enclosure, along with a power switch.

I've looked at the info regarding the boards pin configuration at https://www.arduino.cc/en/pmwiki.php?n=Main/arduinoBoardDue, and would appreciate if someone could confirm or correct this:

1. Can i use an external 9V adapter through a jack connected to the Vin and GND pins, respectively?

2. According to [This question][1], you can't connect an alternative programming USB port to Serial 0 TX/RX pins (Mega board). If this applies to the due as well, what do i need to break out the programming USB port?

Edit: Perhaps [one of these puppies][2] is the least complicated solution?

  [1]: https://arduino.stackexchange.com/questions/47480/are-pins-0-and-1-rx-and-tx-parallel-with-the-usb-jack-can-i-connect-another-u
  [2]: https://www.adafruit.com/product/3258

body:
so 1 - yes. the VIN pin has a common trace with the barrel jack, you can verify with a multimeter in continuity/beep mode. ive actually put power out through the barrel jack on a mega.

2- i cant find a clear schematic for the due at the moment, but on the mega the rx/tx pins are also common with the usb pins, thus they are not usable while plugged into usb


message:
Play sound on top of background music using arduino uno tmrpcm library

We designed a big piano with 15 buttons on it. Every button has a proximity sensor. Whenever users interact with the sensor a specific sound plays for that button. My code is working fine for this purpose but now I want to add background music. Our piano button sound should play on top of that background music. I am using tmrpcm library, and I already added a bg music but when I interact with the sensor, bg music stops and starts from the beginning right after the piano button sound stops. Is there a way to play a sound without interrupting a bg music. Any help will be appreciated.

body:
Assuming you are using an Arduino Uno, You didn't say. As there are many Arduino platforms these days.

As the [tmrpcm library][1] is using the [PWM  (Pulse Width Modulator) HW (Hard Ware)][2] to recreate the sound waves from the WAV file on the SDCard, the PWM is not available for creating the sounds from your piano application (you didn't say what piano application you were using).  That said, it is not impossible to re-write both applications to SUM the two wave forms together mathematically before resampling the SUM and writing that sample value to the PWM HW to simulate the SUM of the two wave forms.  However, this is likely not trivial and it is also likely the [Arduino Uno][3] processor (an [Atmel ATmega328P][4]) will not be powerful enough (perform the math fast enough) to keep up with normal sound playback.

It would likely be much simpler to use 2 Arduino Uno boards and sum the sound from the sound file application and the piano application using analog techniques external from the Arduno Uno boards.

  [1]: https://github.com/TMRh20/TMRpcm
  [2]: https://en.wikipedia.org/wiki/Pulse-width_modulation
  [3]: https://store.arduino.cc/usa/arduino-uno-rev3?gclid=Cj0KCQjw7sz6BRDYARIsAPHzrNL8aVQbqWM4sE5qDRPXdlLgkzKT1edt8cn9HgS7z7tyXz4VYCJFd_EaAnTREALw_wcB
  [4]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf


message:
How to implement a tilt compensated compass?

So i was trying to implement a tilt compensated compass, using HMC5883L and MPU6050. The problem i am facing is, there are 2 equations for tilt compensation

**Tilt Compensated X:**   X,Y,Z are compass output (raw output)

```new_X =  X*cos(pitch) + Y*sin(roll)*sin(pitch) – Z*cos(roll)*sin(pitch)```

**Tilt Compensated Y:**

```new Y =  Y*cos(roll) + Z*sin(roll)```

**Final Heading :**
```Azimuth =  atan2(Y, X) * RAD_TO_DEG```

The angles which i am getting from the mpu are gyro-drift corrected angles which are coming through a kalman filter. Those angles are fed to these above equations and after ```atan2``` i get the tilt compensated heading. But the issue/observation here is, when i rotate the body(on which the compass and mpu are) along the Z axis (YAW axis) the heading doesn't change(sort of locked on), but changes when i tilt the body in X/Y.
I searched for thorough references, but wasn't able to find any!
Here is my code snippet (uses *compass* part form adafruit library):
```
double HEADING(double r, double p){
  sensors_event_t event;
  mag.getEvent(&event);
  r = r * (PI/180);
  p = p * (PI/180);
  double x = (event.magnetic.x)*cos(p) + (event.magnetic.y)*sin(r)*sin(p) - (event.magnetic.z)*cos(r)*sin(p);
  double y = (event.magnetic.y)*cos(r) + (event.magnetic.z)*sin(r);

  float heading = atan2(y,x);

  float declinationAngle = 0.366667 * (PI/180);// (0°22')positve declination
  heading += declinationAngle;

  if(heading < 0)
    heading += 2*PI;

  if(heading > 2*PI)
    heading -= 2*PI;

  heading = heading * 180/PI;

  return heading;
}
```
**The HMC5883L data acquisition I wrote :**
```
// i just need a direction reference not actual heading, just to keep my drone
// steady on yaw axis with reference to that direction reference but it shall be Tilt compensated
#include<Wire.h>

#define MAG 0x1E

#define R 0
#define P 1
#define Y 2

float mag_raw[3],h;
float CMP_DEC = 0.36667 * (PI/180);

void setup(){
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(400000);

  Wire.beginTransmission(MAG);
  Wire.write(0x02);
  Wire.write(0x00);
  Wire.endTransmission(true);

}

void loop(){
  Wire.beginTransmission(MAG);
  Wire.write(0x03);
  Wire.endTransmission(false);
  Wire.requestFrom(MAG,6,true);

  mag_raw[R] = Wire.read() << 8 | Wire.read();
  mag_raw[P] = Wire.read() << 8 | Wire.read();
  mag_raw[Y] = Wire.read() << 8 | Wire.read();

  h = atan2(mag_raw[P],mag_raw[R]);

//  h += CMP_DEC;

  if(h < 0) h+= (2*PI);
  if(h > (2*PI)) h -= (2*PI);
  h *= (180/PI);

//  Serial.print("X : ");
//  Serial.print(mag_raw[R]);
//  Serial.print(" Y : ");
//  Serial.print(mag_raw[P]);
//  Serial.print(" Z : ");
//  Serial.print(mag_raw[Y]);

  Serial.print(" H : ");
  Serial.println(h);

}
```
Some guidance will be very helpful!

body:
Inspecting your code, it does not appear you are [compensating the raw magnetometer values for soft and hard iron effects][1].  These terms roughly refer to adjusting the range and magnitude of each of the individual magnetometers (X, Y and Z).  Some magnetometer manufactures allow writing these compensation values into the chip.  Even then the developer and user will still need to perform some form of calibration as the magnetometer can not predict under what conditions the magnetometer will be used.  [Here is another explanation using matrices of hard and soft iron compensation][2].

Once the compass produces expected results on a flat surface parallel to the surface of the earth (in a place on earth where the magnetic lines roughly align with true north).  Consider adding tilt compensation.  Accelerometers usually do not need to be compensated as extensively as magnetometers.

This can be done using trigonometric math and [Euler angles][3].  However, as with physical [gambles][4], this can lead to a situation similar to [gimbal lock][5].  Where the trigonometric math goes to infinity.

To avoid a gimbal lock like situation, most tilt compensated compasses use [quaternions][6].  Quaternions use imaginary numbers and matrix math to describe 3 dimensional rotation.

  [1]: https://www.fierceelectronics.com/components/compensating-for-tilt-hard-iron-and-soft-iron-effects
  [2]: https://www.vectornav.com/resources/magnetometer-errors-calibration
  [3]: https://en.wikipedia.org/wiki/Euler_angles
  [4]: https://en.wikipedia.org/wiki/Gimbal
  [5]: https://en.wikipedia.org/wiki/Gimbal_lock
  [6]: https://en.wikipedia.org/wiki/Quaternion


message:
WS2812B Power Supply

I have a WS2812b addressable RGB led ribbon that is 5m (150 RGB leds). I purchased a 5v 10amp power supply to power it; however, whenever I try to use it to power the LED strip the leds start flashing colors like crazy. Is there a reason I would be seeing this behavior or is this a sign of a bad power supply?

The setup is very simple, the data line is coming from an Arduino Uno, the voltage and ground are from the power supply. The program is just one of the sample ones with FastLED library and works "fine" when just powered by the arudino's 5V pin.

Thank you

body: The strip and the Arduino need to share the same ground connection. They are communicating through voltage and voltage is always a difference between two points. The power supply sets the supply voltage as the difference between + and ground. The chips in the strip will then try to measure the voltage on the data line relative to their ground. When the grounds are not connected, the Arduinos output pin is floating somewhere else, depending on external factors. By connecting the grounds, both devices (Arduino and strip) use the same ground value to measure voltages. Only this enables communication between the devices.


message:
Arduino offline commands

I wanted to know if there is a way for my arduino to keep the last command I sent to it before I disconnected it from my computer. Thanks.

body: Arduino always store the last sketch you have uploaded. Even if you disconnect your board and then replug it then it follow the same commands that you gave earlier.


message:
How to clear SoftwareSerial values?

I'm using software serial on my weather station. The way it's supposed to work is that you send an SMS to the device and it replies with the wind speed, etc.

At the moment, The wind speed is detected, waiting for an incoming SMS. The SMS arrives and it sends a response but the response SMS is sent over and over infinitely.
I'm guessing the problem is due to the:

     if (mySerial.available()>0){

As this is what I'm using to test whether the SMS has arrived and presumably, it's then always set to available.

Does anyone know how to basically reset the software serial after the message has been sent?

     #include <SoftwareSerial.h>
     #include <ADSWeather.h>

    SoftwareSerial mySerial(9, 10);

    #define ANEMOMETER_PIN 2
    #define VANE_PIN 0
    #define RAIN_PIN 3

    #define CALC_INTERVAL 1000

    unsigned long nextCalc;
    unsigned long timer;

    int windDir;
    int windSpeed;
    int rainAmmount;

    ADSWeather ws1(RAIN_PIN, VANE_PIN, ANEMOMETER_PIN); //This should configure all pins correctly

    void setup()
    {
      Serial.begin(9600);
      attachInterrupt(digitalPinToInterrupt(RAIN_PIN), ws1.countRain, FALLING); //ws1.countRain is the ISR for the rain gauge.
      attachInterrupt(digitalPinToInterrupt(ANEMOMETER_PIN), ws1.countAnemometer, FALLING); //ws1.countAnemometer is the ISR for the anemometer.
      nextCalc = millis() + CALC_INTERVAL;

      mySerial.begin(9600);   // Setting the baud rate of GSM Module
      delay(100);
    }

    void loop()
    {
      timer = millis();

      int rainAmmount;
      long windSpeed;
      long windDirection;
      int windGust;
      int sent;

      ws1.update(); //Call this every cycle in your main loop to update all the sensor values

      if(timer > nextCalc)
      {

        nextCalc = timer + CALC_INTERVAL;
        rainAmmount = ws1.getRain();
        windSpeed = ws1.getWindSpeed();
        windDirection = ws1.getWindDirection();
        windGust = ws1.getWindGust();

    //     windSpeed / 10 will give the interger component of the wind speed
    //     windSpeed % 10 will give the fractional component of the wind speed
        Serial.print("Wind speed: ");
        Serial.print(windSpeed / 10);
        Serial.print('.');
        Serial.print(windSpeed % 10);
        Serial.print(" ");

        Serial.print("Gusting at: ");
        Serial.print(windGust / 10);
        Serial.print('.');
        Serial.print(windGust % 10);
        Serial.println("");

      }

      if (Serial.available()>0)
      {
          RecieveMessage();
      }

      //If an message comes in
     if (mySerial.available()>0){
      // Serial.write(mySerial.read());
      Serial.write("Message received");

      //Send the wind speed response.
      SendMessage();

      //At this point the SendMessage() repeats and the message is sent over and over.
    }
    }

     void SendMessage()
    {
      mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
      delay(1000);  // Delay of 1000 milli seconds or 1 second
      mySerial.println("AT+CMGS=\"NUMRemoved\"\r"); // Replace x with mobile number
      delay(1000);
      mySerial.println("I am SMS from GSM Module");// The SMS text you want to send
      delay(100);
       mySerial.println((char)26);// ASCII code of CTRL+Z
      delay(1000);
    }

     void RecieveMessage()
    {
      mySerial.println("AT+CNMI=2,2,0,0,0"); // AT Command to receive a live SMS
      delay(1000);
     }

     void serialFlush(){
      while(mySerial.available() > 0) {
        char t = mySerial.read();
      }
    }

body:
For the hardware serial port, the buffer is 64 and I was reading at least 100 times. Every read will clear one byte of data from the serial buffer at a time.

For the software serial port, you do a dummy read and then check whether the buffer is empty or not using

        while(mySerial.available()>0)  {
           dummy = mySerial.read();
        }

So, in summary, you have to read the buffer until it is empty.

**Useful notes:**

1. You should be knowing when to expect actual data and when not to
2. have a way to identify the valid messages (some fixed header bytes)
3. have a way to validate the contents (checksum)

Leave a comment if you have any questions


body:
     if (mySerial.available()>0){

You are checking if any serial data has arrived. Then you **never** read it. So naturally it is always available. You have a serialFlush function which does read it, however that function is never called.

You need, however, to read more than one byte. Otherwise you will send an SMS for every byte in the input message.


body:
```c++
if (mySerial.available() > 0) {
  // Serial.write(mySerial.read());
  Serial.write("Message received");

  //Send the wind speed response.
  SendMessage();

  mySerial.begin(9600);   // Reset myserial buffer

  //At this point the SendMessage() repeats and the message is sent over and over.
}
```