message:
How to connect multiple I2C devices?

I am trying connecting I2C OLED SSD1306 and I2C INA219 on ESP32 but without success.

**First try:**

    #include <WiFi.h>
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_INA219.h>
    Adafruit_INA219 ina219;

    #define SDA1 21  //OLED SSD1306
    #define SCL1 22  //OLED SSD1306
    #define SDA2 5  //INA219
    #define SCL2 4  //INA219

    float shuntvoltage = 0;
    float busvoltage = 0;
    float current_mA = 0;
    float current_A = 0;
    float loadvoltage = 0;
    float power_W = 0;

    #define SCREEN_WIDTH 128
    #define SCREEN_HEIGHT 64
    #define OLED_RESET   0
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

    const char* ssid     = "SSID";
    const char* password = "PASSWORD";

    IPAddress local_IP(192, 168, 0, 241);
    IPAddress gateway(192, 168, 0, 230);
    IPAddress subnet(255, 255, 255, 0);
    IPAddress primaryDNS(8, 8, 8, 8);
    IPAddress secondaryDNS(8, 8, 4, 4);

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

      Wire.begin(SDA1, SCL1);

      if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
        Serial.println(F("SSD1306 allocation failed"));
        for(;;); // Don't proceed, loop forever
      }

       display.fillScreen(BLACK);
       display.setTextColor(WHITE);
       display.setTextWrap(false);

       startWiFi();

      Wire.begin(SDA2, SCL2);
      ina219.begin();

      display.ssd1306_command(SSD1306_DISPLAYOFF);
      delay(5000);
      display.ssd1306_command(SSD1306_DISPLAYON);
      display.println("Awake!");
      display.display();

    }

    void loop()
    {
          shuntvoltage = ina219.getShuntVoltage_mV();
          busvoltage = ina219.getBusVoltage_V();
          current_mA = ina219.getCurrent_mA();
          loadvoltage = busvoltage + (shuntvoltage / 1000);
          current_A = current_mA / 1000;
          power_W = current_A * loadvoltage;

          Serial.println("");
          Serial.print("Bus Voltage:   "); Serial.print(busvoltage); Serial.println(" V");
          Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
          Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
          Serial.print("Current:       "); Serial.print(current_mA); Serial.println(" mA");
          Serial.print("Power:       "); Serial.print(power_W); Serial.println(" w");
          Serial.println("");

      delay(1000);

      display.stopscroll();
      display.fillScreen(BLACK);
      display.invertDisplay(0);

      testscrolltext("TESTING");    // Draw scrolling text

    }

    const char* wl_status_to_string(wl_status_t status) {
      switch (status) {
        case WL_NO_SHIELD: return "WL_NO_SHIELD";
        case WL_IDLE_STATUS: return "WL_IDLE_STATUS";
        case WL_NO_SSID_AVAIL: return "WL_NO_SSID_AVAIL";
        case WL_SCAN_COMPLETED: return "WL_SCAN_COMPLETED";
        case WL_CONNECTED: return "WL_CONNECTED";
        case WL_CONNECT_FAILED: return "WL_CONNECT_FAILED";
        case WL_CONNECTION_LOST: return "WL_CONNECTION_LOST";
        case WL_DISCONNECTED: return "WL_DISCONNECTED";
      }
    }

    void printWifiStatus() {
      Serial.println("");
      Serial.println("WiFi connected.");
      Serial.print("SSID: ");
      Serial.println(WiFi.SSID());

      IPAddress ip = WiFi.localIP();
      Serial.print("IP Address: ");
      Serial.println(ip);

      Serial.print("Gateway: ");
      Serial.println(WiFi.gatewayIP());
      Serial.print("Subnet: ");
      Serial.println(WiFi.subnetMask());
      Serial.print("Primary DNS: ");
      Serial.println(primaryDNS);

      long rssi = WiFi.RSSI();
      Serial.print("signal strength (RSSI):");
      Serial.print(rssi);
      Serial.println(" dBm");

      Serial.printf("BSSID: %s\n", WiFi.BSSIDstr().c_str());
      Serial.println("Connected to wifi");
    }

    void startWiFi() { // Start a Wi-Fi access point, and try to connect to some given access points. Then wait for either an AP or STA connection

    typedef enum {
        WL_NO_SHIELD        = 255,   // for compatibility with WiFi Shield library
        WL_IDLE_STATUS      = 0,
        WL_NO_SSID_AVAIL    = 1,
        WL_SCAN_COMPLETED   = 2,
        WL_CONNECTED        = 3,
        WL_CONNECT_FAILED   = 4,
        WL_CONNECTION_LOST  = 5,
        WL_DISCONNECTED     = 6
    } wl_status_t;

      WiFi.begin(ssid, password);
      Serial.print("MAC Address: ");
      Serial.println(WiFi.macAddress());
      WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
      WiFi.mode(WIFI_STA);
      Serial.println("Connecting Wifi...");
      delay(5000);

      // Wait for connection
      while (WiFi.status() != WL_CONNECTED) {
        Serial.println("NOT Connected to wifi");
        Serial.print("Status: ");
        Serial.println(wl_status_to_string(WiFi.status()));
        WiFi.begin(ssid, password);
      WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
        WiFi.mode(WIFI_STA);
        delay(5000);
        ESP.restart();
      }

      //If connection successful show IP address in serial monitor
      Serial.println("Connected to wifi");
      printWifiStatus();

    }

    void testscrolltext(char * text) {
      display.clearDisplay();

      display.setTextSize(2); // Draw 2X-scale text
      display.setTextColor(WHITE);
      display.setCursor(10, 0);
      display.println(F(text));
      display.display();      // Show initial text
      delay(100);

      // Scroll in various directions, pausing in-between:
      display.startscrollright(0x00, 0x0F);
      delay(2000);
      display.stopscroll();
      delay(1000);
      display.startscrollleft(0x00, 0x0F);
      delay(2000);
      display.stopscroll();
      delay(1000);
      display.startscrolldiagright(0x00, 0x07);
      delay(2000);
      display.startscrolldiagleft(0x00, 0x07);
      delay(2000);
      display.stopscroll();
      delay(1000);
    }

**OLED doesn't work. But INA219 works perfectly.**

**Second try:**

    #include <WiFi.h>
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_INA219.h>
    Adafruit_INA219 ina219;

    #define SDA1 21  //OLED SSD1306
    #define SCL1 22  //OLED SSD1306
    #define SDA2 5  //INA219
    #define SCL2 4  //INA219

    TwoWire I2Cone = TwoWire(0);
    TwoWire I2Ctwo = TwoWire(1);

    float shuntvoltage = 0;
    float busvoltage = 0;
    float current_mA = 0;
    float current_A = 0;
    float loadvoltage = 0;
    float power_W = 0;

    #define SCREEN_WIDTH 128
    #define SCREEN_HEIGHT 64
    #define OLED_RESET   0
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

    const char* ssid     = "SSID";
    const char* password = "PASSWORD";

    IPAddress local_IP(192, 168, 0, 241);
    IPAddress gateway(192, 168, 0, 230);
    IPAddress subnet(255, 255, 255, 0);
    IPAddress primaryDNS(8, 8, 8, 8);
    IPAddress secondaryDNS(8, 8, 4, 4);

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

      I2Cone.begin(SDA1,SCL1,400000);
      I2Ctwo.begin(SDA2,SCL2,400000);

      I2Cone.beginTransmission(0x3C);
      I2Ctwo.beginTransmission(0x40);

      if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
        Serial.println(F("SSD1306 allocation failed"));
        for(;;); // Don't proceed, loop forever
      }

       display.fillScreen(BLACK);
       display.setTextColor(WHITE);
       display.setTextWrap(false);

      startWiFi();
      ina219.begin();

      display.ssd1306_command(SSD1306_DISPLAYOFF);
      delay(5000);
      display.ssd1306_command(SSD1306_DISPLAYON);
      display.println("Awake!");
      display.display();

    }

    void loop()
    {

          shuntvoltage = ina219.getShuntVoltage_mV();
          busvoltage = ina219.getBusVoltage_V();
          current_mA = ina219.getCurrent_mA();
          loadvoltage = busvoltage + (shuntvoltage / 1000);
          current_A = current_mA / 1000;
          power_W = current_A * loadvoltage;

          Serial.println("");
          Serial.print("Bus Voltage:   "); Serial.print(busvoltage); Serial.println(" V");
          Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
          Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
          Serial.print("Current:       "); Serial.print(current_mA); Serial.println(" mA");
          Serial.print("Power:       "); Serial.print(power_W); Serial.println(" w");
          Serial.println("");

      delay(1000);

      display.stopscroll();
      display.fillScreen(BLACK);
      display.invertDisplay(0);

      testscrolltext("TESTING");    // Draw scrolling text

    }

**OLED works perfectly. But INA219 doesn't work.**

How to make both OLED SSD1306 and INA219 works simultaneously?

Please help...

body:
I have used a 128*64 oled display with a ina219. Both of them were working fine. Check the below code. Hope it helps.

    #include <Adafruit_INA219.h>
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_GFX.h>

    #define I2C_OLED_ADDRESS    0x3C
    #define I2C_INA219_ADDRESS  0x40

    #define OLED_RESET  4

     Adafruit_SSD1306 oled(OLED_RESET);
     Adafruit_INA219 ina219;

     void initialize_device () {

      oled.begin (SSD1306_SWITCHCAPVCC, I2C_OLED_ADDRESS);
      oled.setTextColor (WHITE);
      oled.clearDisplay ();

      ina219.begin ();
    }

     void refresh_oled (float current_ma, float load_voltage) {
      oled.clearDisplay ();

      oled.setTextSize (2);
      oled.setCursor (0, 0);
      oled.print ("V:"); oled.print (load_voltage); oled.print ('V');
      oled.setCursor(0, 20);
      oled.print ("I:"); oled.print (current_ma); oled.print ("mA");

      oled.display();
    }

     void setup () {
      initialize_device ();
    }

     void loop () {

      float current_ma = ina219.getCurrent_mA ();
      float load_voltage = ina219.getBusVoltage_V () + (ina219.getShuntVoltage_mV() / 1000);

      refresh_oled (current_ma, load_voltage);

      delay(100);
    }


sender: user

sender: assistant

body:
I think that the issue is during INA219 initialization.

According with the **begin** function of class [Adafruit_INA219][1].

Use:

> ina219.begin(&I2CTwo);

instead of

> ina219.begin();

  [1]: https://github.com/adafruit/Adafruit_INA219/blob/master/Adafruit_INA219.h


body:
Here is the code for connecting I2C OLED SSD1306 and I2C INA219 on ESP32 which will works simultaneously

    #include <WiFi.h>
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_INA219.h>
    Adafruit_INA219 ina219;

    #define SDA 21  //OLED SSD1306 & INA219 pin
    #define SCL 22  //OLED SSD1306 & INA219 pin

    float shuntvoltage = 0;
    float busvoltage = 0;
    float current_mA = 0;
    float current_A = 0;
    float loadvoltage = 0;
    float power_W = 0;

    #define SCREEN_WIDTH 128
    #define SCREEN_HEIGHT 64
    #define OLED_RESET   0
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

    const char* ssid     = "SSID";
    const char* password = "PASSWORD";

    IPAddress local_IP(192, 168, 0, 241);
    IPAddress gateway(192, 168, 0, 230);
    IPAddress subnet(255, 255, 255, 0);
    IPAddress primaryDNS(8, 8, 8, 8);
    IPAddress secondaryDNS(8, 8, 4, 4);

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

      Wire.begin(SDA, SCL);

      if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
        Serial.println(F("SSD1306 allocation failed"));
        for(;;); // Don't proceed, loop forever
      }

       display.fillScreen(BLACK);
       display.setTextColor(WHITE);
       display.setTextWrap(false);

      startWiFi();
      ina219.begin();

      display.ssd1306_command(SSD1306_DISPLAYOFF);
      delay(5000);
      display.ssd1306_command(SSD1306_DISPLAYON);
      display.println("Awake!");
      display.display();

    }

    void loop()
    {

          shuntvoltage = ina219.getShuntVoltage_mV();
          busvoltage = ina219.getBusVoltage_V();
          current_mA = ina219.getCurrent_mA();
          loadvoltage = busvoltage + (shuntvoltage / 1000);
          current_A = current_mA / 1000;
          power_W = current_A * loadvoltage;

          Serial.println("");
          Serial.print("Bus Voltage:   "); Serial.print(busvoltage); Serial.println(" V");
          Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
          Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
          Serial.print("Current:       "); Serial.print(current_mA); Serial.println(" mA");
          Serial.print("Power:       "); Serial.print(power_W); Serial.println(" w");
          Serial.println("");

      delay(1000);

      display.stopscroll();
      display.fillScreen(BLACK);
      display.invertDisplay(0);

      testscrolltext("TESTING");    // Draw scrolling text

    }

    const char* wl_status_to_string(wl_status_t status) {
      switch (status) {
        case WL_NO_SHIELD: return "WL_NO_SHIELD";
        case WL_IDLE_STATUS: return "WL_IDLE_STATUS";
        case WL_NO_SSID_AVAIL: return "WL_NO_SSID_AVAIL";
        case WL_SCAN_COMPLETED: return "WL_SCAN_COMPLETED";
        case WL_CONNECTED: return "WL_CONNECTED";
        case WL_CONNECT_FAILED: return "WL_CONNECT_FAILED";
        case WL_CONNECTION_LOST: return "WL_CONNECTION_LOST";
        case WL_DISCONNECTED: return "WL_DISCONNECTED";
      }
    }

    void printWifiStatus() {
      Serial.println("");
      Serial.println("WiFi connected.");
      Serial.print("SSID: ");
      Serial.println(WiFi.SSID());

      IPAddress ip = WiFi.localIP();
      Serial.print("IP Address: ");
      Serial.println(ip);

      Serial.print("Gateway: ");
      Serial.println(WiFi.gatewayIP());
      Serial.print("Subnet: ");
      Serial.println(WiFi.subnetMask());
      Serial.print("Primary DNS: ");
      Serial.println(primaryDNS);

      long rssi = WiFi.RSSI();
      Serial.print("signal strength (RSSI):");
      Serial.print(rssi);
      Serial.println(" dBm");

      Serial.printf("BSSID: %s\n", WiFi.BSSIDstr().c_str());
      Serial.println("Connected to wifi");
    }

    void startWiFi() { // Start a Wi-Fi access point, and try to connect to some given access points. Then wait for either an AP or STA connection

    typedef enum {
        WL_NO_SHIELD        = 255,   // for compatibility with WiFi Shield library
        WL_IDLE_STATUS      = 0,
        WL_NO_SSID_AVAIL    = 1,
        WL_SCAN_COMPLETED   = 2,
        WL_CONNECTED        = 3,
        WL_CONNECT_FAILED   = 4,
        WL_CONNECTION_LOST  = 5,
        WL_DISCONNECTED     = 6
    } wl_status_t;

      WiFi.begin(ssid, password);
      Serial.print("MAC Address: ");
      Serial.println(WiFi.macAddress());
      WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
      WiFi.mode(WIFI_STA);
      Serial.println("Connecting Wifi...");
      delay(5000);

      // Wait for connection
      while (WiFi.status() != WL_CONNECTED) {
        Serial.println("NOT Connected to wifi");
        Serial.print("Status: ");
        Serial.println(wl_status_to_string(WiFi.status()));
        WiFi.begin(ssid, password);
      WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
        WiFi.mode(WIFI_STA);
        delay(5000);
        ESP.restart();
      }

      //If connection successful show IP address in serial monitor
      Serial.println("Connected to wifi");
      printWifiStatus();

    }

    void testscrolltext(char * text) {
      display.clearDisplay();

      display.setTextSize(2); // Draw 2X-scale text
      display.setTextColor(WHITE);
      display.setCursor(10, 0);
      display.println(F(text));
      display.display();      // Show initial text
      delay(100);

      // Scroll in various directions, pausing in-between:
      display.startscrollright(0x00, 0x0F);
      delay(2000);
      display.stopscroll();
      delay(1000);
      display.startscrollleft(0x00, 0x0F);
      delay(2000);
      display.stopscroll();
      delay(1000);
      display.startscrolldiagright(0x00, 0x07);
      delay(2000);
      display.startscrolldiagleft(0x00, 0x07);
      delay(2000);
      display.stopscroll();
      delay(1000);
    }

**NOTE:** Both OLED SSD1306 and INA219 must be using the same SDA & SCL pins (pin 21 & pin 22 on ESP32).

Hope this will help anyone who has same issue like me.


message:
Why my LCD does not work with this if statement?

#include <LiquidCrystal.h>
    LiquidCrystal lcd(1, 2, 4, 5, 6, 7);
    int greenLedPin = 12;
    int blueLedPin = 11;
    int redLedPin = 8;
    int yellowLEdPin = 9;

    int lightSensorPin = A0;
    int analogValue = 0;

    void setup() {
      // put your setup code here, to run once:
      lcd.begin(16, 2);
      pinMode(greenLedPin, OUTPUT);
      pinMode(blueLedPin, OUTPUT);
      pinMode(redLedPin, OUTPUT);
      pinMode(yellowLEdPin, OUTPUT);
      Serial.begin(9600);
      while (! Serial);

    }

    void loop() {
      // put your main code here, to run repeatedly:
      Serial.println(analogRead(lightSensorPin));
      analogValue = analogRead(lightSensorPin);
      if (analogValue < 50) {

    digitalWrite(redLedPin, HIGH);

      }
      else if (analogValue >= 50 && analogValue <= 99) {
        digitalWrite(yellowLEdPin, HIGH);
      }
      else if (analogValue >= 100 && analogValue <= 300) {

        digitalWrite(blueLedPin, HIGH);
        lcd.print("its bright");
     }
      else {
          digitalWrite(greenLedPin, HIGH);
          lcd.print("its bright");
          }

      delay(3000);
      digitalWrite(greenLedPin, LOW);
      digitalWrite(blueLedPin, LOW);
      digitalWrite(redLedPin, LOW);
      digitalWrite(yellowLEdPin, LOW);
      lcd.clear();

    }
I'm very new to this so sorry if its a dumb mistake and I know my LCD is working right, since I have tested it so all the pins are good.

body:
On the Uno, [pin 0 and 1 are used for Serial](https://www.arduino.cc/reference/en/language/functions/communication/serial/). You can't use pin 1 for Serial in addition to the LCD. In general, it's best to avoid using pins 0 and 1.

You need to change the LCD wiring to use a different pin and update the code accordingly. For example, if you moved the LCD's RS pin connection from pin 1 on your Arduino to pin 13, you would update this line from:

<!-- language-all: lang-cpp -->

    LiquidCrystal lcd(1, 2, 4, 5, 6, 7);

to:

    LiquidCrystal lcd(13, 2, 4, 5, 6, 7);

After that, your LCD should work correctly.


message:
Arduino based fully controlled aquaculture

I am doing a project on aquaculture,so I am using temperature sensor, water level sensor, dissolved oxygen sensor, pH sensor and also 4 motor's and water heater is it possible for a single Arduino to run all these at the same time??

body:
I would suggest finding sensors that work on an I2C bus. This way all the sensors are only using two pins for data. That will free up other outputs for motors, heaters that will probably be on relays or other drivers that need a single or multiple pins for each devices.  As you start to plan it out, if you do run out of pins on a arduino uno, look at the Mega, as it has many more GPIO pins as well as multiple dedicated UART ports.

Bottom line, find your sensors, drivers, see what type of communication they require, and start to make a list of how many separate io pins you need. Then that will tell you which board is suitable for your project.


message:
How to check whether my arduino-mega ADC is sampling correctly?

I have a code which samples the given input signals with sampling rate 256hz. I plotted the graph of FFT and was able to see the peaks at the expected frequencies.But I would like to know whether my ADC is sampling correctly or not?Is there a way to do it?`

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

    const unsigned long READ_PERIOD = 3906;  // 3906 us: 256 Hz
    void loop() {
        static unsigned long lastRead;
        if (micros() - lastRead >= READ_PERIOD) {
            lastRead += READ_PERIOD;
            int val_a0 = analogRead(A0);
            int val_a1 = analogRead(A3);
            int val_a2 = analogRead(A5);
            int val_a3 = analogRead(A7);
           Serial.print(val_a0);
           Serial.print("  ");
           Serial.print(val_a1);
           Serial.print("  ");
          Serial.print(val_a2);
          Serial.print("  ");
            Serial.println(val_a3);
        }
    }

body:
In this case the baud rate will be real bottleneck. You have to send from 110 to 230 bits per reading (1 start bit, 8bits data, 1 stop bit)*(3*2 spaces + 4-16 number characters + 1 line feed).

That means best case (all numbers are less than 10) 349 readings per second. And worst case is 166 readings per second (all readings are more than 999).

So it's about 10% probability to be sampled correctly.

You can check if the next time (with misleading name `lastReading`) is less than current time. That means you are already too slow.


message:
USB Communication between Arduino Nano and UHF Reader module

I am working on a project that requires a UHF reader development kit that can communicate using either RS232 or by USB.  Via USB and a Serial terminal, I have been able to send commands to the reader as well as analyze its response.

My goal is to send these same commands to the reader, but through an Arduino Nano.  My first instinct was to use the RS232, converting the signal via a MAX232.  However, this is for a school project, and my advisor preferred I try to work with USB.  I am familiar with UART communication, and I've been under the assumption that USB operates using UART.

I had purchased a USB converter that gives me access to the pins, but it had two additional pins than I was not expecting: CTS and DTR.  I attempted to communicate despite these pins (just leaving them open, and connecting Rx, Tx, Vcc and GND as I normally would).  When plugged into the UHF reader, the device did power on (as it draws power from the USB connection), however, it did not receive the output signal from the Arduino Nano.

I know that my baud rate and other settings are correct, because, as I have said, communicating via USB and a Serial terminal gives me no problems.  My initial thought is that I need to properly connect the CTS and DTR pins, but immediately I could not find a good reference on how to do this, and I am not entirely convinced this is the issue.  My other thought was that perhaps I am writing out my HEX values wrong from the Arduino, using a line similar to the following, where "UHF_Reader" is defined by SoftwareSerial:

    UHF_Reader.write(0xAA);

However, it appears to me from research that this is indeed the correct way to output HEX values via serial.

My final attempt to resolve this was to connect the micro-USB from the Nano to the USB of the reader, and then use Software Serial in conjunction with the USB converter to analyze the output on a Serial terminal, while powering the Nano via a 5V power supply.  However, since the reader draws power from the USB port, it did not even turn on when I attempted this (I am assuming that the Vcc can only be supplied *from* the USB end?).  Regardless, this attempt proved useless as well.

If anyone can offer any advice, or point me towards any references for something similar, I would much appreciate it!  I have spent a while on this, and I just can't figure out what the problem is.

For reference, the reader I am using is found here: [UHF Reader][1]

And the USB converter I am using is here: [USB Converter][2]

  [1]: https://www.aliexpress.com/item/PR9200-chip-Desktop-USB-UHF-RFID-Reader-writer-3m-long-range-uhf-RFID-module-with-free/32907646941.html?spm=2114.10010108.1000014.12.2e72398fnRnY9K&gps-id=pcDetailBottomMoreOtherSeller&scm=1007.13338.80878.000000000000000&scm_id=1007.13338.80878.000000000000000&scm-url=1007.13338.80878.000000000000000&pvid=c35ca25d-2b3b-4c20-9874-b32aefe03017
  [2]: https://www.amazon.com/WINGONEER-CP2102-Module-Serial-Converter/dp/B01LRVQIFQ/ref=sr_1_2?s=electronics&ie=UTF8&qid=1546528820&sr=1-2&keywords=wingoneer+usb+2.0+to+uart

body:
> I've been under the assumption that USB operates using UART.

No. You have it backwards.  Devices can emulate a UART (known as CDC/ACM) over a USB connection as one of the many possible device profiles, but it is about as far from being a UART as an F1 car is from a Penny Farthing.

USB operates on a strict Master / Slave principle. That is, it has a single master device, called the *Host*, which coordinates all the devices on the bus and makes requests to them.  Everything you plug into a USB system is a *Device* and requires a *Host* to tell it what to do.

Neither the Nano, nor this adaptor you bought, are *Hosts*. They are just *Devices*. And Devices cannot talk to Devices. Only Hosts can talk to Devices.

Which means you need a Host in there somewhere. If you want it controlled by Arduino then you need a USB Host Shield (or something similar) which normally communicates over SPI.

If the device you are trying to talk to uses the CDC/ACM profile then you can use the USB Host Shield with it. If it uses a proprietary profile, like the CH340G or FT232, then getting it to work with the USB Host Shield will be much harder (maybe even impossible) unless you are intimate with the underlying protocol used.


message:
Digispark Attiny85 ultrasonic sensor input problem

I was trying to use ultrasonic with digispark Attiny85 board and used separate pins for trigger and echo, and used MM5451 led controller as a display, I uploaded the code successfully the problem is if the echo pin is connected to it at startup board stops/freezes I don't know but code doesn't work, and if I connect the echo pin few seconds after the board starts everything works fine.

Below is the code I wrote

    #define clock 0
    #define data 1
    #define trig 2
    #define echo 3
    byte c[5]={10,11,11,0,12};
    long dist=0;
    const uint8_t digits[15]={
        B1110111,
        B1000100,
        B1101011,
        B1101110,
        B1011100,
        B0111110,
        B0111111,
        B1100100,
        B1111111,
        B1111110,
        B0111011,
        B0010011,
        B1011101,
        B0111001,
        B0000000
    };
    void setup()
    {
        pinMode(clock,OUTPUT);
        pinMode(data,OUTPUT);
        pinMode(trig,OUTPUT);
        pinMode(echo,INPUT);
        digitalWrite(clock,LOW);
        digitalWrite(data,LOW);
        digitalWrite(trig,LOW);
    }
    void pulse()
    {
        delayMicroseconds(5);
        digitalWrite(clock,HIGH);
        delayMicroseconds(10);
        digitalWrite(clock,LOW);
        delayMicroseconds(5);
    }
    long ultrasonic(boolean ci)
    {
        long distance;
        unsigned long pulsetime;
        digitalWrite(trig,LOW);
        delayMicroseconds(5);
        digitalWrite(trig,HIGH);
        delayMicroseconds(10);
        digitalWrite(trig,LOW);
        pulsetime=pulseIn(echo,HIGH);
        if(ci)
        {
            distance=pulsetime/58;
        }
        else
        {
            distance=pulsetime/148;
        }
        delay(50);
        if((distance<450)&&ci)
        {
            return distance;
        }
        else if((distance<180)&&(!ci))
        {
            return distance;
        }
        else
        {
            return 0;
        }
    }
    void show(byte a[5])
    {
        delayMicroseconds(5);
        digitalWrite(data,HIGH);
        pulse();
        for(byte x=0;x<5;++x)
        {
            byte data1=digits[a[x]];
            for(byte y=0;y<7;++y)
            {
                if(data1&(1<<y))
                {
                  digitalWrite(data,HIGH);
                    pulse();
                }
                else
                {
                    digitalWrite(data,LOW);
                    pulse();
                }
            }
        }
        digitalWrite(data,LOW);
        pulse();
    }
    void loop()
    {
        show(c);
        delay(2000);
        while(1)
        {
            dist=ultrasonic(true);
            if(dist>0)
            {
                byte i=3;
                c[4]=14;
                c[0]=14;
                c[1]=14;
                c[2]=14;
                c[3]=14;
                while(dist>0)
                {
                    c[i]=(dist);
                    if(i==0)
                    {
                        i=4;
                    }
                    dist/=10;
                    --i;
                }
                show(c);
            }
            delay(200);
        }
    }

body:
Pins 3 and 4 are used for USB (during programming). Try using pin 5 instead.

Or swap it with one of the clock, data, or trig outputs (i.e. 0,1,2)


message:
ESP8266 Supply Voltage dropping below 3.3V

I am trying to power an ESP8266 with a 3.3V regulator ([this one][1], can supply ~ 1A). I've been struggling for days to get the ESP to work – it will occasionally boot, occasionally connect, but then not work again for hours. What I mean by "not working" is that it will often have trouble communicating over UART; or, upload my code, but not run it; or, run my code and crash on an Exception 0.

Now I have noticed that my voltage rail is dipping severely, sometimes below 3V. If I press my reset button, the level returns to 3.3V, but then when the ESP "boots" (but often not running any code, or crashing), it dips back to 2.9V. It is also fine while programming.

Does this suggest my ESP is simply fried? It's possible I briefly misconnected a wire when I first got the unit.

  [1]: https://www.mouser.com/datasheet/2/389/ld1117a-974076.pdf

body:
It was a power issue. Everyone tells you the ESP8266 needs a lot of current, and I didn't believe them.

In case anyone else runs in to this issue, I was powering the ESP via a 3.3V regulator (fine), being fed from and Arduino's 5V (fine). **However:** I was plugging my Arduino directly into my MacBook. It seems that my Mac was limiting USB power. Using a powered USB hub (max current ~2A) worked fine, but you could probably also get away with directly powering VIN on the Arduino (or a standalone 3.3V supply).


body:
The ESP8266 will do an analog calibration when it is running the user code. This will typically be the worst case power requirement. The peak current requirement can be as much as 1/2 an amp. While your regulator probably can supply that I would bet your interconnecting wiring, and maybe the power source, are causing too much voltage drop.

The fact that you can see the voltage go down to 2.9 volts makes me thin that you have serious problems.

Early on when I started with the ESP8266 I was getting flaky operation. I put it down to bad code. But eventually I ruled that out. I took my setup to work (where I design electronic products) and looked at the power connections with a digital scope **at the module**. Right at the last point before the traces run under the shield. (I use the ESP-12 modules) It dipped just under 3.0 volts for two microseconds, and that was enough to cause a reset.

These things are **not tolerant** to any power dips. And this is why I recommend anyone starting with the ESP8266 to buy a Nodemcu or a Wemos type module. Something that has the regulator right at the processor.


message:
MQTT - Can lastwill be sent to multiple topics?

I'm using an ESP8266 as an IOT device, with MQTT to send status messages.
Each device have its own availability topic, to state its `online` or `offline` state ( needed for `Home Assistant` indication on web GUI )

Since multiple devices are present- I was wondering if a lastwill status can be sent for a joint topic to be monitored ( for example :"`device_id:offline`" )

my relevant part of the code defining a lastwill for devices topic is : `mqttClient.connect(deviceName, user, passw, availTopic, 0, true, "offline")`

**EDIT1:**
using `PubSubClient.h`

body:
The "Last Will & Testament" facility of MQTT is controlled by the server, not the client.

The topic and payload are specified when the client connects as part of the connection handshaking. When the client disconnects this stored information is published automatically by the server.

The specification only allows for one topic and payload to be set.

Of course, you can specify the same topic for many clients and give each one its own distinct payload, but you can't also have a unique topic for each client at the same time.

This is according to the specification - however that doesn't stop a broker implementing its own extensions to the specification to allow such things - but I know of no such extensions being implemented. But, given the open-source nature of many MQTT implementations (PubSubClient.h and Mosquitto, for example), there is no reason you couldn't extend the protocol to implement your own requirements (at the cost of compatibility with other systems of course).


message:
How is this simple transistor circuit suppose to work?

I've tried to replicate this circuit today.

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

 1. My motor is a computerfan, they apperntly don't need a flyback diode since there [are no brushes.][2]
 2. I used a 12V power source for my arduino and hooked it up via
    VIM.

 3. I used the arduino ground as external power source.

 4.  I verified that the transistor worked as expected with a voltmeter.

Here is the transistor I used:[![enter image description here][3]][3]

As I understand this, the transistor is stimulated to "steal" electrons away from the motors circuit. But it seems connected to the base. Why would you do that?

  [1]: https://i.stack.imgur.com/Ruxiv.png
  [2]: https://www.hardwaresecrets.com/anatomy-of-computer-fans/2/
  [3]: https://i.stack.imgur.com/ACDXY.png

body: This looks like a circuit to monitor the power loss in the motor supply. If the motor is powered and the circuit is not interrupted then the collector will poll Arduino pin 9 to GND.


body:
There are many bad schematics and pictures online, and these pictures are really bad.

Do not try to make that. You may damage the Arduino board and the transistor.

 - Even the picture of the BC548 is wrong. The BC548 is always
   called "BC548" and never "BC-548".
 - The BC548 is not a good choice to drive a motor. It can only
   do 100 mA continuous.
 - The DC barrel socket has plus and minus wrong connected.
   The 12V plus is connected to the Arduino GND.
   That is not okay.
 - The transistor in the first picture is probably a
   transistor with the pins in BCE order.
 - A resistor is missing to the base of the transisor.
 - Because of the missing resistor, the Arduino board
   can be damaged.
   When the breadboard has a bad connection to GND,
   the 12V can go to pin 9 of the Arduino board.

@Dorian, there are no mystical higher alien intelligent thoughts for that schematic. It is obvious a wrong circuit that is meant to drive a motor with PWM using a transistor.

And last but not least:
There are a few different types of computer fans. Some have a capacitor inside and some will only accept a PWM signal to a PWM input.
Are you sure that your fan is able to accept PWM for the 12V power?


message:
Arduino Uno: avrdude: stk500_recv(): programmer is not responding

I have an original Arduino Uno board purchased directly from the official arduino website. I have used it successfully with IDE v1.8.5 on my Windows 10 laptop for various projects in the last 6 months.

Recently my laptop stopped working and I tried shifting the IDE to my old windows 8 laptop. I installed the latest IDE v1.8.8 on it. But whenever I am trying to upload the sample blink code to the arduino, I am getting the following - "stk500_recv(): programmer is not responding" error.

I have verified that the I have selected the right board - "Arduino/Genuino Uno" in the IDE. I can also see the driver installed in the windows "Device Manager" with COM3 as the port. I have selected COM3 as the port in the IDE as well.

Thinking that its a bit old windows 8 laptop, I tried installing the IDE on two other newer laptops (windows 7 and 10) along with the same troubleshooting steps as above. But unfortunately, same results.

I looked at the many links on internet and tried the following steps, but no luck so far.

 - Resetting the board: It flashes the LED on the pin 13 twice which means the chips are ok and resetting the board. This where I think the board is functioning well.
 - Tried using both "Upload" and "Upload using programmer" mode from IDE.
 - Restarting laptops multiple times.
 - Unplugging USB cable between laptop and arduino several times.
 - Reinstalled arduino ide version 1.8.5 which was on my old laptop.

Do I need to choose Tools --> Programmers? I guess this is not needed as I am using USB to upload code, but please advice. What else can I try? Please help !!

Here is the complete error:

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

             System wide configuration file is "C:\Users\Anurag\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/etc/avrdude.conf"

             Using Port                    : COM3
             Using Programmer              : arduino
             Overriding Baud Rate          : 115200
             AVR Part                      : ATmega328P
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PC2
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
               flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
               lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

             Programmer Type : Arduino
             Description     : Arduino
             Hardware Version: 3
             Firmware Version: 4.4
             Vtarget         : 0.3 V
             Varef           : 0.3 V
             Oscillator      : 28.800 kHz
             SCK period      : 3.3 us

    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.00s

    avrdude: Device signature = 0x1e950f (probably m328p)
    avrdude: reading input file "C:\Users\Anurag\AppData\Local\Temp\arduino_build_337690/Blink.ino.hex"
    avrdude: writing flash (930 bytes):

    ***Writing | avrdude: stk500_recv(): programmer is not responding
    ######avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_recv(): programmer is not responding***
    ================================================================

**UPDATE 1:**
In the meanwhile -

 - I also changed my USB cable.
 - Tried on a MAC laptop as well.

No luck with these approaches as well.

I also tried the Arduino loopback test with my board and it is giving me positive results which suggests that my board is processing the data. May be the problem is only when uploading the code. I have updated my original post as well with these steps.

Still need help!

Thanks in advance,

Anurag

body: The output shows that avrdude (the uploading program) can contact your Arduino and is able to detect some settings. But as soon as it tries to upload it doesn't get the correct answers. Seems like the bootloader is damaged. Try to burn a new bootloader (you need an ICSP programmer for that, another Arduino with a special sketch and some basic hardware might do the job too).


message:
Cannot get pins on esp 8266 adafruit wifi module to read HIGH on pin 15

I have an esp8266 and I cannot get the value to read HIGH when 3.3v is applied to directly to pin by hand. I have an Arduino Uno powering the esp8266. It connects to the WiFi like it should, and now all I want is to manually see that when I apply 3v that the state will change from 0 to 1. Does anyone know how I can do this.

When I apply 3 volts directly to pin 15 it outputs 0. Even if I try digitalWrite on the pin and set it to HIGH it still says 0 and i serialPrint. My end goal if to use the arduino uno to fire and ouput on pin 8. On the arduino UNO side I am using a super sonic sensor. When the sensor is triggered I want to turn pin 8 on. From there I want to take pin 8 to feed pin 15 on the 8266 as an input. Before I did that I just wanted to see that when you manually apply 3v that the pin would read 1 or HIGH but no matter I do it wont change value. Once I get that value as HIGH I can send  a second request to the server like im already but now I want to say  that there was an intruder. Im not sure why the value wont change but being a beginner with arduino Im trying to keep it simple and ideally would like to wire it in this manner.

    #include <SoftwareSerial.h>
    #include <ESP8266HTTPClient.h>
    #include <ESP8266WiFi.h>

    const char* ssid = "********";
    const char* password = "********";

    HTTPClient http;

    static const uint8_t D8 = 15;
    int featherPin = D8;

    //int trigPin = 13;
    //int echoPin = 12;
    //int ledPin = 10;
    //int hornPin = 11;
    //
    //int spaceIntruded;
    //
    //long duration, cm, inches;

    void setup() {
      Serial.begin(115200);
      pinMode(featherPin,INPUT);

      WiFi.begin(ssid, password);

      while(WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.println("Waiting for connection");
     }

    //  Serial.begin (9600);
    //  pinMode(trigPin, OUTPUT);
    //  pinMode(echoPin, INPUT);
    //  pinMode(ledPin, OUTPUT);
    //  pinMode(hornPin, OUTPUT);
    //  delay(5000);
    //  Serial.println("Armed...");

    }

    void loop() {

      if (WiFi.status() == WL_CONNECTED) {
        Serial.println("yay connect");

        http.begin("http://10.150.40.121:3000/");
        http.addHeader("Content-Type", "text/plain");

        int httpCode = http.POST("Message from ESP8266");
        String payload = http.getString();
        Serial.println(payload);
        http.end();

        } else {
          Serial.println("Error in Wifi connection");
        }
    //    digitalWrite(featherPin, HIGH);
        int sensorValue = digitalRead(featherPin);
        Serial.print(sensorValue);

    //    if (digitalRead(featherPin) == HIGH) {
    //      http.begin("http://10.150.40.121:3000/home");
    //      http.addHeader("Content-Type", "text/plain");
    //
    //      int httpCode = http.POST("Message from ESP8266");
    //      String payload = http.getString();
    //      Serial.println(payload);
    //      Serial.print("hi");
    //      http.end();
    //      } else {
    //        Serial.print(featherPin);
    //        Serial.println("I am not hot");
    //      }

    //  digitalWrite(trigPin, LOW);
    //  delayMicroseconds(1);
    //  digitalWrite(trigPin, HIGH);
    //  delayMicroseconds(2);
    //  digitalWrite(trigPin, LOW);
    //
    //  pinMode(echoPin, INPUT);
    //  duration = pulseIn(echoPin, HIGH);
    //
    //  inches = (duration / 2) / 74;
    //  Serial.println(inches);
    //
    //  spaceIntruded = inches;
    //
    //  if (spaceIntruded <= 50 || spaceIntruded >= 900){
    //      digitalWrite(ledPin, HIGH);
    //      digitalWrite(hornPin, HIGH);
    //      Serial.println("Intruder Detected!");
    //      Serial.println("Sending text Notification...");
    //      delay(500);
    //      Serial.println("Armed...");
    //  }
    //
    //  else{
    //    digitalWrite(hornPin, LOW);
    //    digitalWrite(ledPin, LOW);
    //  }
        delay(30000);

    }

body:
Pin 15 is one of the boot configuration pins (0, 2, 15) and must be LOW at boot. To ensure it, dev boards with esp8266 have external pull-down on pin 15 (and pull-up on 0 and 2). To read the pin HIGH you must overcome the pull-down.

Adafruit Feather HUZZAH has 4.7kOhm resistor for the pull-down, so it is a 'strong' pull down. NodeMcu has 12kOhm resistor on io 15.

From schematics of Adafruit Feather HUZZAH

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

Note: setting pin as OUTPUT and HIGH doesn't make it read HIGH in code. Only INPUT pin state can be read with digitalRead (only on some MCUs digitalRead reads the same register set by digitalWrite).

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


message:
Multiple definition error when linking firmware.elf

I just can't wrap my head around on how to properly work with multiple files. My code has been getting quite big so I decided to split all the classes into one file each. So I'm left with 6 files:

    dataHandler.cpp
    fileHandler.cpp
    header.cpp
    main.cpp
    request.cpp
    sensorData.cpp

*header.cpp includes all the header files, and main.cpp the setup() and loop() functions.*

Visual Studio Code shows me no errors while compiling. The includeguards have the name convention: CLASSNAME_INCG

So in my main.cpp for example I have something like:

    #ifndef HEADER_INCG
    #include "header.cpp"
    #define HEADER_INCG
    #endif

    #ifndef SENSORDATA_INCG
        #include "SensorData.cpp"
        #define SENSORDATA_INCG
    #endif

    #ifndef DATAHANDLER_INCG
        #include "DataHandler.cpp"
        #define DATAHANDLER_INCG
    #endif

    setup()
    {
        ...
    }

    ...

When going into a class-file I have it defined in the following way (fileHandler.cpp):

    #ifndef HEADER_INCG
    #include "header.cpp"
    #define HEADER_INCG
    #endif

    #ifndef FILEHANDLER_INCG
    #define FILEHANDLER_INCG

    class FileHandler{
        ...
    }

    #endif

**So in summary** I include the headerfile into every file, with includeguards arround. If I wouldn't include it I would get errors that crucial libaries like Serial etc. are missing. But when including the header into every file compiliing works just fine, but when it comes to linking the files togehter I get an error of multiple definitions.

*So how can I define the headerfile just once for all files albeit I need it in every file?*

body:
1. Rule #1:

Header file extension is ".h". Files with ".cpp" are ususally compiled as separate compilation units into the object file. If you have any function definition (= declaration + implementation) or any global variable in more object files, it'll fail to link.

 2. Rule #2:

No definitions in headers - variables and functions will cause this error if you include .h file into more .cpp files. If you need super global variable, you have to use declaration with extern modifier and you have to define it in one of the .cpp files. But only one! Also there can be only function prototypes (declarations) in header file. Implementation have to be only once in one of the ".cpp" files.

It's usually in the first chapter of books about learning C/C++.

Really short example:

    // myLib.h
    #ifndef _myLib_h_guard_
    #define _myLib_h_guard_

    void myFunction(); // function prototype (declaration)

    extern int mySuperGlobalVariable;  // variable declared as extern, there must be definition somewhere

    class MyClass {
    public:
      int someMethod(); // method declaration

      int anotherMethod() { return 1; }  // definition inside of class works, but sometimes is less readable
    };

    #endif

    // myLib.cpp
    #include "myLib.h"

    void myFunction() { // function implementation (definition)
      // do something...
    }

    int mySuperGlobalVariable; // definition

    int MyClass::someMethod() { return 2; } // method definition

    // main.cpp
    #include <myLib.h>

    int main() {

      mySuperGlobalVariable = 10;

      myFunction();

      MyClass instance;
      int first = instance.someMethod();
      int second = instance.anotherMethod();
    }


message:
Arduino Nano Midi to cv convertor interesting issue

I created the circuit in this schematic on protoboard,
[![schamatic][1]][1]

and the code,
https://github.com/elkayem/midi2cv

I use a dual opamp and a single dac, because i only need note and velocity.
The opto i use is, H11L1

It works but has a strange issue that i can not figure out.

The author says the code supports midi notes from 21 to 108.

When I send midi notes to test the device,

(Arduino powered with +12, TL082 Opamp powered with +15 to GND )

The notes <= 36 gives +15V in the output of the opamp.
The note 37 gives +3.43V
The note 38 gives +1.7V
.
.
.then it increments as expected until note 108 which gives +7.52 V

Also to add I have +1.5V DC offset on the both outputs of the opamp.
(This, i can live with but i would love it not to happen. )

I would be very happy if you help me on this, thank you.

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

body:
I changed the opamp to LM358 and all problems solved it works perfectly!

If you have enough motivation and time please explain me why, but i will research and learn anyway.


message:
74HC595 shift register not working

I got my Arduino kit a few days ago and I've been going through some of the tutorials.

I got to the 8 LEDs with a shift register tutorial, where I got stuck. Nothing would light up after I plugged everything in and uploaded the sketch.

[![arduino][1]][1]

This is the circuit I've attempted to recreate using Fritzing, and the following is the code I used, from the tutorial :
<!-- language-all: lang-cpp -->

    int tDelay = 100;
    int latchPin = 11;      // (11) ST_CP [RCK] on 74HC595
    int clockPin = 9;      // (9) SH_CP [SCK] on 74HC595
    int dataPin = 12;     // (12) DS [S1] on 74HC595

    byte leds = 0;

    void updateShiftRegister()
    {
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, LSBFIRST, leds);
      digitalWrite(latchPin, HIGH);
    }

    void setup()
    {
      pinMode(latchPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
    }

    void loop()
    {
      leds = 0;
      updateShiftRegister();
      delay(tDelay);
      for (int i = 0; i < 8; i++)
      {
        bitSet(leds, i);
        updateShiftRegister();
        delay(tDelay);
      }
    }

I have also attempted to use an 8-segment digit display using the same shift register, also failing.

Is there something wrong that I am doing or could it be that the little chip is broken?

I accidentally discovered that when I swap the ground from pin 8 on the 595 to 5V, all the LEDs will light up.

Update : I got the same circuit in Tinkercad, some kind of Arduino simulator.
After dropping in the code and running the simulation, after it lights up the 5th LED, I get this warning :

[![warning][2]][2]

However, when I change the 220 ohm resistors to something like 500 ohm resistors, that pop-up is gone. Could this be another reason of why my chip could be possible broken at the moment?

  [1]: https://i.stack.imgur.com/bPD5g.png
  [2]: https://i.stack.imgur.com/3QOJs.png

body:
One omission I see is that you don't have a bypass capacitor across Vcc and Gnd of the 74HC595. Without it you would have inconsistent operation.

But if you had the power reversed on the chip then that will be the major problem and I'm sure the chip is damaged.

What I would do is put leds on the clock, data, and latch lines. And then make your delay very long, 1 second, so that you can see what the lines are doing. Just to confirm that you are getting the output that you expect. But first put a bypass cap across the chip.

Also double check that your leds are in the right way.


body:
A few thoughts

Connecting 5v to pin 8 (=gnd) is not a good idea.  It may not cause any damage if pin 16(=vcc) is also connected to 5v but i would not rely on that. Generally reverse voltage will kill all electronics unless they are specifically protected against it.

For the LEDs I would use 1k to 10k ohm resistors.  This is giving still enough current to see them light up. Using 330ohms just takes more current and makes the leds extremely bright (3mA is enough).

For testing whether something simple is working, like a shiftregister, flipflop, or logic gate, I would not use a microcontroller at all. You can just use a couple of switches attached to the CLK and LATCH pins, with a slide switch attached to the DATA pin to select 1 or 0 input bit. This eliminates one point where stuff can go wrong.

Whether or not you put in a bypass cap will not make a difference if your supply is sufficiently capable and stable. I use the charger of my broken laptop that can deliver 5v at up to 2.5amps. In this setup I don't need any bypassing, although it's still best practise to include it.

Adding LEDs to the serial IN, latch, and shift clock, and serial output may also help nail down the problem.

Also make sure you don't have dodgy cables. If any of the wires is broken or has microscopic internal breaks this can lead to misbehaviour and is very difficult to find.

One thing I did when I tried if my chips worked was to first use a known good chip from a colleague to confirm the circuit was ok.

Depending on where you take your power from, adding a power LED is usually a good idea as well. If you power everything from a powerbank you may find that some of them just shutoff the outputs if there is less than a certain threshold current flowing out.  This can leads to effects like "the circuit worked for 30 seconds and then died. After disconnecting and waiting a couple of seconds and repluging the power it works again..."  For this reason I include a power LED in just about every project of mine.


body:
The only way i found to make this circuit to work
is by putting  8 pullup resistors (1k) from vcc
to each of the output pins of the 74hc595 whithout
them no leds light up ever.


message:
Newbe needing help with fixed string length

im trying to build a bit of test equipment that will talk to some software and it needs to send a fix string. when the voltage changes the string length does as well. i need to cap the results to 4 in length. (sorry for not knowing the correct terminology. this is the output i need -
<X_PCCCC_Y_PFFFF_Z_PTTTT>
Where,

    X = Flag CP Value
    _ = Space
    P = Polarity
    C = CP Received value
    Y = Flag Field Gradient
    F = Field Gradient Received value
    Z = Flag Contact CP
    T = Contact CP Received value

There is also a line feed and carriage return present at the end of each string.
The polarity indicator will only display a minus sign ‘-‘ if the received value is
negative otherwise no assignation will be transmitted. Although the overall string
length is constant the values for each measurement are right justified and hence a
space will be present should the value of the measurement not necessitate the
utilisation of all allocated character spaces.
Sample Outputs

    < X -89 Y -1989 Z -1096 >
    < X 1039 Y 8 Z 78 >

this is my code so far

    #include <Wire.h>
    #include <Adafruit_ADS1015.h>

    Adafruit_ADS1115 ads1(0x48);     // Use this for the 16-bit version
    Adafruit_ADS1115 ads2(0x49);

    void setup(void) {

      Serial.begin(9600);

      ads1.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV
      ads2.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV

      ads1.begin();
      ads2.begin();
    }

    void loop(void) {

      int16_t results01,results02,results03;

      results01 = ads1.readADC_Differential_0_1();
      results02 = ads1.readADC_Differential_2_3();
      results03 = ads2.readADC_Differential_0_1();

      Serial.print("X ");
      Serial.print(round(results01 * multiplier));

      Serial.print(" Y ");
      Serial.print(round(results02 * multiplier));

      Serial.print(" Z ");
      Serial.print(round(results03 * multiplier));

      Serial.println();              // send a cr/lf
      delay(500);
    }

Any help pointing me in the right direction would be Amazing.
Thanks in advance

Joe

body:
The [printf() family of functions][printf] comes handy when you need
this kind of control over the formatted output:

    /*
     * Format a number as 5 characters.
     * Returns the string in a statically allocated buffer.
     */
    char * format5(int x)
    {
        static char buffer[6];  // 5 chars + terminating NUL
        snprintf(buffer, sizeof buffer, "]", x);
        return buffer;
    }

    void setup() {
        Serial.begin(9600);
        Serial.println(format5(15));
        Serial.println(format5(-15));
        Serial.println(format5(-1500));
        Serial.println(format5(1500));
    }

    void loop(){}

output:

       15
      -15
    -1500
     1500

[printf]: https://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html


message:
Cannot get esp8266 - 12 wifi module to always read analogRead incoming voltage accurately

So I have and arduino uno that is firing an output on pin 8. This code is not in this file just to be clear. From there Im taking that output and using it to fire pin 0 on the wifi module. Im using pin 0 because from what I understand all other pins have a pullup or pulldown resistor. When pin 0 is hot I want to print that value. Sometimes it works when I do it other times the analog values reads very low. I am using the 3.3v from the arduino uno and I plan to get a voltage regulator for the wifi module but would this cause this kind of issue? I am very very new to arduino so if anyone has any ideas I would appreciate a very dumbed down explanation. Thanks a lot. Also the reason why I have the delay turned down so low is because it seemed to make the analog signal pick up more often. Im not sure why this would matter but at a delay of 3000 it would almost never change analog value but when I turned the delay down to one the value came through much more consistently. Currently the code just outputs low analog numbers and occasionally pops up 1023 when voltage is applied but not consistently. And sometimes it just stops altogether until I keep trying for a while. I am getting voltage to the pin however so I know I have a complete circuit and power.

#include <SoftwareSerial.h>

    #include <ESP8266HTTPClient.h>
    #include <ESP8266WiFi.h>

    const char* ssid = "ENDOWED Underwear";
    const char* password = "endowwear";

    HTTPClient http;

    static const uint8_t D0   = 16;
    static const uint8_t D1   = 5;
    static const uint8_t D2   = 4;
    static const uint8_t D3   = 0;
    static const uint8_t D4   = 2;
    static const uint8_t D5   = 14;
    static const uint8_t D6   = 12;
    static const uint8_t D7   = 13;
    static const uint8_t D8   = 15;
    static const uint8_t D9   = 3;
    static const uint8_t D10  = 1;

    int featherPin = D3;

    void setup() {
      Serial.begin(115200);
      pinMode(featherPin, INPUT);

      WiFi.begin(ssid, password);

      while(WiFi.status() != WL_CONNECTED) {
        delay(10);
        Serial.println("Waiting for connection");
      }
    }

    void loop() {
      int sensorValue = analogRead(featherPin);

      if (WiFi.status() == WL_CONNECTED) {
            Serial.println("yay connect");

            http.begin("http://10.150.40.121:3000/");
            http.addHeader("Content-Type", "text/plain");

            int httpCode = http.POST("Message from ESP8266");
            String payload = http.getString();
    //        Serial.println(payload);
            http.end();

        } else {
            Serial.println("Error in Wifi connection");
        }

        if (sensorValue > 850) {

          http.begin("http://10.150.40.121:3000/home");
          http.addHeader("Content-Type", "text/plain");

          int httpCode = http.POST("Message from ESP8266");
          String payload = http.getString();
          Serial.println(payload);
          Serial.print("hi");
          http.end();
          } else if (sensorValue < 850) {
            Serial.print(sensorValue);
    //        Serial.println("I am not hot");
          }

    //  digitalWrite(trigPin, LOW);
    //  delayMicroseconds(1);
    //  digitalWrite(trigPin, HIGH);
    //  delayMicroseconds(2);
    //  digitalWrite(trigPin, LOW);
    //
    //  pinMode(echoPin, INPUT);
    //  duration = pulseIn(echoPin, HIGH);
    //
    //  inches = (duration / 2) / 74;
    //  Serial.println(inches);
    //
    //  spaceIntruded = inches;
    //
    //  if (spaceIntruded <= 50 || spaceIntruded >= 900){
    //      digitalWrite(ledPin, HIGH);
    //      digitalWrite(hornPin, HIGH);
    //      Serial.println("Intruder Detected!");
    //      Serial.println("Sending text Notification...");
    //      delay(500);
    //      Serial.println("Armed...");
    //  }
    //
    //  else{
    //    digitalWrite(hornPin, LOW);
    //    digitalWrite(ledPin, LOW);
    //  }
        delay(1);

    }

body:
Analog to Digital conversion is one aspect1 where the ESP8266 is very poor. It has a single ADC pin which can read a maximum of 1V.

That pin is the only pin you can use with `analogRead()`. Any attempts to use any other pin just use that pin instead. The parameter (pin number) to `analogRead(pin)` is ignored and no matter what you do that one single ADC pin is what is being read. Also the pin cannot be used for anything else. None of the digital functions can be used with it since the pin doesn't have a GPIO number associated with it.

Some boards include a simple voltage divider on the ADC pin to allow higher voltages to be read, such as the NodeMCU:

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

If your board doesn't have such a divider you will have to implement it (or something similar) to be able to read the 3.3V incoming voltage.

----

1 The ESP8266 is great for WiFi but pretty poor for everything else. It is seriously starved of internal peripherals (it doesn't even have I²C). For a more feature-rich solution you might consider upgrading to the ESP32.

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


message:
ESP8266 Switching firmware on the fly

Can you help me out to understand if this is possible with ESP8266 / 32 ?

I have a main binary that i upload to the chip, let's call it **A** - that's done from arduino.

**A** starts to work, but communicates every couple of minutes with central server polling for a *task*.

If there is a task - let's call it **B**

**A** downloads it and stores it on SPIFFS.

Now what should happen is that **A** uploads it, reboots and **B** starts to work.

When **B** finishes it loads up again **A** and the circle closes - this process goes on forever.

Questions:

1) Is it possible that a stored on SPIFFS binary file can be uploaded to the chip? Like OTA does via www.

2) Can i somehow store **A** onto the SPIFFS, so that when **B** finishes i reupload **A** ?

Thanks for any input into this

body:
The esp8266 Arduino package has 3 libraries for firmware update.

 - ArduinoOTA for upload from Arduino IDE
 - ESP8266HTTPUpdateServer for upload with web browser
 - **ESP8266httpUpdate library to check a web server for new version of the
   firmware**


body:
I think i've found an answer to my question here

https://www.esp8266.com/viewtopic.php?f=32&t=11324

    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266WebServer.h>

    #include "FS.h"

    void setup() {
      Serial.begin(115200);
      Serial.println();
      SPIFFS.begin();
      Dir dir = SPIFFS.openDir("/");

      pinMode(BUILTIN_LED, OUTPUT);
      digitalWrite(BUILTIN_LED, LOW);

      File file = SPIFFS.open("/blinkESP.bin", "r");

      uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
      if (!Update.begin(maxSketchSpace, U_FLASH)) { //start with max available size
        Update.printError(Serial);
        Serial.println("ERROR");
      }

      while (file.available()) {
        uint8_t ibuffer[128];
        file.read((uint8_t *)ibuffer, 128);
        Serial.println((char *)ibuffer);
        Update.write(ibuffer, sizeof(ibuffer));

      }

      Serial.print(Update.end(true));
      digitalWrite(BUILTIN_LED, HIGH);
      file.close();
    }

    void loop() {

    }

Will give it a try and revert back to confirm if it answers my question.


message:
Divide two integers resulting into a float

Suppose I want to divide two integer variables and put the result into a float.
In order to prevent integer division do I have to program like this:

        int i = 6312;
        int j = 258;
        float f;
        f = i;
        f = i/j;

Or can I straightforward program like below and the compiler makes sure it is handled the 'proper' way:

        f = i/j;

body:
Cast the integers to float before doing the calculation.

    float f = float(i) / float(j);

or

    float f = (float) i / (float) j;

Always be clear how the calculation should be done, so the compiler will do what you want it to do.


body:
As Arduino is C++, you should *really* use a [static cast][1], to be technically accurate. However, for Arduino code it probably doesn't really matter.

So either

```
float f = static_cast< float >(i) / static_cast< float >(j);
```

or

```
float f = static_cast< float >(i) / j;
```

**Note**: Using a static cast on each operand, rather than just one, is  useful to quiet any warnings about the loss of precision with `int` to `float`, which typically needs to form a rounded `float` for large `int` values.

See [C++ int float casting][2] for more info.

---

Just to add to Jot's answer: Strictly speaking, it should be pointed out that `(float)` is C, whereas `float()` is C++.

---

Also, as you had meant to write in your question:

int i = 6312;
int j = 258;
float f;
f = i;
f = f/j;

Yes, that would work. However, even though it seems quite elegant, it could cause confusion later in time, when someone else examines the code - unless you added a comment explaining why.

it is probably best to keep the code simple and obvious (for debugging purposes) unless you are deliberately intending to obfuscate the code.

  [1]: https://stackoverflow.com/a/1255015/2628257
  [2]: https://stackoverflow.com/q/5456801/4424636


message:
Reading Multiple Analog Input Pins

I am having a bit of trouble trying to read multiple Analog Input Pins (A0 and A3, in this instance). I am using a Pololu A-Star 32U4 LV Robot Controller (https://www.pololu.com/product/3116), and am using the Arduino IDE to program the board; it is recognized as a Arduino Leonardo. I am using the Joystick Library (https://github.com/MHeironimus/ArduinoJoystickLibrary/tree/version-2.0) to have the controller be recognized by Windows as a Game Pad (irrelevant to the issue I am seeing, I believe).

I am simulating an Axis by using a potentiometer, with the data line running into the Analog Input, the 5V baseline coming from the board, and the Ground on the opposite of the Analog Input. This does indeed cause the values to change.

The issue that I am specifically running into is when I attempt to get the analog value for each pin that I am monitoring, it appears that the values of the other pins change at the same time. Because I am trying to use the Analog Pin values to drive an X/Y Axis, this issue manifests itself in an X/Y graph that appears linear with some sort of defined slope (with an X change leading to a Y change); rather than the expected X Horizontal only movement and Y Vertical only movement.

Further.. when I remove the second Axis (ie. only using X or only using Y), it appears to track as I expect, with the Pot moving the axis (changing the value of the Analog Input).

Here is where I check the pins in the loop:

      // Read the Analog Pins and update the controller
      for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
        checkAnalogAxisState(a, axisPins, axisPinVals);
        delay(10);
      }

And here is where I attempt to send the X/Y Axis changes based off of the readings coming from the Analog Pins:

    // Checks the Analog Pin for a value to be used as the Axis value. Only updates the state if it
    // has been found to have changed. Will update the Joystick Axis based on which pin it is currently
    // looking at
    void checkAnalogAxisState(uint8_t pinIndex, uint8_t analogPins[], int analogPinVals[]) {
        uint8_t analogPin = analogPins[pinIndex];

        // The trick when using multiple analog sensors is to read them twice, with a small delay after each read (10ms is good)
        // then discard the first reading. This is because the ADC multiplexer needs switching time and the voltage needs
        // time to stabilize after switching.
        int currentState = analogRead(analogPin);
        delay(10);
        currentState = analogRead(analogPin);
        delay(10);

        if(currentState <= analogPinVals[pinIndex] - 5 || currentState >= analogPinVals[pinIndex] + 5) {
            if(analogPin == X_AXIS_PIN) {
                Joystick.setXAxis(currentState - ANALOG_ADJUSTMENT);
            } else if(analogPin == Y_AXIS_PIN) {
                Joystick.setYAxis(currentState - ANALOG_ADJUSTMENT);
            }
            analogPinVals[pinIndex] = currentState;
        }
    }

I try to keep the Pin and the Value of that pin in an array, but even when I do this with 2 separate variable and function calls, I still see that the Analog values change at the same time.

Here is the full sketch, I can include the full contents of ControllerDefines.h and ControllerFunctions.h if they will be helpful, but I have pulled the relevant functions from each:

    #include <AStar32U4.h>
    #include <Joystick.h>
    #include "libraries/ControllerDefines.h"
    #include "libraries/ControllerFunctions.h"

    void setup() {
      // Setup pins for the Axis controls
      for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
        pinMode(axisPins[a], INPUT);
      }

      // Setup Joystick
      Joystick.begin();
      Joystick.setXAxisRange(-ANALOG_ADJUSTMENT, ANALOG_ADJUSTMENT);
      Joystick.setYAxisRange(-ANALOG_ADJUSTMENT, ANALOG_ADJUSTMENT);

      // Setup Serial Comm
      Serial.begin(9600);
    }

    void loop() {
      // Read all button states and update the controller
      for(uint8_t b = 0; b < TOTAL_BUTTONS; b++) {
        checkButtonState(b, buttons, buttonStates);
      }

      // Read the Analog Pins and update the controller
      for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
        checkAnalogAxisState(a, axisPins, axisPinVals);
        delay(10);
      }

      // Delay before polling buttons again
      delay(50);
    }

Edit:

I have taken a plot of the 2 Array values over time, as can be seen here. This is with the Pot hooked up to A3, which is `axisPinVals[0]`:
[![Plotted Values][1]][1]

Moving the Pot to A0 gives the following:
[![Plotted Values 2][2]][2]

Using the modified code below:

      // Read the Analog Pins and update the controller
      for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
        checkAnalogAxisState(a, axisPins, axisPinVals);
        delay(10);
      }

      // For the plotter
      Serial.print(axisPinVals[0]);
      Serial.print(",");
      Serial.println(axisPinVals[1]);

As you can see, the two values track together. This same behavior is not present in the buttons presses, and multiple buttons can be held at the same time with no issue.

I would expect each variable (line) to track independently of one another, when the Pot is moved from A0 to A3.

  [1]: https://i.stack.imgur.com/iGPF6.png
  [2]: https://i.stack.imgur.com/e6x3x.png

body: Try reading each input twice in a row, and use the value from the 2nd read.  The input source may need additional time to charge up the sample & hold cap that is read by the ADC in the uC.


body:
I can't reproduce your problem. Your code is a bit lengthy to say for certain whether or not A0 and A3 clash when read in quick succession. Try this test code and see what results you get:

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

    void setup() {
     Serial.begin (115200);
     while (!Serial) {}  // wait for Serial

     Serial.println ("Starting");
    }

    void loop() {

    int a, b;

      a = analogRead (0);
      b = analogRead (3);

      Serial.print ("A0 = ");
      Serial.println (a);
      Serial.print ("A3 = ");
      Serial.println (b);
      delay (100);
    }

I found on my Micro (which has the same processor) that the two inputs were completely independent. For example changing A3:

    A0 = 0
    A3 = 195
    A0 = 0
    A3 = 453
    A0 = 0
    A3 = 680
    A0 = 0
    A3 = 879

And then changing A0:

    A3 = 0
    A0 = 64
    A3 = 0
    A0 = 292
    A3 = 0
    A0 = 427
    A3 = 0
    A0 = 474
    A3 = 0
    A0 = 294
    A3 = 0
    A0 = 48

This was with two potentiometers connected at all times. If you only had one you might get a "floating" input.

I suggest you try the code above and confirm whether or not you get similar results. If you do, then the problem is not "Reading Multiple Analog Input Pins" but something else entirely, like logic in your code.

Even when I changed the delay in my code to 10, the figures reported were still independent. That is, one pot did not influence the other at all.


message:
Does UNO and Nano have the same pins?

Do Arduino Nano Atmega328p have the same pins as Arduino/Gizduino Uno Atmega328p?

body: The '328P uC on the boards is the same die. The 328P in DIP has 4 fewer pins brought out (Vcc, Gnd, A6, A7) compared to the surface mount parts. The boards themselves then bring the pins out to edge connectors in physically different locations.


message:
Detect power interruption on NodeMCU

Im using a 5v 1A power supply and connected to VIN pin on the NodeMCU. I also use 18650 battery to keep NodeMCU running in case the power supply shuts off due to power interruption.

I'm planning to use the 5V from power supply, convert it to 3.3V with voltage divider and connect it to the gpio to detect power interruption.

Is it possible? Can the NodeMCU handle the current from the power supply?

body: Yes, you can.  You need to convert the 5V down to 3.3V with a voltage divider. You also need to consider how you are going to operate the ESP8266 when there is no power.


message:
SSD1306 allocation failed when adding a constant

I am trying to get this code working:

    #include <Button.h>
    #include <SPI.h>
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    #include <RTClib.h>

    #define SCREEN_WIDTH 128 // OLED display width, in pixels
    #define SCREEN_HEIGHT 32 // OLED display height, in pixels

    // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
    #define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
    RTC_DS1307 RTC;

    // when I remove this part it works...
    int mode = 1;
    const String periodicSystem[60] = {
        "H", "He", "Li", "Be", "B", "C", "N", "O",
        "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S",
        "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr",
        "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge",
        "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb",
        "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn",
        "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd"
    };
    /////////////////////////////////////////////////////////////////////

    Button button1(7);

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

      // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
      if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
        Serial.println(F("SSD1306 allocation failed"));
        for(;;); // Don't proceed, loop forever
      }

      RTC.begin();
      if (! RTC.isrunning()) {
        Serial.println("RTC is NOT running!");
        // This will reflect the time that your sketch was compiled
        RTC.adjust(DateTime(__DATE__, __TIME__));
      }

      display.display();
    }

    void loop() {
      DateTime now = RTC.now();
      if(button1.pressed()) {
          display.clearDisplay();
          display.setTextSize(1); // Draw 2X-scale text
          display.setTextColor(WHITE);
          display.setCursor(10, 0);
          display.print(now.second());
          display.display();
      }
    }

Whenever I try to add the constant `periodicSystem`, I get the error `SSD1306 allocation failed` over Serial. The error also goes away when I remove the part with `button1.pressed()`. Basically I am not able to add the constant `periodicSystem` and read out a digital pin at the same time. To me it seems to be some sort of memory issue (I am only adding the constant, I am not doing anything else with it), but my IDE tells me I am only using 52% of the available storage. What am I doing wrong?

Here is my wiring (in reality I am using a 128x32 display, I didn't have the correct part for Fritzing; my display is labeled SDA, SCK, VCC, GND instead of SDA, SCK, VDD, GND; the RTC Module I am using is a DS1307 AT24C32 RTC Module):

[![My wiring][1]][1]

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

body:
Your display needs 624 bytes of RAM for its internal buffer (`128 * ((32 + 7) / 8)`). The `periodicSystem` array needs a massive 360 bytes of RAM just for the objects. That doesn't include the memory used to store the actual string data, which by my reckoning is 168 bytes.

So far we're up to 624+360+168 = 1152 bytes of a maximum of 2048.  Over half way and we haven't touched on the serial buffers or other objects that you're using.

An array (`const` or otherwise) of `String` objects is by far the least efficient way possible of storing constant string data on an Arduino. You're using 528 bytes of RAM to store what could be stored in 121 bytes of flash.

Personally I would store the data thus:

    const char periodicSystem[] PROGMEM = "H HeLiBeB C N O F NeNaMgAlSiP S ClArK CaScTiV CrMnFeCoNiCuZnGaGeAsSeBrKrRbSrY ZrNbMoTcRuRhPdAgCdInSnSbTeI XeCsBaLaCePrNd";

Each symbol consists of exactly two bytes, and the `PROGMEM` forces it to stay in flash and never be copied to RAM.

You can get the two bytes of each symbol with:

    char b1 = pgm_read_byte(periodicSystem + (i * 2));
    char b2 = pgm_read_byte(periodicSystem + (i * 2) + 1);

Then either print them separately, or combine them into a C string:

    char symbol[3] = { b1, b2, 0 };

That will include the space character, of course. So you could remove that if you like:

    if (symbol[1] == ' ') symbol[1] = 0;

Theoretically you could also change the spaces in the original data to be character 0 if you like - depending on what you do with it, it shouldn't cause any issues:

    const char periodicSystem[] PROGMEM = "H\0HeLiBeB\0C\0N\0O\0F\0NeNaMgAlSiP\0S\0ClArK\0CaScTiV\0CrMnFeCoNiCuZnGaGeAsSeBrKrRbSrY\0ZrNbMoTcRuRhPdAgCdInSnSbTeI\0XeCsBaLaCePrNd";


message:
How to upload Arduino C code to mBot?

I am trying to program [mBot][1] using Arduino IDE. I am connected to the mBot using USB on `COM7`, I am able to upload a code created in [mBlock 3.4.11][2] fine, using "Arduino Mode" as the editing mode. I would like to proceed to more complex coding now and for this I want to be able to edit the source code directly. The source code seen in the MBlock application seems to be read only, there is a button which should allow editing the code, called "Edit with Arduino". When I press this button, the Arduino IDE opens and I am able to edit the code. The trouble is I seem to be unable to send the code edited this way into the mBot.

When I use the Arduino IDE Sketch/Upload menu item, the code is compiled, but when sending it, I always get following error:

> avrdude: stk500v2_ReceiveMessage(): timeout

Note: I was editing and uploading Arduino code before with both Ardino IDE and VisualStudio visualMicro (now [Arduino IDE for Visual Studio][3]) without any issues.

I do not know exactly how is the mBlock application handling the upload, but while doing so a folder with the project is created, which contains the following buildprefs.txt - perhaps this could help to understand what it is doing:

    build.arch = AVR
    build.board = AVR_UNO
    build.core = arduino
    build.core.path = X:\Users\UserName\mblockExe\Arduino\hardware\arduino\avr\cores\arduino
    build.extra_flags =
    build.f_cpu = 16000000L
    build.mcu = atmega328p
    build.path = X:\Users\UserName\AppData\Local\Temp\build3998294614124133332.tmp
    build.project_name = project_followLineAuto0_0.cpp
    build.source.path = X:\Users\UserName\AppData\Roaming\com.makeblock.Scratch3.4.11\Local Store\scratchTemp\project_followLineAuto0_0
    build.system.path = X:\Users\UserName\mblockExe\Arduino\hardware\arduino\avr\system
    build.usb_flags = -DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'
    build.usb_manufacturer = "Unknown"
    build.variant = standard
    build.variant.path = X:\Users\UserName\mblockExe\Arduino\hardware\arduino\avr\variants\standard
    build.verbose = true
    build.warn_data_percentage = 75
    compiler.S.extra_flags =
    compiler.S.flags = -c -g -x assembler-with-cpp
    compiler.ar.cmd = avr-ar
    compiler.ar.extra_flags =
    compiler.ar.flags = rcs
    compiler.c.cmd = avr-gcc
    compiler.c.elf.cmd = avr-gcc
    compiler.c.elf.extra_flags =
    compiler.c.elf.flags = {compiler.warning_flags} -Os -Wl,--gc-sections
    compiler.c.extra_flags =
    compiler.c.flags = -c -g -Os {compiler.warning_flags} -ffunction-sections -fdata-sections -MMD
    compiler.cpp.cmd = avr-g++
    compiler.cpp.extra_flags =
    compiler.cpp.flags = -c -g -Os {compiler.warning_flags} -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD
    compiler.elf2hex.cmd = avr-objcopy
    compiler.elf2hex.extra_flags =
    compiler.elf2hex.flags = -O ihex -R .eeprom
    compiler.ldflags =
    compiler.objcopy.cmd = avr-objcopy
    compiler.objcopy.eep.extra_flags =
    compiler.objcopy.eep.flags = -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0
    compiler.path = {runtime.tools.avr-gcc.path}/bin/
    compiler.size.cmd = avr-size
    compiler.warning_flags = -w
    compiler.warning_flags.all = -Wall -Wextra
    compiler.warning_flags.default =
    compiler.warning_flags.more = -Wall
    compiler.warning_flags.none = -w

  [1]: https://www.makeblock.com/steam-kits/mbot
  [2]: http://www.mblock.cc/software-1/mblock/mblock3/
  [3]: https://www.visualmicro.com/

body:
Be sure to select correct board (Arduino UNO) and port.

See this guide for details:
https://www.arduino.cc/en/Guide/ArduinoUno#toc5


message:
Newbie question: Set servo at certain degrees when something happens

I am trying to set my servo at f.e. 90 degrees when the friendlyValue of the soil sensor is < 50%. The servo isn't moving at all, is it because the code is running too fast and the servo doesn't have time to reposition in between? I tried putting in delays but that didn't work, how do I fix this?
I am new to Arduino and would appreciate any help.

    #include <Servo.h>
    Servo myservo;

    int dryValue = 1024; // max
    int wetValue = 0; // min

    int friendlyDryValue = 0; // %
    int friendlyWetValue = 100;

    int sensor = A0;
    int sensorValue;

    void setup() {

      Serial.begin(115200);

      pinMode(A0, INPUT);
      pinMode(D6, OUTPUT);
    }

    void loop() {

      int rawValue = analogRead(A0); // soil sensor

     Serial.print("Raw: ");
      Serial.print(rawValue);
      Serial.print (" | ");

       int friendlyValue = map(rawValue, dryValue, wetValue,     friendlyDryValue, friendlyWetValue);

      Serial.print("Friendly: ");
      Serial.print(friendlyValue);
      Serial.println("%");

    if (friendlyValue <50)
    {
      myservo.write(9);
      }
      else
      {
        myservo.write(90);
        }
      }

body:
From your statement `pinMode(D6, OUTPUT);`, It looks you're using pin6 for the servo - ? If so, you need instead: `myservo.attach(6);` to prepare a servo object to use that pin to drive a servo. Not having done this is the reason why your servo wasn't moving. There is an [example program to drive a servo][1] using the servo library on the Arduino site.

Your code will run very fast, but since soil moisture can't change rapidly, the value being read from the soil sensor shouldn't either - unless there is electrical noise (and there will always be some; it's a question of how much). Your print statements should show you how consistent the readings are.

There are a couple of things you can do about it:

 1. Delay for a second or so at the bottom of the loop() function so the servo updates will come less frequently and the servo will have time to track them. This really doesn't help with a noisy signal though, and you probably don't want it to track noise. Also, I don't usually suggest using delays but in so uncomplicated a program as this one, it is really the most straightforward approach.

 2. Calculate the servo position from an average of a few sensor readings rather than using just one. This will help with noise so the servo should only have to track real data rather than data+noise.

 3. Do both. Update less frequently and average a few readings taken a few 10s of milliseconds apart. This will both reduce noise and keep the servo updates to within its tracking ability.

  [1]: https://www.arduino.cc/en/Tutorial/Knob