text:
LCD (I2C) issues with pull up resistor
I'm close to finish my first DYI project. But a never seen issue on the breadboard has apprear as soon as assembled.
The LCD is always / totally blank/black.
When I remove the 4.7 K ohm pull-up resistor from my 2 temperature sensors 18b20 the LCD works like a charm but temperature sensor doens't work. If a reconnect the pull-up resistor when the LCD is OK the temperature is displayed.
So it could be a wrong initialisation in my code (maybe during last cleaning)
Or a bad way to do this with my sensors and resistors.
I have theory but I'm quite a noob on electronic. What do you think I can do to resolve that ?
Thanks,
.
.
.
It's a LoLin card an not a Wemos.

#include <Arduino.h>
#include <math.h>
#include <TimeLib.h>
#include <ArduinoJson.h>

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

#define PIN_DZero D4    // LCD PIN D0
#define PIN_DOne D3     // LCD PIN D1
#define PIN_RESET D2    // LCD PIN RST
#define PIN_DC D1       // LCD PIN DC

#define PIN_TEMP D8     // TEMP PIN
#define PIN_BtnMoins D6 // Button -
#define PIN_BtnPlus D7  // Button +
#define PIN_RELAY D0    // RELAY PIN
#define PIN_UV A0       // UV ANALOG PIN

// Temperature sensor
#include <Wire.h>
#include <DallasTemperature.h>
OneWire oneWire(PIN_TEMP); // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.

// LCD
#include <U8g2lib.h>
#include <U8x8lib.h>
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, PIN_DZero, PIN_DOne, U8X8_PIN_NONE, PIN_DC, PIN_RESET);

ESP8266WiFiMulti WiFiMulti;

/*-----SENSOR VALUES-----*/
float sensorUVvolt ;
float sensorUV ;
float sensorTemp0 ;
float sensorTemp1 ;
String macAddress = "";
String txtWebService = "";
String txtTime ;
String txtSunRise;
String txtSunSet ;
int utcTime ;
int utcSunRise;
int utcSunSet ;
long timeLast = -55000;
bool isInternetConnected = 0;
bool isLampOn = 0;

time_t timeNow = now();
int minuteSunRise = 0;
int minuteSunSet = 0;

bool previousBlink = 0;
int menu = 0;
bool freezeMenu = 0;
unsigned int paramMinuteTimeNow;
unsigned int paramMinuteSunRise;
unsigned int paramMinuteSunSet;
int paramLampMode = 0; // AUTO

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

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

  pinMode(PIN_BtnMoins, INPUT_PULLUP);
  pinMode(PIN_BtnPlus, INPUT_PULLUP);
  //pinMode(PIN_TEMP, INPUT_PULLUP);

  txtTime = "1990-01-01 00:00:00";
  setTime(txtTime.substring(11, 13).toInt(), txtTime.substring(14, 16).toInt(), txtTime.substring(17, 19).toInt(), txtTime.substring(8, 10).toInt(), txtTime.substring(5, 7).toInt(), txtTime.substring(0, 4).toInt()); // Another way to set

  Serial.setDebugOutput(true);

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

  sensors.begin();

  u8g2.begin();

  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP("WIFINAME", "PASS");
  macAddress = WiFi.macAddress();

}

void GetAllSensorValues() {

  sensorUVvolt = 3.3 * analogRead(PIN_UV) / 1024; ;  //*100/1024;
    sensorUV = mapfloat(sensorUVvolt, 1.06, 2.9, 0.0, 15.0);
    if (sensorUV <= 0 ) sensorUV =0;

  sensors.requestTemperatures(); // Send the command to get temperature readings
    sensorTemp0 = sensors.getTempCByIndex(0);
    sensorTemp1 = sensors.getTempCByIndex(1);

    if (sensorTemp0 <= 0 ) sensorTemp0 =0;
    if (sensorTemp1 <= 0 ) sensorTemp1 =0;

}

void ActuorAll() {
  if (paramLampMode == 3) {
    digitalWrite(PIN_RELAY, HIGH);
  } else if (paramLampMode == 2) {
    digitalWrite(PIN_RELAY, LOW);
  } else {
    if ( minuteSunSet != minuteSunRise && minuteSunSet != 0 && minuteSunSet > minuteSunRise && year(timeNow) != 1982 && hour(timeNow) + minute(timeNow) !=0 ) {
      if (  minuteSunRise + paramMinuteSunRise <= 60 * hour(timeNow) + minute(timeNow) + paramMinuteTimeNow && 60 * hour(timeNow) + minute(timeNow) + paramMinuteTimeNow <= minuteSunSet + paramMinuteSunSet  ) {
        isLampOn = 1;
        digitalWrite(PIN_RELAY, HIGH);
      } else {
        isLampOn = 0;
        digitalWrite(PIN_RELAY, LOW);
      }
    }
  }
}

//The Arduino Map function but for floats
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void loop() {

  boolean btnPlus = !digitalRead(PIN_BtnPlus);
  boolean btnMoins = !digitalRead(PIN_BtnMoins);

  if ( !freezeMenu && btnMoins==HIGH && btnPlus==HIGH ) {
      if (menu >= 6) {
        menu = 0;
        freezeMenu = 1;
      } else {
        menu++;
        freezeMenu = 1;
      }
  }

  if ( btnMoins==LOW || btnPlus==LOW) {
    freezeMenu = 0;
  }

  if (menu != 0) {
    if (previousBlink) {
      previousBlink = 0;
    } else {
      previousBlink = 1;
    }
    if (menu == 2 && btnMoins==HIGH) { paramMinuteTimeNow=paramMinuteTimeNow-10; }
    if (menu == 2 && btnPlus==HIGH) { paramMinuteTimeNow=paramMinuteTimeNow+10; }
    if (menu == 3 && btnMoins==HIGH) { paramLampMode--; }
    if (menu == 3 && btnPlus==HIGH) { paramLampMode++; }
    if (menu == 5 && btnMoins==HIGH) { paramMinuteSunRise=paramMinuteSunRise-10; }
    if (menu == 5 && btnPlus==HIGH) { paramMinuteSunRise=paramMinuteSunRise+10; }
    if (menu == 6 && btnMoins==HIGH) { paramMinuteSunSet=paramMinuteSunSet-10; }
    if (menu == 6 && btnPlus==HIGH) { paramMinuteSunSet=paramMinuteSunSet+10; }
  } else {
    previousBlink = 0;
  }

  if (paramLampMode>3) {paramLampMode=0;}
  if (paramLampMode<0) {paramLampMode=3;}

  GetAllSensorValues();

  if ( millis()-timeLast >= 60000 ) {

    WebServiceCall("UV", String(sensorUV), "Temp0", String(sensorTemp0), "Temp1", String(sensorTemp1) );

    timeLast = millis();
  }

  ActuorAll();

  DisplayLCD();

  delay(500);
}

void DisplayLCD(){
  String line1 = "";
  String line2 = "";
  String line3 = "";

  float txtTemp0 = round(sensorTemp0*10);
  txtTemp0 = txtTemp0/10;
  float txtTemp1 = round(sensorTemp1*10);
  txtTemp1 = txtTemp1 /10;

  /*Serial.print(" | minute timeNow:");
  Serial.print(minute(timeNow));
  Serial.print(" | A0:");
  Serial.print(sensorUVvolt);
  Serial.print("V ");
  Serial.print(sensorUV);
  Serial.print(" mW/cm² | temp0:");
  Serial.print(sensorTemp0);
  Serial.print("°C | temp1 ");
  Serial.print(sensorTemp1);
  Serial.println("°C");
  */
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_helvB12_tf);

  /* ------- LINE 1 ------- */
  if (menu == 1 && previousBlink) line1 = macAddress;
  if (menu != 1) line1 = String(txtTemp0).substring(0, 4) + " | " + String(txtTemp1).substring(0, 4) + " | " + String(sensorUV);

  /* ------- LINE 2 ------- */

  String dsplTime = MinuteToTime(60*hour(timeNow)+minute(timeNow)+paramMinuteTimeNow);
  if (menu == 2 && previousBlink) dsplTime = "__:__";

  String txtLamp = GetLampMode();
  if (menu == 3 && previousBlink) txtLamp = "____";

  String txtInternet = "X";
  if (isInternetConnected) txtInternet = "@";
  if (menu == 4 && previousBlink) txtInternet  = "_";

    line2 = dsplTime+ "  " +txtLamp+ "  " +txtInternet;

  /* ------- LINE 3 ------- */
  String dsplSunRise = MinuteToTime(minuteSunRise+paramMinuteSunRise);
  if (menu == 5 && previousBlink) dsplSunRise  = "__:__";

  String dsplSunSet = MinuteToTime(minuteSunSet+paramMinuteSunSet);
  if (menu == 6 && previousBlink) dsplSunSet  = "__:__";

    line3 = "  " +dsplSunRise+ " > " +dsplSunSet;

  u8g2.drawStr(0,12, line1.c_str() );
  u8g2.drawStr(0,35, line2.c_str() );
  u8g2.drawStr(0,55, line3.c_str() );

  u8g2.sendBuffer();

}
String GetLampMode(){
  if (paramLampMode == 3) {return "ON";}
  else if (paramLampMode == 2) {return "OFF";}
  else {return "AUTO";}

}

String MinuteToTime(int min) {
  int resutHour = min/60;
  int resutMin = min - resutHour*60;
  String resultTime = String(resutHour);

  if (resutHour < 10) {
    resultTime = "0" + String(resutHour);
  }
  if (resutMin < 10 ) {
    resultTime = resultTime + ":0" + String(resutMin);
  } else {
    resultTime = resultTime + ":" + String(resutMin);
  }

  return resultTime;

}

int WebServiceCall(String sensor1Id , String sensor1Value, String sensor2Id , String sensor2Value, String sensor3Id , String sensor3Value) {
  String url = "http://MYWEBSERVICE/save?mac=" + macAddress + "&sensor1id=" + sensor1Id + "&sensor1value=" + sensor1Value + "&sensor1id=" + sensor2Id + "&sensor2value=" + sensor2Value + "&sensor3id=" + sensor3Id + "&sensor3value=" + sensor3Value;
  Serial.println("[HTTP] url is:" + url);
  // wait for WiFi connection
  if ((WiFiMulti.run() == WL_CONNECTED)) {
    isInternetConnected = 1;
    WiFiClient client;

    HTTPClient http;

    Serial.print("[HTTP] begin...\n");
    if (http.begin(client, url)) {  // HTTP

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

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

        // file found at server
        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          String payload = http.getString();
          Serial.print("JSON:" + payload);
          txtWebService= payload;
          StaticJsonDocument<200> doc;
          DeserializationError error = deserializeJson(doc, payload);

          if (error) {
            Serial.print("[HTTP] JSON error ");
            Serial.println(error.c_str());
            //return;
          }

          JsonObject root = doc.as<JsonObject>();
          txtTime = root["time"].as<String>();
          txtSunRise = root["sunRise"].as<String>();
          txtSunSet = root["sunSet"].as<String>();
          minuteSunRise = 60 * txtSunRise.substring(11, 13).toInt() + txtSunRise.substring(14, 16).toInt();
          minuteSunSet = 60 * txtSunSet.substring(11, 13).toInt() + txtSunSet.substring(14, 16).toInt();

          setTime(txtTime.substring(11, 13).toInt(), txtTime.substring(14, 16).toInt(), txtTime.substring(17, 19).toInt(), txtTime.substring(8, 10).toInt(), txtTime.substring(5, 7).toInt(), txtTime.substring(0, 4).toInt()); // Another way to set
          //Serial.printf("[TIME] TimeNow %s\n", txtTime);
          //Serial.printf("[TIME] hour %d\n", txtTime.substring(11, 13).toInt());
          //Serial.printf("[TIME] minute %d\n", txtTime.substring(14, 16).toInt());

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

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

}

tip: previousBlink is boolean, so use true/false for the values ............................. also, you can reduce if (previousBlink) { previousBlink = 0; } else { previousBlink = 1; } to just previousBlink = !previousBlink;

what happens if you remove one of the sensors?

Thanks @jsotola. With only the relay & 1 sensor it do the same. Blank if connected at launching - LCD OK if the pull-up resistor is not connected at launching

Youtube video here: https://www.youtube.com/watch?v=hwbx0FxLWJ4

start at the beginning ..... leave everything connected ..... run LCD demo sketch

Thnaks @jsotola for your support I found the error.

... by doing it again and with observation on a few GPIO maps (lolin 32 pro, Wemos mini, ...). The GPIO pins cannot be used as you want and you have dedicated I2C and SPI pins. My conclusion is (not sure of that): the temperature sensors cannot use the SPI pins when you have an I2C. I switched sensor pin on my test breadboard from D8 to D4 (youtube link) and it's OK. I will not do a deep study on my project already soldered but will try a few other pins and I hope it will work .


text:
Software serial conflict with WiFi on ESP8266
I'm trying to use an ESP8266 (Wemos D1 mini) to read from a 19.2K serial port and report the results over WiFi. Programming is via Arduino IDE. The code to read the port works just fine if WiFi is not enabled. Once WiFi is enabled I lose chars from the input stream. I've seen several posts in various places that point to problems with using SoftwareSerial and WiFi at the same time, apparently having to do with timing conflicts. My latest attempt calls
WiFi.disconnect();

before the code that reads the chars from the serial stream, then calls
WiFi.reconnect();

after reading the serial stream but before making the calls to send data over the web. This did not work.
My code is reading from the serial port in a (blocking) loop, which other posts suggest is the problem. This is not a problem when there is no WiFi object connection. I could restructure the code to create a non-blocking read, but that would be a significant effort (and make the code much harder to understand), so before I go that route I'm wondering if there is a different solution.

Why not use the hardware UART?

If I understand correctly, UART0 is connected to the USB interface, which I'm using for flashing and debug messages. UART1 is send-only, and I'm trying to read data.

try the beta version (2.5) of the arduino esp8266 core. it has improvements in SoftwareSerial

As noted, there are conflicts between Wifi and SoftwareSerial. The attempt in the question to disconnect WiFi is a step in the right direction, but not enough. You have to actually turn off the WiFi. The challenge is to reliably shut down the WiFi and then start it up again. This has been discussed extensively in the ESP8266/Arduino Git repository here and is referred to by some as "Issue 644".  An sample implementation of the code to reliably is presented here.
Here's what the on/off functions look like. I strongly urge you to go to the code linked above and copy from there rather than here, though.
extern "C" {
#include "user_interface.h"
#define WIFI_RETRIES 25

int conn_tries = 0;
bool WiFiOff() {
    WiFi.disconnect();
    WiFi.mode(WIFI_OFF);
    WiFi.forceSleepBegin();
    yield();

    /*
     * It can take a while for the ESP to disconnect, so we need
     * to give it a couple of seconds before returning a fail.
     */
    while ((WiFi.status() == WL_CONNECTED)
           && (conn_tries++ < WIFI_RETRIES)) {
        delay(100);
#ifdef DEBUG
        Serial.print(".");
#endif
    }
    if (WiFi.status() != WL_CONNECTED)
        return (true);
    else
        return (false);
}

/*
 * Turn the WiFi back on again with forceSleepWake().
 * NOTE:-  =Your= SSID and password must be in the
 *         user_config.h file.
 */
bool WiFiOn() {
    conn_tries = 0;

    WiFi.forceSleepWake();
    WiFi.mode(WIFI_STA);
    wifi_station_connect();
    WiFi.begin("corazon_del_bosque", "");

    /*
     * It may take a while for the ESP to re-connect, depending
     * upon external factors (e:- has the access-point moved out
     * of range since we were last connected?).  This loop will
     * give us a reasonable time to re-connect without blocking
     * permanently.
     */
    while ((WiFi.status() != WL_CONNECTED)
           && (conn_tries++ < WIFI_RETRIES)) {
        delay(100);
#ifdef DEBUG
        Serial.print(".");
#endif
    }
    if (WiFi.status() == WL_CONNECTED)
        return (true);
    else
        return (false);
}

I'm using this code in my program via the Arduino IDE. The author used it in PlatformIO. Other build systems may have other requirements.

WiFi uses interrupts. Alot. SoftwareSerial doesn't work well with interrupts.  On the Arduino all interrupts are disabled while SoftwareSerial does its work. I don't know how it is implemented on the ESP8266, nor how interrupts operate on the ESP8266, so cannot comment on how to work around it.
However, if you can't use one of the hardware UART channels then maybe you need to start thinking outside the box. And by "the box" I mean "the ESP8266".
Maybe the ESP8266 isn't for you. It's a great chip for making a WiFi interface, but it's not good for much else. It simply lacks the internal peripherals to be useful.  Maybe upgrading to the ESP32 would be a good option for you (that's the ESP8266's big brother). It has a far more feature-rich peripheral set.
Also don't be afraid of using more than one microcontroller. If the ESP8266 doesn't have the interfacing you need then add another MCU to it which does have the interfacing you need - and then get them to communicate using whatever interface you do have available (I2S, SPI, etc).  Yes, it means more programming and a more complex project, but learning such things will certainly unlock more doors for future projects.

source: Stack Exchange

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

sort: votes


text:
How to blink led and run another code at same time?
I had written a code to calculate rpm of the motors using IR sensor and
Arduino nano and displaying it on OLED . With that I want an LED to
blink always. Here is the code what I did:
You can skip the declarations and setup() part. Just move directly
to loop(). I have problem in loop. In loop(), only LED goes on
blinking and further rpm calculation with OLED displaying codes are not
performed.
#include "avr/sleep.h"
#include "avr/power.h"
#include "SPI.h"
#include "Wire.h"
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"

#define OLED_RESET 4

Adafruit_SSD1306 display(OLED_RESET);

int led = 12;
int in = 13;
int pushbutton=10;
unsigned long duration = 0;
float rpm = 0;
float rpm_a = 0;
int counter = 0;
int present = 0;
int previous = 0;
unsigned long elapsed = 0;
unsigned long elapsed_prev = 0;
int disabled = 0;

void setup() {
    Serial.begin(9600);
    pinMode(led, OUTPUT);
    pinMode(in,INPUT);
    pinMode(pushbutton,INPUT);
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(35,1);
    display.print("xyz");
    display.display();
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(25,13);
    display.print("abc");
    display.display();

    delay(5000);

    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(0,0);
    display.println("RPMmeter");
    display.display();
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(0,19);
    display.println("RPM:");
    display.setCursor(80,19);
    display.println(rpm);
    display.display();

    elapsed = micros();
}

void loop()
{
    /** led blink part **/
    digitalWrite(led, HIGH);
    delay(70);
    digitalWrite(led, LOW);
    delay(70);
    digitalWrite(led, HIGH);
    delay(70);
    digitalWrite(led, LOW);
    delay(900);

    /** led blink part over and rpm calculation and displaying on
     * oled part starts **/

    if(digitalRead(pushbutton))
    {
        //Arduino low power enabled
        if(disabled==0)
        {
            sleep_disable();
            disabled = 1;
        }
        if (digitalRead(in) == 1 && previous == 0)
        {
            previous = 1;
            duration = elapsed - elapsed_prev;
            elapsed_prev  = micros();
        }
        if (digitalRead(in) == 1 && previous == 1)
        {
            previous = 1;
        }
        if (digitalRead(in) == 0 && previous == 1)
        {
            previous = 0;
        }
        if (digitalRead(in) == 0 && previous == 0)
        {
            previous = 0;
            elapsed = micros();
        }

        rpm = 60000000/duration;

        //We add a small error in the rpm value (in this case +-2)
        if ((rpm_a-2) < rpm  &&  rpm < (rpm_a+2))
        {
            rpm_a = rpm;
            counter = counter + 1;
            if (counter == 50)
            {
                display.clearDisplay();
                display.setTextSize(1);
                display.setTextColor(WHITE);
                display.setCursor(0,0);
                display.println("JARVIS RPMmeter");
                display.setTextSize(2);
                display.setTextColor(WHITE);
                display.setCursor(0,19);
                display.println("RPM:");
                display.setCursor(80,19);
                display.println(rpm);
                display.display();
                counter = 0;
            }
        }
        if (!( (rpm_a-2) < rpm  &&  rpm < (rpm_a+2)))
        {
            rpm_a=rpm;
        }

    }//end if pushbutton=1
    else {
        display.display();
        display.clearDisplay();
        delay(10);
        duration = 0;
        rpm = 0;
        rpm_a = 0;
        counter = 0;
        present = 0;
        previous = 0;
        //Arduino low power enabled
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
        sleep_enable();
        disabled = 0;
    }
}

This was the code. The problem is without that led blinking code
part in the loop, the code works fine, but if we include that LED
blinking part, the code doesn't move further. I mean only LED goes on
blinking and further codes are not performed. Why is it so? And how to
make both rpm calculation with display on OLED as well as LED
blinking happen through a single code simultaneously?

Don't use delay. Instead non-blocking code like in the BlinkWithoutDelay example of the Arduino IDE. How this is done is described in many many tutorials and also questions on this site.

@userLP, it would help if you would pick the answer which proved to be correct and mark it such so future visitors will know which answer worked for you.

While executing the 'Delay' commands your arduino doesn't really do anything. The best thing you can do is have a look at BlinkWithoutDelay and adapt your code accordingly.

Look at my answer to a similar question. Apply the same principle to your problem:

Move each task (blinking; calculating RPM) into its own separate function.
Make loop() call those functions as often as possible.
Make each function decide whether it is time to do its task, do it or not, and return.
Those functions must never wait.

This kind of program organization - called non-blocking - is extendable to as many tasks as you wish, until you run out of memory, or the processor runs out of time to do everything as fast as you need it to (that will be a great many more than the two you've described!).

There are a few options to use millis() for this.
Is it okay if I change the 900ms into a multiple of 70ms? Then I can count intervals of 70ms.
// blink led: 70ms on, then 70ms off, then 70ms on, then 910ms off

unsigned long previousMillis;
int count = 0;

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis >= 70) {
    previousMillis = currentMillis;

    switch(count) {
      case 0:
        digitalWrite(13, HIGH);
        break;
      case 1:
        digitalWrite(13, LOW);
        break;
      case 2:
        digitalWrite(13, HIGH);
        break;
      case 3:
        digitalWrite(13, LOW);
        break;
    }
    count++;

    if(count >= 16)
      count = 0;
  }
}

When the values of the intervals are in a array, then the code is probably smaller.
// blink led: 70ms on, 70ms off, 70ms on, 900ms off

unsigned long previousMillis;
const int intervals[4] = {70, 70, 70, 900};
int index = 0;

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);  // turn led on, after 70ms it will be turned off
}

void loop() {
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis >= intervals[index]) {
    previousMillis = currentMillis;

    int level = (index % 2) == 0 ? LOW : HIGH;
    digitalWrite(13, level);

    index++;

    if(index > 3)
      index = 0;
  }
}

This second sketch is smaller, but I prefer the first one.

The only thing that I can see that makes your code faulty is the fact that you use a if statement to check if your button is pushed and then you have a lot of code to be executed in that statement rather set up a bool outside of your loop and set it with the if function then use a while to do all the rest of the work that was in your if statement that way when the button is released the code will still be executed and when it is pressed again it will happen again
Almost forgot the good stuff yes the blinkwithoutdelay is the way to go on the blink code

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


text:
Why is this failing after 3 iterations?
I simply cannot figure this out, why is this failing after 3 iterations? Other than that, what better way is there to do this? Thanks!
#define rotary_encoder_topic  "/rotary/encoder"
#define remote_button_topic  "/remote/button"
#define remote_2x_toggle_topic  "/remote/2xtoggle"
#define rotary_button_topic  "/rotary/button";
char* devices[] = { "ledrpi", "lamprpi", "mediaroom" };
int currentDevice = 0;

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

void incrementCurrentDevice() {
  currentDevice++;
  if (currentDevice >= sizeof(devices)) {
    currentDevice = 0;
  }
 Serial.println(concatenateChars("Switched device to: ", devices[currentDevice]));
}

char* concatenateChars(const char* one, const char* two) {
  char result[150] = "";
  strcat(result, one);
  strcat(result, two);
  return result;
}

void loop() {
  Serial.println(concatenateChars(devices[currentDevice], remote_2x_toggle_topic));
  incrementCurrentDevice();
  delay(1000);
}

what does failing mean?

As Jaromanda X pointed out in the comments, sizeof(array[0]) (size of first element) will not return the size of the literal strings, but the size of a char pointer.

It doesn't work (whatever that means for you), because sizeof(devices) doesn't return the number of entries in the array, but the size of the array in bytes, e.g. something like (following is wrong: 24 (1 byte per character plus 1 byte with the concluding null character for each string) ) 6 (The size of a char pointer is 2 bytes on most microcontrollers; I'm not sure, if this is the same for Node MCU). So after 3 iterations (which can use the string literals in the array) currentDevice doesn't go back to zero, but counts further. With the access to the array with exceeding index you are accessing memory, that doesn't belong to the array anymore (e.g. random data).
There is no native function, that gives you the length of an array. But it can be calculated with sizeof(array)/sizeof(array[0]), which is the size of the array in bytes divided by the size of one element in bytes. In your case you would have an array size of 6 and an element size of 2, resulting in a calculated element count of 3, which is correct.
Another simple solution, which is easier to understand for beginners, but not as flexible, is to set a constant or define, that contains the size of your array. You can then use it in your code, whenever you need the size, including, when you define the array.

actually wouldn't sizeof(devices) return 3 x sizeof(char *) so, the length of each string is irrelevant. therefore sizeof(array)/sizeof(array[0]) will give 3 in this case, guaranteed

of course, I meant sizeof(devices)/sizeof(devices[0])

@JaromandaX Mhh, I haven't thought of this. But I think, you are right. The size of a pointer is 2 bytes, as I remember. So it will count to 6. Is this the same for a Node MCU? And yes, the division should work either way.

knowing size of the pointer doesn't actually matter :D

It doesn't matter for this case, but I was interested


text:
Differing behaviour from Arduino Nano when plugged into laptop vs power source
Well here's a weird one. I'm monitoring a mic on an analog pin of an Arduino Nano and using the variation in voltage to control and LED.
When plugged in to my Laptop (USB 3, 500ma available, the nano only pulls 90) the detection is flawless. When plugged into an external power source, I get no variation at all or a random, non-responsive pattern of variation. Could be I'm getting voltage values that are out of range, but of course I can't monitor them on the serial port when I'm not plugged into the laptop.
I've got a potentiometer on the circuit to increase or decrease sensitivity by changing the trigger value. I can play poke-and-try at changing the trigger values to higher and lower ranges to try and find the sweet spot, but does anybody have an explanation of why I'd see a difference in the first place? I've tried a variety of external supplies, 500ma 1a, 2a - but if it's only pulling 90 (as reported by my Macbook System Report) this shouldn't matter, right? What else could account for differing behaviour?
Here's the code:
    void loop()
{
   unsigned long startMillis= millis();  // Start of sample window
   unsigned int peakToPeak = 0;   // peak-to-peak level

   unsigned int signalMax = 0;
   unsigned int signalMin = 1024;

   // collect data for 50 mS
   while (millis() - startMillis < sampleWindow)
   {
      sample = analogRead(0);
      if (sample < 1024)  // toss out spurious readings
      {
         if (sample > signalMax)
         {
            signalMax = sample;  // save just the max levels
         }
         else if (sample < signalMin)
         {
            signalMin = sample;  // save just the min levels
         }
      }
   }
   peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
   double volts = (peakToPeak * 5.0) / 10;  // convert to volts
   val = analogRead(potPin);
   if (val > 0) triggervoltage = 10;
   if (val > 500) triggervoltage = 11;
   if (val > 800) triggervoltage = 12;
   if (val > 1000) triggervoltage = 15;

   Serial.println(val);
   Serial.println(triggervoltage);
   Serial.println(volts);
//triggervoltage =
//Serial.println(volts);
//Serial.println(val);
//THIS IS the trigger mechanism for the effect. Vary the volts value to adjust sensitivity.

   if (volts > triggervoltage) [LED RESPONSE HERE]

noisy external power source, perhaps ..... how is the external power source connected?  ..... try using a battery

Hmm. Indeed, it works on a battery. But I guess that means my entire house's supply is noisy -- I tried different supplies in different rooms.

which supply are you using? .... what are the specs?

You could make a small sketch to send the value of analogRead to the serial plotter (instead of the serial monitor), then you can try a few things and see what the noise is doing. The laptop running at battery power is probably the best. As soon as you connect the laptop to a charger and a external power supply to the circuit, that is when the trouble begins. How is your microphone connected to the arduino? Please add extra information to your question. Could you add a photo of the arduino with microphone?


text:
Docs for using i2C LCD with Newliquidcrystal_1.3.5 library?
I bought a 20x4 I2C LCD from OddWires. (https://www.oddwires.com/20x4-lcd-display-with-i2c-interface/) It came with ZERO specs or documentation. After some hair-pulling I was able to figure out how to get it working. (I had to use the commands
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address and pin assignments, including the backlight pin and polarity

and
  lcd.begin(20,4);               // initialize the lcd to 20 characters, 4 lines

To get the LCD working (The tricky bit was figuring out the pin assignments. They're not documented.)
I'm assuming this LCD unit is a lot like all the others out there.
It works, and If found the basic commands to clear the screen, position the cursor, and print text.
I've also found commands lcd.cursor() and lcd.noCursor() that let me show/hide the cursor.
I'd like to know if I can do things like blink characters between normal and inverse, underline text, etc using the standard LCD library (I've seen code that uploads custom character maps, so I assume I could upload an alternate underlined character set, but that sounds like a LOT of work for something I'm hoping is built in to the library.)
Can somebody point me to docs on the full suite of commands commonly available for these LCD units in the Arduino Newliquidcrystal_1.3.5 library?
(Sorry to be vague on the specifics of my LCD module. I did not get specs from the vendor, so I have had to guess as to how to use it.)
I'm using the I2C LCD NewLiquidCrystal LCD library. (https://github.com/fmalpartida/New-LiquidCrystal)

https://www.sparkfun.com/datasheets/LCD/HD44780.pdf ..... the link that you posted shows that the controller chip is the HD44780

So it does. (in passing.) I missed that. Thanks. I'm not clear on how I access the features of the HD44780 through the I2C backpack however.

@jsotola So it does (in passing). I missed that. Thanks. That's the datasheet for the LCD driver. It isn't clear to me what I can do from the  I2C "backpack" on my LCD module.

Something might be wrong w/your example code.  The LiquidCrystal_I2C code at github clearly shows a constructor with only 3 arguments (i2c_address, columns, rows).  Can you explain this?

@st2000, Yes, there are at least 3 different versions of the constructor. The one with just 3 arguments assumes default pin assignments, and doesn't work. I had to use the long form that included all the different pin assignments in order to get it to work.

Perhaps I do not understand.  In the link in my comment above is the code by John Rickman on github.com for LiquidCrystal_I2C which I assume you are using.  The only definition for the constructor is on line 47.  I do not see where this is an over-loaded constructor as you are indicating.  Therefore it is difficult to help as we do not know the meaning of the arguments you are using when you instantiate an instance of LiquidCrystal_I2C.

As I say in the title of my question, I'm using the library Newliquidcrystal_1.3.5, which (I think) is an enhancement of LiquidCrystal_I2C. (https://github.com/fmalpartida/New-LiquidCrystal)

There are many many Arduino LCD drivers out there spread on sites such as github and bitbucket.  The one I pointed to was is one of the more commonly used ones.  Please edit your original question to include this important link.  (I've run out of time just now - I think what you need is a link to the commonly used LCD chip specs & perhaps an explanation as to what to expect.  If no one else answers I'll try to form an answer later when I have more time.)

Often in software development, the code is the documentation. The merits of this are debated ad nauseam elsewhere.
As you have provided a link to the GitHub repository of the library you are using, you have all you need, though the provided utility/docs path doesn't fully document the I2C interface.
The function prototype (that is, the function, its return type, and parameters, but without the actual code) is found in header files which usually have the .h suffix.
Since you have an LCD with a I2C interface, you can look at the GitHub repo for the file LiquidCrystal_I2C.h
Within this file, you can see that the class is defined with name LiquidCrystal_I2C and has multiple constructors, each with a different list of parameters. The particular class constructor used is the one that matches the count and type called in your declaration of the object of that class.
The code in the header file is well documented. The first prototype listed includes good commenting:
/*!
    @method
    @abstract   Class constructor.
    @discussion Initializes class variables and defines the I2C address of the
    LCD. The constructor does not initialize the LCD.

    @param      lcd_Addr[in] I2C address of the IO expansion module. For I2CLCDextraIO,
    the address can be configured using the on board jumpers.
    */
   LiquidCrystal_I2C (uint8_t lcd_Addr);
   // Constructor with backlight control
   LiquidCrystal_I2C (uint8_t lcd_Addr, uint8_t backlighPin, t_backlighPol pol);

This block shows the first 2 constructor options: With a uint8_t type that defines the I2C address of an I/O expansion module (which is what many "LCD backpacks" are -- that, or shift registers), and one with an I2C address, a backlight pin, and the polarity of the backlight.
Proceeding down, we find the one with 10 parameters, which is what you ended up using:
  /*!
    @method
    @abstract   Class constructor.
    @discussion Initializes class variables and defines the I2C address of the
    LCD. The constructor does not initialize the LCD.

    @param      lcd_Addr[in] I2C address of the IO expansion module. For I2CLCDextraIO,
    the address can be configured using the on board jumpers.
    @param      En[in] LCD En (Enable) pin connected to the IO extender module
    @param      Rw[in] LCD Rw (Read/write) pin connected to the IO extender module
    @param      Rs[in] LCD Rs (Reset) pin connected to the IO extender module
    @param      d4[in] LCD data 0 pin map on IO extender module
    @param      d5[in] LCD data 1 pin map on IO extender module
    @param      d6[in] LCD data 2 pin map on IO extender module
    @param      d7[in] LCD data 3 pin map on IO extender module
    */
   LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
                     uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7 );
   // Constructor with backlight control
   LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
                     uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
                     uint8_t backlighPin, t_backlighPol pol);

That last constructor is used to override the default pin mappings from the I/O Expander to the LCD. This is tricky -- what were the mappings based on? An I/O expander is basically a way to access multiple pins on an external chip through a single two-wire interface (I2C). How an LCD is connected depends on what pins of the I/O Expander are connected to which pins of the LCD. There is not a formal standard, though there may be convention.
Reading the GitHub page, you see that this is a

Clone of the new liquid crystal library from: https://bitbucket.org/fmalpartida/new-liquidcrystal

Following that link takes us to some kind of documentation, noting that one of the connection types is:

I2C IO bus expansion board with the PCF8574* I2C IO expander ASIC such as I2C LCD extra IO.

A link to that hardware is helpfully provided! We can follow the link to see that the hardware is discontinued, but helpfully documented with some schematics and PCB layouts that tell us which pins of the I/O expander are connected to which pins of the LCD:

P0 is pin 0 of the I/O expander -- the top row are the I/O expander pins. Vo, RS, R/W, etc. are the LCD pins.
LCD Pin  |  I/O Expander Pin
     En  |  P4
    R/W  |  P5
E (rst)  |  P6
     D4  |  P0
     D5  |  P1
     D6  |  P2
     D7  |  P3

(And the backlight is a passthrough pin, not on the I/O Expander. It appears the definition of the backlight pin and polarity refer to I/O Expander pins.)
This is the point where you have to find out if the I/O expander on your purchase has the same pinout as the product for which this library was written.
Your "working" instance is called as (with annotations to the constructor being called)
LiquidCrystal_I2C lcd(
  0x27,       // lcd_Addr
  2,          // En (enable pin)
  1,          // Rw (read/write pin)
  0,          // Rs (reset pin)
  4,          // d4 (data)
  5,          // d5 (data)
  6,          // d6 (data)
  7,          // d7 (data)
  3,          // backlight
  POSITIVE    // backlight polarity
);

This indicates that the I/O expander on your LCD does not have the same pin connections as that for which the library was written, which is why you had success only when remapping them in the constructor.
All that to just re-state the hair-pulling you had to do!
The actual functions available are noted to be:

This library provides the same interface to applications as the LiquidCrystal library sourced by the Arduino SDK.

But to be absolutely sure, you can also see their prototypes in the header file: https://github.com/fmalpartida/New-LiquidCrystal/blob/master/LCD.h
It provides scrolling, blinking, enable/disable, etc.


text:
Configuring I2S with ESP32 and WM8978
I'm trying to get I2S audio working with an ESP32 and WM8978 codec, using the TTGO TAudio dev board. Currently, I'm trying to implement the I2S example code provided by Espressif (link below) using the Arduino ESP32 framework.
I'm using a library for sending I2C commands to the codec, and that works fine - I'm able to configure the analog signal path in the codec and change gain levels, but getting the DAC/ADC to work has been more of a challenge.
The code below compiles and seems to run - but on boot the ESP32 I2S function i2s_driver_install returns an error "I2S: clkmdiv is too large".  Looking at the driver on github it seems like this is because either the bits_per_sample or samplerate are too small, but they are currently set at the max.
https://github.com/espressif/esp-idf/blob/master/components/driver/i2s.c
Also, I note that i2s_write() returns a 'not declared in this scope' error, which makes me think that the esp32 arduino framework is out of date? But there are examples using i2s_write_bytes() which seem to be working for people.
I don't see what I am doing wrong, based on my reference examples below. Any suggestions of things to try?
Arduino 1.8.7
ESP hardware definitions by espressif, v1.0.0
code below based on the espressif sample i2s code:
https://github.com/espressif/esp-idf/tree/97eecfa1b2b95a6f77e8e9ffcb676ded687ab68f/examples/peripherals/i2s
And the TTGO TAudio demo sketch:
https://github.com/LilyGO/TTGO-TAudio
And the DFRobot NuvotonDuino:
https://github.com/DFRobot/NuvotonDuino
//WM8978 I2S dependencies
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s.h"
#include "esp_system.h"

//WM8978 I2C dependencies
#include <types.h>
#include <WM8978.h> //borrowed from the NuvotonDuino example
#include <Wire.h>

const byte I2S_SERIAL_DEBUG = 1;
const byte SAMPLE_RATE  = 48000;
const byte I2S_NUM = 0;

//16-bit 128-sample sine wavetable
int sineT[128]= {0, 1620, 3237, 4845, 6442, 8023, 9584, 11122,
12633, 14113, 15558, 16965, 18331, 19651, 20924, 22146,
23313, 24423, 25474, 26462, 27385, 28241, 29029, 29745,
30388, 30957, 31451, 31867, 32205, 32465, 32645, 32745,
32765, 32705, 32565, 32345, 32046, 31668, 31213, 30682,
30076, 29396, 28644, 27822, 26931, 25975, 24956, 23875,
22736, 21541, 20294, 18997, 17653, 16266, 14840, 13377,
11881, 10356, 8806, 7234, 5645, 4042, 2429, 810, -810,
-2429, -4042, -5646, -7235, -8807, -10357, -11881, -13377,
-14840, -16267, -17653, -18997, -20294, -21542, -22736,
-23875, -24956, -25976, -26932, -27822, -28644, -29396,
-30076, -30682, -31214, -31668, -32046, -32345, -32565, -32705,
-32765, -32745, -32645, -32465, -32205, -31867, -31450, -30957,
-30388, -29745, -29028, -28241, -27385, -26461, -25473, -24423,
-23313, -22145, -20924, -19651, -18330, -16965, -15557, -14112,
-12632, -11122, -9584, -8022, -6441, -4845, -3236, -1620};

//i2s configuration
int i2s_num = 0; // i2s port number
i2s_config_t i2s_config = {
     .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX),
     .sample_rate = SAMPLE_RATE,
     .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
     .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
     .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
     .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // high interrupt priority
     .dma_buf_count = 3,
     .dma_buf_len = 1024,
     .use_apll = false
};

//updated I2S pins for tAudio
i2s_pin_config_t pin_config = {
    .bck_io_num = 33, //this is BCK pin
    .ws_io_num = 25, // this is LRCK pin
    .data_out_num = 26, // this is DATA output pin
    .data_in_num = 27   //
};

uint32_t missedByteCounter = 0; //debug variable

 // I2S FUNCTIONS

//this function just streams samples from the wavetable to the codec
static uint16_t setup_triangle_sine_waves(int bits)
{
  static byte index = 0;
   uint16_t samples_data = sineT[index/2] + 32765;
   //write to codec below
   int bytes_written = i2s_write_bytes((i2s_port_t)I2S_NUM, (const char *)&samples_data, 2, 100);

  //i2s_write((i2s_port_t)I2S_NUM, (const char *)&samples_data, 2, &bytes_written, 100);

  if (bytes_written > 0)  index++;
  else missedByteCounter++;
  index+=11;
 // missedByteCounter+=bytes_written;
   return samples_data;
}

void i2sSetup()
{
    i2s_driver_install((i2s_port_t)I2S_NUM, &i2s_config, 0, NULL);
    i2s_set_pin((i2s_port_t)I2S_NUM, &pin_config);
}

void i2sLoop(){
  static uint32_t timer = 0;
  int interval = 1000;
  uint16_t val = setup_triangle_sine_waves(0);

  if (I2S_SERIAL_DEBUG) {
    if( millis() - timer > interval){
      timer = millis();
      Serial.print(" i2s buffer full cycles: ");
      Serial.println( missedByteCounter );
      Serial.println(val);
      missedByteCounter = 0;
    }
  }
}

//WM8978 I2C SETUP
//Uses the WM8978 I2C library distributed with the NuovoDuino
  void wm8978Setup() {
  Wire.begin(19,18); //(SDA,SCL,Frequency)
  WM8978_Init();

  unsigned char dacen = 1;
  unsigned char adcen = 1;
  unsigned char micen = 1;
  unsigned char lineinen = 0;
  unsigned char auxen = 0;
  unsigned char bpsen = 1;

  unsigned char initVal = WM8978_Init();

  WM8978_ADDA_Cfg(dacen, adcen);
  WM8978_Input_Cfg(micen, lineinen, auxen);
  WM8978_Output_Cfg(dacen, bpsen);
  WM8978_MIC_Gain(50);
  WM8978_SPKvol_Set(30);
  WM8978_HPvol_Set(50,50);
  //WM8978_ALC_Set(1,7,3);
  WM8978_Write_Reg(3,0xFF);
  WM8978_I2S_Cfg(2,0); //format, bit-length
  WM8978_Write_Reg(7,4<<1);//sets sample rate to 12kHz
  WM8978_Write_Reg(11,0xFF);
  WM8978_Write_Reg(12,0xFF|1<<8);
} //wm8978Setup

// SETUP AND LOOP

void setup() {
  Serial.begin(115200);
  //wm8978Setup();
  i2sSetup();
}

void loop(){
  i2sLoop();
}


text:
I keep gettint the error expected construcotr,destructor or type conversion before = token
#include <dht.h>
dht DHT;
#define DHT11_PIN 2     // what pin we're connected to  // DHT 11

String TextForSms ;
String humidity = " Humidity: %";
String temperature = "   Temperature";
String sign = " *C";
char fromc;

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

void loop() {
  int chk = DHT.read11(DHT11_PIN);
  float h = DHT.humidity;
  float t = DHT.temperature;
  delay(2000);
  }

  TextForSms = TextForSms + t + "," + h + ",";
Serial.println(TextForSms);
     TextForSms = "";
   delay(1000);

Please add a sentence to describe the question.  What are you actually asking?

This whole section:
  TextForSms = TextForSms + t + "," + h + ",";
Serial.println(TextForSms);
     TextForSms = "";
   delay(1000);

is outside a block. Code must be inside a block.
There are strict rules governing what can go where in a C or C++ program. I suggest you learn them.


text:
Sparkfun CAN Shield BMW OBD2 reading
I bought the CAN-Shield from Sparkfun https://www.sparkfun.com/products/13262 and I also got the Uno from Sparkfun just to be sure everything works fine.
Some info about my car:

BMW E91 2006
OBD2 is available
KWP 2000 and other lines are available
like the ones with the same baud rates from the demo

I tried the SparkFun_CAN_Demo which is available on their website and GitHub.
My output is that
CAN init is successful but I don´t know if that´s true...
If I try to read the RPM, for example, I get a buffer with a size of 1 -> " ".
My questions are:

Did I something wrong with the MCP2515 how do I know if it´s dead?
Does anybody know if the demo is working properly or not?
What´s the right way to get data from an BMW with OBD2?

what is the content of the buffer?

Do you know the bitrate of your BMW's CAN-Bus? If not, have you tried different bitrates?

@oh.dae.su I tried different bitrates but none work I know that my BMW supports KWP 2000 with a bitrate of 10.5kbits and the standard OBD-II ISO with a rate of 500kbits

@jsotola it´s just a space char -> " "

First off I cannot say much about the library that you are using I have't tried that one yet as for the shield i have some of those and there are two versions of them check your PIN outs on them the cs pin is either on d9 or d10
the other thing is make sure that you are in the right operation mode ie. Normal and maybe give this library a try I have had lots of success with this one:
https://github.com/coryjfowler/MCP_CAN_lib
as for the baud rate I have tried all types of ways of getting the right baud rate for certain vehicles but the best remains start small and step it up till you get the one that gives you reply
make sure that you ground the Arduino to the car as well it works without that but sometimes it does nothing If you are using the OBDII cable it should be grounded by default

Thank you for your reply, your suggestions seem to be a good way to find out what I´ve done wrong.

I have battled in the beginning and am still battling with the STM32 CAN bus but i think I have the Arduino one sorted from my side give that library a try it is the best one i could find be sure to use this line:
if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK)
and this:
CAN0.setMode(MCP_NORMAL);
one to set your device up right


text:
let Arduino limit it's own input power
My current project will be sitting next to a 12VDC power line. It seems a waste no to tap it to power into the Arduino board too. Now I read everywhere that with 12V input quite  a lot power gets dissipated by the voltage regulator. Wouldn't it then a wise move to use the board 's own PWM capabilities to throttle the input voltage?
Nother point is whether it is sensible at all when the board is using little current (in this case less than 5mA over the pins for 0.1 sec every few seconds, plus the board in deep sleep mode).

You could use a 12V to 5V or 3.3V Buck Converter Module ($0.84CDN) https://www.aliexpress.com/item/Mini-DC-DC-12-24V-To-5V-3A-Step-Down-Power-Supply-Module-Buck-Converter-Adjustable/32821900056.html

If there isn't a lot connected to the Arduino, that is not a lot of current is used, then the loss will also be minimal. (12-5)*current. Let's say the Arduino Uno uses 50ma. You'd end up with a loss of 0.350Watt. Not a lot, so the regulator will only get a bit warm. The problem is that some people will connect a 12V power supply, and then run a string of leds from the regulated 5V pin. Resulting in a lot of wasted power in the form of heat. So much heat that the regulator burns out.

Thanks @Gerben, this is reassuring. I thought so, but wasn't too confident about it. VE7JRO: at the moment the price is no issue with the Chinese parts, but shipping times have increased to well over a month. If I could take a shortcut as outlined here, I would prefer that. But not yet in this project, so.

How did you measure that it's going to be 5mA? Because if that's really the case, the regulator dropping 7V (I'm assuming it's a regular 5V arduino) will need to dissipate ~35mW of heat which is not much and it should not cause a lot of problems for your board.
Another option would be using a step-down power supply module, there are tons of available dc-dc converters, mostly based on LM2596 (search for LM2596 DC-DC module) which will handle your 12 power rail with ease.

There are some models of clone boards that have a DC-DC switching regulator instead of linear regulators to do just that.  The extra cost for the regulator chip, inductor, diode, etc. are probably not worthwhile in the majority of applications tho.


text:
Controlling multiple stepper motors non-simultaneously
I want to control multiple stepper motors one after another and at different speeds/directions. I am using the ULN2003 driver and the stepper has 5 coils.
My current code for controlling one motor is:

#include <Stepper.h>

const int stepsPerRevolution = 500;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);

void setup() {
  // set the speed at 60 rpm:
  myStepper.setSpeed(50);
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper.step(stepsPerRevolution);

  // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.step(-stepsPerRevolution);
}

How would I define each stepper motor differently?
Sorry if I have not asked the question properly. I will try to clarify as time goes on.

How about multiple variables of the type Stepper, each representing one stepper motor? Do you understand how the code above works?

@chrisl Yes, I do understand how the code works. I just want to know how to control two different stepper motors. For example, above we have a stepper motor being defined as myStepper.... Oh, do I just have to replace ‘myStepper’ with ‘Stepper2’? Right??

Exactly. Each Stepper variable controls 1 motor. That should work.

just a note: that is a Stepper object, not a Stepper variable

Like @chris! suggested, you could include two Stepper variables. So in the line where you were initializing the variable, you could instead have:
Stepper steppermotor1(stepsPerRevolution, 8, 10, 9, 11);

Stepper steppermotor2(stepsPerRevolution, 4, 5, 6, 7);

and then continue on with the code for speed, rotation and so on for each motor.

just realized you got your answer after reading through the comments. Never mind then. Thanks :)


text:
Why can't I print boolean variable values (0 and 1) through println function?
source code :
int buttonPin = 8;
boolean buttonState = 0;

void setup()
{
   Serial.begin(9600);
   pinMode (buttonPin, INPUT);
}

void loop()
{
   buttonState = digitalRead(buttonPin);
   Serial.println(buttonState);
   delay(500);
}

But when, instead of boolean I specify an int data type for buttonState variable it produces the result I want i.e. 1 when pressed and 0 when not pressed.
Is it related to the way these variables when stated with different data types give different values to the println() function to convert them into ASCII values?

Works fine for me. What version of the IDE are you running, and more importantly, what version of the AVR boards package does it have installed?

I also have no problems with the above code.

After testing your sketch using boolean, bool, and byte, they all worked correctly. Using bool with IDE version 1.0.6.2 and GCC version 4.2.1, increased the binary sketch size by 108 bytes (ouch). If boolean doesn't work for you, try using byte. Both variable types occupy one byte of memory.

First, you are not supposed to use boolean with digitalRead.
The function prototype in Arduino.h is:
int digitalRead(uint8_t);

Thus, the correct data type for buttonState in your code is int. Then your other problem goes away. What I am guessing is happening is that the version of the IDE you are using does not have an overloaded function for Serial.println that takes a boolean argument, and the compiler is casting it to byte, in which case it would print as 0x00 (LOW) or 0x01 (HIGH) which are not printable characters.
Unfortunately the documentation for digitalRead on the Arduino site does not mention the datatype, it just mentions that it returns HIGH or LOW which isn't very helpful to help you work out what data type to use. BTW, neither of those values are, per se, booleans. If they had said it returns true or false you might reasonably put the result into a boolean field.
I have tried to get the Arduino developers to improve the documentation in this respect, something they have declined to do. I raised the issue almost 4 years ago, and no-one is even assigned to this particular task.

If you insist on using the boolean type, then a reasonable way of printing would be:
Serial.println(buttonState ? "HIGH" : "LOW");

In response to some comments ...

Works fine for me. – Majenko

...

boolean is a typedef for bool. bool gets promoted to int, not byte - Majenko

What you mean by "is a typedef for bool" is in some (later) versions of the IDE.
Looking at, for example, Arduino pre-release version 0023 I see in the file wiring.h:
typedef uint8_t boolean;
typedef uint8_t byte;

So you can clearly see that boolean and byte are the same, and therefore that using boolean would be treated as byte. Now if you look at the Print class in that release:
class Print
{
  private:
    void printNumber(unsigned long, uint8_t);
    void printFloat(double, uint8_t);
  public:
    virtual void write(uint8_t) = 0;
    virtual void write(const char *str);
    virtual void write(const uint8_t *buffer, size_t size);

    void print(const String &);
    void print(const char[]);
    void print(char, int = BYTE);
    void print(unsigned char, int = BYTE);
    void print(int, int = DEC);
    void print(unsigned int, int = DEC);
    void print(long, int = DEC);
    void print(unsigned long, int = DEC);
    void print(double, int = 2);

    void println(const String &s);
    void println(const char[]);
    void println(char, int = BYTE);
    void println(unsigned char, int = BYTE);
    void println(int, int = DEC);
    void println(unsigned int, int = DEC);
    void println(long, int = DEC);
    void println(unsigned long, int = DEC);
    void println(double, int = 2);
    void println(void);
};

So you can see that the overload for print and println treats an unsigned char (effectively uint8_t) to be printed with BYTE default treatment and not DEC treatment.
BYTE is declared:
#define BYTE 0

And the writing is done thus:
void Print::print(unsigned long n, int base)
{
  if (base == 0) write(n);
  else printNumber(n, base);
}

What this boils down to is that both byte and boolean will be written as "binary" bytes, not converted into decimal.
As Majenko says, things are different today, and boolean is now equivalent to bool which is promoted to int.

ElectroManiac did not respond to a question about what version of the IDE s/he is using, however my point is that for some versions of the IDE my explanation is true.

Oh, and assigning the return of digitalRead to a bool is perfectly valid ...

Yes, for bool, but the question was about boolean. Whilst we know, by reading the code and reading the documentation, that digitalRead will return a 0 or 1, the fact that the return type is int means that the compiler can potentially see that you are stuffing a 16-bit return value into a 8-bit variable which will possibly lead to data truncation.
I must admit I don't get a warning when compiling with the Arduino IDE, however there is certainly the potential for truncation. A test program written in C++ and compiled with the -Wconversion flag gives a suitable warning:
warning: conversion to ‘uint8_t {aka unsigned char}’ from ‘int’ may alter its value [-Wconversion]

(There is no warning if you are placing the result into bool, however that is not the version of the IDE that the OP is using).

aren't HIGH/LOW, true/false or 0/1 the same thing for the micro controller?Like these values are interpreted by the micro controller as the same bit 0 and bit 1.

Depends what you mean by "the same thing". Internally they are. However to the compiler, different types may mean that it calls a different function for printing, particularly when you use overloaded C++ functions, which println is an example of.

I am unable to get a complete insight into the print() or println() function from the Arduino site.

Like if you give a INT type number like 123, is it segregating the number to individual digits like 1,2 and 3 and then converting it to binary data to be interpreted by the Arduino and then converting these digits to ASCII charcter representing that same number and then prints it on screen! And since print() takes all data types(being an  overloaded function),

and since boolean returns a BYTE data type(bit 0 and bit 1) as an argument to print() it converts it into ASCII characters which are non printable by Arduino's serial monitor. Am i right?

And if I am wrong can you please educate me with your knowledge on print() function

boolean is a typedef for bool.  bool gets promoted to int, not byte ("the type bool can be converted to int with the value false becoming 0 and true becoming 1."). In Gnu C bool is a macro giving the internal (GCC specific) _Bool type, not a byte. In Gnu C++ bool is a natively supported internal type.

Oh, and assigning the return of digitalRead to a bool is perfectly valid, since "The value zero (for integral, floating-point, and unscoped enumeration) and the null pointer and the null pointer-to-member values become false. All other values become true.". And since LOW just happens to be 0 and HIGH 1 they map nicely to false and true in a bool.

It could be nice to have a bool type overloaded print function though - maybe one that prints Y and N, or T and F perhaps.

@Majenko (and others) see amended answer about what boolean is a typedef for.

Like if you give a INT type number like 123, is it segregating the number to individual digits like 1,2 and 3 and then converting it to binary data to be interpreted by the Arduino - this is nothing to do with the Arduino per se. This question is about how do variables get printed which is a whole different question.


text:
Why wifiManager.setTimeout(60) is not working?
in this code I am using wifiManager.setTimeout(60); so that when it fails to connect to the wifi it should restart. However, wifiManager.setTimeout(60) is not working at all. It get stuck and display these lines :
*WM: AutoConnect
*WM: Connecting as wifi client...
*WM: Using last saved values, should be faster
It never displays this :
"failed to connect and hit timeout"
which means wifiManager.setTimeout(60) is not working . Below is the code:
  #include <ESP8266WiFi.h>

 //needed for library
 #include <DNSServer.h>
 #include <ESP8266WebServer.h>
 #include <WiFiManager.h>

  void setup() {
       // put your setup code here, to run once:
       Serial.begin(115200);

      //WiFiManager
       //Local intialization. Once its business is done, there is no need to
       //keep it around
        WiFiManager wifiManager;
      //reset settings - for testing
      //wifiManager.resetSettings();

     //sets timeout until configuration portal gets turned off
     //useful to make it all retry or go to sleep
      //in seconds

      wifiManager.setTimeout(60);

  //fetches ssid and pass and tries to connect
  //if it does not connect it starts an access point with the specified name
 //here  "AutoConnectAP"
 //and goes into a blocking loop awaiting configuration

  if(!wifiManager.autoConnect("AutoConnectAP")) {
     Serial.println("failed to connect and hit timeout");
     delay(3000);
     //reset and try again, or maybe put it to deep sleep
     //ESP.reset();
     ESP.restart();
     //ESP.deepSleep(20e6, WAKE_RFCAL);
    delay(5000);
   }

   //if you get here you have connected to the WiFi
   Serial.println("connected...yeey :)");

    ESP.deepSleep(20e6, WAKE_RFCAL);
    delay(3000);

 }

  void loop() {
  // put your main code here, to run repeatedly:

  }

I am using ESP8266 thing dev board. Can anyone please tell me what is wrong and how to resolve the issue ? Thank You!!

Are you certain this comment is on one line? //Local intialization. Once its business is done, there is no need to keep it around. Also are you sure what times are in seconds and what is in mS?

Yes I have corrected it. Time is in seconds. 60 mean 1 minute.

You'll probably need to pursue this with the author of the library.

it must be using the last wifi settings - because Using last saved values means that it has successfully connected to an AP - though, it's surprising that "connected...yeey :)" isn't output

add delay(500) after Serial.begin to see all the output from the beginning

Try using setConfigPortalTimeout(60) instead of setTimeout(60)
Because it has been updated in version 0.10 of WiFiManager library.
see : https://github.com/tzapu/WiFiManager#010

setTimeout just calls setConfigPortalTimeout - so there's no difference


text:
Programming ATMEGA328p via AVR Pocket Programmer
I have a ATMEGA328p on a breadboard with the following connections to the 2x3 ICSP connector and its connected to AVR Pocket Programmer.

While running AVRDUDE utility, i get the following error,
avrdude -c usbtiny -p m328p

The controller is powered by the AVR and i have made certain about the pinout. Anyone run into the above error?
Adding more verbose output from the terminal.

please do not post pictures of text

Is the chip wired to receive the correct clock that it is configured for?

There is no mention of any external clk needed or required.

Hi, which text to be specific so I can remove that.


text:
CPU information on Arduino Serial Monitor
how to show the
CPU temperature,
CPU usage (percentage) and
the memory usage(percentage)
in Arduino Serial Monitor.

an Arduino does not have a CPU

@jsotola Yes it does.

CPU temperature
Some Arduino boards have a microcontroller with a temperature sensor inside. For example the Arduino Uno can measure the temperature inside the microcontroller.
As far as I know, no one uses it. It is not accurate and a microcontroller should not get hot in the first place. The microcontroller or processor on the Arduino board can run at 100% load and it does not get hot.
The internal temperature sensor is not accurate enough to measure the ambient temperature.
The internal temperature is therefore (almost) useless.
See this page on the Arduino Playground and this forum thread for the internal temperature sensor.
CPU usage
There is no CPU usage. There is no idle task. The microcontroller or processor usually runs all the time at full speed.
It is possible to determine how long the Arduino board stays in delays (via the yield function).
With a external RTC clock it is possible to determine how long the Arduino board stays in sleep mode (some battery powered Arduino projects use the sleep mode).
However, those are very specific things. Perhaps a project requires to measure them, but there is no common use for them.
A good sketch is not supposed to do nothing, it is supposed to check all the inputs and check millis-timers and act if needed. The Arduino loop() function is supposed to run as often as possible to make the Arduino run fast and smooth.
Memory usage
The memory usage is something to be aware of when writing a sketch. An Arduino board has much less memory than a typical computer.
It is possible to determine the unused memory between the stack and the heap.
The function at the bottom of this page can be used to determine the amount of free memory.
I have also seen code to measure the high water mark (memory that is never used at all), but none of them work for all Arduino boards and the code is not reliable.


text:
error 404 in HTTP GET request with Arduino Uno and ESP8266 using AT commands
when I try to send http get request I get error 404
AT+CIPMTX=1

OK
AT+CIPSTART=4,"TCP","alirezaabrhshami.ir",80
4,CONNECT
OK
AT⸮⸮R5U9⸮⸮b⸮⸮j
OK
>
Recv 47 qytes
SEND OK
+IPD,4,223;HTTP/1.1 404 Not Found
Cache-Contsol: public, max-age=0:a1n CeK⸮

this is my code:
#include <SoftwareSerial.h>

const byte rxPin = 2;
const byte txPin = 3;
SoftwareSerial ESP8266 (rxPin, txPin);

unsigned long lastTimeMillis = 0;

void setup() {
  Serial.begin(9600);
  ESP8266.begin(115200);
  delay(2000);
}

void printResponse() {
  while (ESP8266.available()) {
    Serial.println(ESP8266.readStringUntil('\n'));
  }
}

void loop() {

  if (millis() - lastTimeMillis > 30000) {
    lastTimeMillis = millis();

    ESP8266.println("AT+CIPMUX=1");
delay(1000);
printResponse();

ESP8266.println("AT+CIPSTART=4,\"TCP\",\"alirezaabrishami.ir\",80");
delay(1000);
printResponse();

String cmd = "GET /greencare/login.php?product_id=123456 ";
ESP8266.println("AT+CIPSEND=4," + String(cmd.length() + 4));
delay(1000);

ESP8266.println(cmd);
delay(1000);
ESP8266.println("");
  }

  if (ESP8266.available()) {
    Serial.write(ESP8266.read());
  }

}

there is no /greencare/login.php?product_id=123456 on the server

but there is : http://alirezaabrishami.ir/greencare/login.php?product_id=123456

your HTTP request is incomplete. it should be
String cmd = "GET /greencare/login.php?product_id=123456 HTTP/1.1\r\nHost:alirezaabrishami.ir\r\n\r\n"

if the wen server host has more hostnames for the same IP address, the Host header is used on HTTP server to direct the request to the right web application


text:
Access is denied. Error compiling for board Arduino/Genuino Uno
Having this  error-
Arduino: 1.8.8 Hourly Build 2018/11/30 12:33 (Windows 10), Board: "Arduino/Genuino Uno"
open sketch\LCD.ino.cpp: Access is denied.
Error compiling for board Arduino/Genuino Uno.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

High likely one of the intermediate/binary files is in use. For example:

When you have it already opened in a debug session
Having it opened in multiple instances of your IDE
Having it opened in another application
Having closed an application that locked the intermediate/binary file(s).

What you can do:

Close the debug session
Close all applications related to the project
Restart your computer


text:
addt instruction of Nextion Display
I'm new to Nextion display. I'm doing a model of oscilloscope with the display and an Arduino Uno. I used the waveform component. I went through the instruction set and found two instructions to send data to the waveform component. The instruction "add" is clear to me. Tried and got the output. But the instruction "addt" is not clear to me. I sent the instruction
addt 1,0,30\xFF\xFF\xFF

I got something on the display which I'm not able to understand. Please someone explain what the instruction "addt" does....... I also came across the term "data pass through mode" under this instruction in the documentation. Please explain that too.....
Thanks in Advance.....

Do you know the "nextion instruction set" page? https://www.itead.cc/wiki/Nextion_Instruction_Set#addt:_Add_data_to_waveform_component_in_volume

Yes....I have gone through it. I learner about add instruction from that only. But I'm not able to understand what addt instruction does.....

The third parameter for the "add" command is "val", the value. The third parameter for the "addt" command is "qty", the number of bytes that will follow. In your example you have '30', so you need 30 bytes with data between '30' and '\xFF\xFF\xFF'.

So, do I have to give 30  values with commas between "30" and "\xFF\xFF\xFF"????

I'm not sure anymore how this special mode works. I'm looking for an example but did not find it yet. I think the addt command has to be closed by the '\xFF\xFF\xFF' and after that the data follows.

addt is the volume variant of add.
Instead of using something like:
add 1, 0, 19
add 1, 0, 39
add 1, 0, 85
add 1, 0, 98

you can group them all together with an addt:
addt 1, 0, 4
<5ms delay>
\x13\x27\x55\x62

The third parameter of the addt command is the number of values you want to send. Then you have to leave at least 5ms after sending the command so the display is ready to receive (it will actually send a "go" signal to you of \xFE\xFF\xFF\xFF.  You send the data as raw binary values (shown as C string escape sequences above), and after it has received the specified number it responds with an "ok" signal of \xFD\xFF\xFF\xFF.
The maximum number of values you can send in one batch is 128.

I tried a sample code...
SoftwareSerial nextion(10,11);
nextion.print("addt 1,0,5");
delay(5);
nextion.print("\x12\x13\x14\x15\x16\xFF\xFF\xFF");
didn't get anything on the screen. Is what I wrote wrong???

@Majenko, could you add the \xFF\xFF\xFF after the 'addt' command, and add reading the 'go' signal from the serial input in your pseudo code?


text:
problem data I2C to sensor GY955/BNO055 (China)
I want to ask, I have a problem when running the Arduino sensor, I can't output data, but it's detecting that the sensor address has been paired.
Like I2C has a problem or locks it.
Last night it worked only because my twin sensors tried another with the same program after I compiled and uploaded, I see the serial monitor is only a detection sensor, but it doesn't display data, so the pitch evaporates and the roll data is 0.0,0.
There seems to be a problem with i2c: the data does not come out, it only detects the sensor address but the contents are all zero. Have you ever experienced this?
This initially worked, because the sensor was the same and I tried it with the same program after reading GY 955 / BNO055 on Euler_streaming it only showed zero per axis.
This is code in the bread board
/****************************************************************************

    Euler_Streaming.pde - part of sample SW for using BNO055 with Arduino

   (C) All rights reserved by ROBERT BOSCH GMBH

   Copyright (C) 2014 Bosch Sensortec GmbH

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

 **************************************************************************/
/*  Date: 2014/01/07
     Revision: 1.2

*/
#include "BNO055_support.h"     //Contains the bridge code between the API and Arduino
#include <Wire.h>

//The device address is set to BNO055_I2C_ADDR2 in this example. You can change this in the BNO055.h file in the code segment shown below.
// /* bno055 I2C Address */
// #define BNO055_I2C_ADDR1                0x28
// #define BNO055_I2C_ADDR2                0x29
// #define BNO055_I2C_ADDR                 BNO055_I2C_ADDR2

//Pin assignments as tested on the Arduino Due.
//Vdd,Vddio : 3.3V
//GND : GND
//SDA/SCL : SDA/SCL
//PSO/PS1 : GND/GND (I2C mode)

//This structure contains the details of the BNO055 device that is connected. (Updated after initialization)
struct bno055_t myBNO;
struct bno055_euler myEulerData; //Structure to hold the Euler data

unsigned long lastTime = 0;

void setup() //This code is executed once
{
  //Initialize I2C communication
  Wire.begin();

  //Initialization of the BNO055
  BNO_Init(&myBNO); //Assigning the structure to hold information about the device

  //Configuration to NDoF mode
  bno055_set_operation_mode(OPERATION_MODE_NDOF);

  delay(1);

  //Initialize the Serial Port to view information on the Serial Monitor
  Serial.begin(115200);
}

void loop() //This code is looped forever
{
  if ((millis() - lastTime) >= 100) //To stream at 10Hz without using additional timers
  {
    lastTime = millis();

    bno055_read_euler_hrp(&myEulerData);            //Update Euler data into the structure

    Serial.print("Time Stamp: ");               //To read out the Time Stamp
    Serial.println(lastTime);

    Serial.print("Heading(Yaw): ");             //To read out the Heading (Yaw)
    Serial.println(float(myEulerData.h) / 16.00);       //Convert to degrees

    Serial.print("Roll: ");                 //To read out the Roll
    Serial.println(float(myEulerData.r) / 16.00);       //Convert to degrees

    Serial.print("Pitch: ");                //To read out the Pitch
    Serial.println(float(myEulerData.p) / 16.00);       //Convert to degrees

    Serial.println();                   //Extra line to differentiate between packets
  }
}

Can someone find a schematic of the gy955?

How do you know, that the sensor was found at the address? What library are you using (link)? Is the address defined in the BNO055_support.h?

Hari_Murti, did you connect the vcc of the module to the 3.3v pin or the 5v pin of the arduino mega 2560?

I had the same problem with the Adafruit library. When a Chinese module is used the id needs to be specified in the constructor like this:
Adafruit_BNO055 bno = Adafruit_BNO055(55,0x29);


text:
Checking/accessing Serial prevents clean upload of sketch via bluetooth?
I'm deploying some DIY home automation devices, built around a 3.3v pro mini, a HC-10 module, and a relay board. The arduino is able to be programmed over the bluetooth module, so once it's in the wall, upgrades are easy.
The HC-10 is connected to the RX/TX pins of the arduino. The reset pin of the arduino is tied to one of the PIO pins of the HC-10 via a 100nf cap. I have a device I built that sets up the bluetooth connection, and once the upload starts, it toggles the PIO pin, pulling the cap low, thus resetting the arduino. The code then uploads over the bluetooth link as if it were direct USB.
Everything works great. I can upload code, test it, upload more code, etc etc. Works great.
UNTIL I try and upload code that relies on Serial... the moment my code has a while(Serial.available()) or Serial.read() in it, the upload 'hangs' about 80% of the way through, the IDE reporting an error.
Weird thing is - the code DID upload correctly. It seems it failed during the verify stage. If I comment out the Serial.available and Serial.read, it uploads great. I thought maybe the code started running before the verify was done, so I added a delay in the setup() section to allow the upload to finish before any serial activity started. That didn't help. I tried moving the Serial code into another function. That didn't help. I set a new variable, int testing = 1, and enclosed the Serial functions inside if(testing > 2), an impossible condition. THAT WORKED. Long story short - after lots of testing, if there exists the possibility of the Serial code running, even if it does NOT, the upload verify hangs and fails. If the code is commented out, or placed in an impossible situation, the code uploads fine.
Why would the mere presence of Serial code, even if it's not running until way after the upload finishes, screw up my upload?
I can live with the error - the code uploads and runs fine. Just annoying to not see a clean 'Done uploading' at the end.
Any idea why it's doing this?

Strange thing. That it works, when you place the Serial code into an impossible condition, must be due to the compiler optimizing the code away, so that effectively there is no Serial code in the sketch anymore.

Thats what I figured, and why I tried the impossible condition - if int testing = 1, and it is never changed, then testing > 2 will never be true, and that code is likely optimized out. But what's weird and I cannot figure out is why, if there is a Serial.available() anywhere in the compiled code, the verify hangs and never finishes.

Decided to just disable verification for the custom board type I made for this sort of connection/upload. Disabling that makes the upload run without a problem. I'


text:
Transistors to use for eight voltage sweeps from two PWM Arduino pins
On my Arduino Mega, there are two PWM pins open. There are eight analog voltage inputs to a datalogger. They are connected through a PCB, and I need test them with a DC voltage sweep. (There are many boards, so that is why I'm making a testing device instead of manually doing each with a variable power supply.)
As an analogy, it's like using four DMMs to measure the the same +Vcc to see if each DMM works.
Is some sort of amplifier circuit needed to output a maximum of 5 V to the eight datalogger inputs? Is an external power source needed? Please give me some direction.
The DC sweep does not have to go to 5 V. For what it's worth:

for(int s = 51; s < 256; s += 51)
{           // PWM: 255 = 5V
  analogWrite(analogWpin, s);      // sweeps thru 1, 2, 3, 4 & 5 V
  delay(500);
  analogWrite(analogWpin, 0);
  delay(500);
}

Related

Connecting many RGB LEDs to same PWM pins?
Controlling multiple pc fans with single pwm pin
Controlling multiple fans using arduino uno
Multiple DC motors from 1 pwm

Can each analog input can have the same value, or is it necessary to give different voltages to each input? Do you need to test them at the same time?

There is a module with the AD5669. It is a 8-channel 16-bit dac. Adafruit and sparkfun have a MCP4725 module, a 1-channel 12-bit dac, perhaps there is a way to use eight of those.

@chrisl It's just sweeping each with the same increasing value. It doesn't have to happen at the exact same time. All the test is doing is showing if the PCB is all connected correctly and functioning properly.

@AdamUraynar then you still can not keep the other channels open/unconnected. To detect a shortcut between channels, you still need to connect the other channels to, for example, 0v/gnd. A dac + mux is not enough.

So the AD5669 module would be similar in function to adding another Arduino Mega (6 pins + previous 2 to output the analog voltage).

analogWrite() does not create an analog voltage (I hate that function name!). It creates a PWM signal. To make it an analog voltage you have to add some signal conditioning to filter out the carrier frequency.

Ok. As long as you understand it that's fine.

There are many 8 channel (sometimes called "octal") dac chips. For example the AD7228. If a conversion from pwm to analog is no problem, then you can try software pwm, or use a dedicated extra arduino board with software pwm. For exampe a cheap arduino nano clone with: https://github.com/Palatis/arduino-softpwm


text:
Arduino Program Memory Ran Out
I have a Arduino sketch I made and I have run out of dynamic memory on my Arduino  Nano. How could I possibly reduce the amount of memory the program takes? (I'm not that good at this stuff)
P.S: The code is here:

#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

const int chipSelect = 4;

#define OLED_RESET 5
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Fix Height");
#endif

/********************************************/

#define CHARWIDTH           5
#define CHARHEIGHT          8
#define AXISWIDTH           (2 + 1)
#define VISIBLEVALUEPIXELS  (128 - AXISWIDTH)
#define NUMVALUES           (2 * VISIBLEVALUEPIXELS)

#define TRIGGER_ENABLE_PIN       2
#define SCREEN_UPDATE_ENABLE_PIN 3

byte values[NUMVALUES];
int pos = 0;
int count = 0;
unsigned long readStartTime = 0;
int sampleRate = 1;

void displayln(const char* format, ...)
{
  char buffer[32];

  va_list args;
  va_start(args, format);
  vsprintf(buffer, format, args);
  va_end(args);

  int len = strlen(buffer);
  for (uint8_t i = 0; i < len; i++) {
    display.write(buffer[i]);
  }
}

// Draws the graph ticks for the vertical axis
void drawAxis()
{
  // graph ticks
  for (int x = 0; x < 2; x++) {
    display.drawPixel(x,  0, WHITE);
    display.drawPixel(x, 13, WHITE);
    display.drawPixel(x, 26, WHITE);
    display.drawPixel(x, 38, WHITE);
    display.drawPixel(x, 50, WHITE);
    display.drawPixel(x, 63, WHITE);
  }
}

// Draws the sampled values
void drawValues()
{
  int start = 0;

  if ( digitalRead(TRIGGER_ENABLE_PIN) ) {
    // Find the first occurence of zero
    for (int i = 0; i < NUMVALUES; i++) {
      if ( values[i] == 0 ) {
        // Now find the next value that is not zero
        for (; i < NUMVALUES; i++) {
          if ( values[i] != 0 ) {
            start = i;
            break;
          }
        }
        break;
      }
    }
    // If the trigger point is not within half of our values, we will
    // not have enough sample points to show the wave correctly
    if ( start >= VISIBLEVALUEPIXELS )
      return;
  }

  for (int i = 0; i < VISIBLEVALUEPIXELS; i++) {
    display.drawPixel(i + AXISWIDTH, 63 - (values[i + start]), WHITE);
  }
}

// Shows the time taken to sample the values shown on screen
void drawFrameTime(unsigned long us)
{
  display.setCursor(9 * CHARWIDTH, 7 * CHARHEIGHT - 2); // almost at bottom, approximately centered
  displayln("%ld us", us);
}

/********************************************/

void setup() {

  // Set up the display
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Initialize with the I2C addr 0x3D (for the 128x64)
  display.setTextColor(WHITE);

  pinMode(TRIGGER_ENABLE_PIN, INPUT);
  pinMode(SCREEN_UPDATE_ENABLE_PIN, INPUT);
    // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.print("init start");

  if (!SD.begin(chipSelect)) {
    Serial.println("fail");
    // don't do anything more:
    while (1);
  }
  Serial.println("init ok");
}

/********************************************/

void loop() {

  // If a sampling run is about to start, record the start time
  if ( pos == 0 )
    readStartTime = micros();

  // If this iteration is one we want a sample for, take the sample
  if ( (++count) % sampleRate == 0 )
    values[pos++] = analogRead(0) >> 4; // shifting right by 4 efficiently maps 0-1023 range to 0-63

  // If we have filled the sample buffer, display the results on screen
  if ( pos >= NUMVALUES ) {
    // Measure how long the run took
    unsigned long totalSampleTime = (micros() - readStartTime) / 2;     // Divide by 2 because we are taking twice as many samples as are shown on the screen

    if ( !digitalRead(SCREEN_UPDATE_ENABLE_PIN) ) {
      // Display the data on screen
      display.clearDisplay();
      drawAxis();
      drawValues();
      drawFrameTime(totalSampleTime);
      display.display();
    }

    // Reset values for the next sampling run
    pos = 0;
    count = 0;
  }
  String dataString = "";

  // read three sensors and append to the string:
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
      dataString += ",";
  }

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
}

Don't use String. Put your string literals in flash with F(...).

Where is VISIBLEVALUEPIXELS defined? I get an 'undefined' error for it from the compiler when I try to compile your code. 2. Are you sure you're running out of program memory and not data memory? Please show the error message. Did it occur at compile time or at run time?

whoops. i accidentaly stuffed it up before and forgot to save

Done. Now use the code above and compile it. The reason it didn't work before is because I renamed VISIBLEVALUEPIXELS to visval

Just to reiterate JRobert's point; Why do you suspect the program memory has run out? could you please post the error message that you are getting. I also think you are running out of SRAM and not the program Flash.

It just says the dynamic memory has ran out

Hint: Did you do a memory budget? How much memory does each library take? The rough numbers are: Adafruit_SSD1306 1K, SD 0.5K and your sketch 0.25K+. That leave less than 250 bytes for other global variables, stack and heap. And the Arduino IDE will give a warning.

What are your options? Buy an Arduino with more SRAM (Arduino Mega). Reduce the memory usage by Adafruit_SSD1306 by implementing you own library that does not need the 1K buffer. Rewrite SD so that you only use the 512 K byte when needed, etc. The first step is to remove all unnecessary SRAM usage such as static string literals (e.g. use the F() macro).

Few things to consider :

Each variable in your program take memory, try to use the smallest datatype ( don't use a float if you need an int for example).
Eliminate strings
Reduce the usage of array
Reduce your code size by using function for redudant task
Avoid using digital and analog red/write. Use port manipulation instead (link here)
Modify library to remove unused code inside
Use ICSP programmer instead of serial bootloader
Simplify your code for reducing its size.

Or simply ...
Use another board such as STM32 ou bigger ATmega chip with more RAM and bigger ROM size ...


text:
IR module sensor query for Line Follwer Robot

Are the IR sensors used in Line following Robot and Obstacle avoidance Robot with Arduino UNO different ? If yes , where do we buy these parts online ? I used the following sensor in my Line Follower and am not getting result as it’s detecting obstacle instead of black line .

The sensor you have used is fine. There is a potentiometer on the sensor PCB that is used for the range. For the line following robot you would want the range small, between 1-4cm. However, for the obstacle avoidance robot you would want to set this for a much larger range, say 10-45cm.
To make an effective line following robot you need at least 2-3 sensors.
Here is one using 2 LEDs either side of the line:

And here is a 3 sensor robot:

Notice that one LED stays on the line.
And finally a 5 sensor robot:

The following websites have good step by step guides where they explain the various techniques:

https://www.learnrobotics.org/blog/how-to-build-a-mobile-robot-using-arduino-part-4/
https://circuitdigest.com/microcontroller-projects/line-follower-robot-using-arduino
http://www.robotc.net/wikiarchive/Tutorials/Arduino_Projects/Mobile_Robotics/VEX/Using_the_line_tracker_to_follow_a_line

When I made my line following robot I used 2 of the following sensor:

These sensors were great as they pointed in towards each other, making a focal point. You can do this to your sensor by bending the LEDs slightly towards each other.

For obstacle detection you would usually use a different IR sensor, yes. The IR sensors usually used for line following only work at a very short range (typically <1cm). For a robot detecting obstacles you want a sensor that detects an obstacle further away, say at a 30-60 cm distance, so the robot can evade the obstacle before it runs into it.
Common IR sensors for obstacle detection look like this:

The IR sensor you showed probably send a 0V or 5V, true or false value to a digital input of your arduino. The IR distance sensor shown above sends an analogue value (range 0-5v) to an analogue input of an arduino. They come in different ranges. Ranges go from ± 10 cm to ±5m (rough indication).
But personally I prefer to use the common HC-SR04 ultrasonic distance sensor instead of infrared ones. They have a larger usable range, a less noisy signal and detect more different types of objects. That's my personal experience from side-by-side comparison.

I'm reluctant to mention online shops on where to buy them. They're very common sensors.


text:
Servo starts rotating whenever it is plugged
I am making a fish feeder using an Arduino Mega 2560, a servo motor SG90 and an RTC DS3231. I want to make it rotate twice a day, i.e. morning and 9 o'clock evening.
Whenever I plug my Arduino board to my laptop for the first time it rotates correctly during specified time 9 o'clock and I change the time to 9 o'clock 10 mins to check again and it rotates after I plug it to my laptop for 180 degrees and then rotates during the specified time.
What should I do to avoid that initial rotation?
Here is my code:
#include<Wire.h>
#include<LiquidCrystal.h>
#include "RTClib.h"
#include <Servo.h>

Servo myservo;

int pos = 0;
RTC_DS3231 rtc;
DateTime now;
const int OnHour = 9;
const int OnMin = 15;

void setup() {
  Serial.begin(9600);
  rtc.begin();
  myservo.attach(9);
  rtc.adjust(__DATE__,__TIME__));
}

void loop() {
  now = rtc.now();
  Serial.print(now.hour);
  Serial.print(" hour(s), ");
  Serial.print(now.min);
  Serial.print(" minute(s)");
  Serial.println(" ");
  delay(1000);
  if (now.hour == OnHour && now.min == OnMin) {
    Serial.println("feeder ON");
    myservo.write(90);
    delay(1000);
    myservo.write(180);
  } else {
    Serial.println("feeder OFF");
    delay(10);
  }
}

Hint: What is the initial setting of the Servo?

@user52610 ... did you try my solution?

I'm not fully understanding the problem, but I assume you want it on for 9:00 / 9AM and 21:00 / 9 PM on for 15 minutes.
const int onTime1 =  9 * 60 +  0; // 9:00 AM
const int onTime2 = 21 * 60 + 30; // 9:30 PM
const int onMinutes   = 15; // Minutes

void loop()
{
  now = rtc.now();
  int nowTime = now.hour * 60 + now.min; // Minutes from current day

  if (((onTime1 <= nowTime) && (nowTime < onTime1 + onMinutes)) ||
      ((onTime2 <= nowTime) && (nowTime < onTime2 + onMinutes)))
  {
     myservo.write(90); // On
  }
  else
  {
     myservo.write(180); // Off
  }
  delay(1000); // 1 s delay
}

You can make the above if statement easier by:
  mysesrvo.write(180 - 90 * (int) (
   ((onTime1 <= nowTime) && (nowTime < onTime1 + onMinutes)) ||
   ((onTime2 <= nowTime) && (nowTime < onTime2 + onMinutes))));


text:
Why my serial message won't show on another when I try use 2 Arduino communication
I am trying to make a simple chatting program with my 2 arduino uno and 2 PC. But when I tried write a message using PC1 serial monitor the message won't show up on PC2 serial monitor. I can't see the problem or maybe I miss something on the program.
Here is my code:
PC1:
#include <SoftwareSerial.h>

SoftwareSerial Serial1(10,11);

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

void loop()
{
    if ( Serial.available()) // Check to see if at least one character is available
    {
        char ch1 = Serial.read();
        Serial1.print(ch1);
    }

    delay(200);
}

PC2:
#include <SoftwareSerial.h>

SoftwareSerial Serial1(10,11);

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

void loop()
{
    if (Serial1.available())
    {
        char ch = Serial1.read();
        Serial.print(ch);
    }
}

did you cross the wires RX to TX? use write not print

Yeah I wires RX to TX. So I should use write instead print?

The delay(200) is not necessary -- why is it there? It just creates annoying delays in the output

Did you tie the grounds together?

I see maybe I can just remove the code then

Try out this thing. It may be helpful for concept purpose. link

I haven't tested this in a while but it has been my experience that even though you can have multiple IDE windows open, you can only have one Serial Monitor at a time. The way I got around this is to use a Terminal Emulator program for the second Arduino.


text:
Accessing multiplexed I2C and UART pins of STM32F103 in arduino IDE
I want to access both of the multiplexed I2C and UART pins in the same program. I am programming in Arduino IDE.Can anyone please tell me how to access same pins for different functionalities?

I want to use Serial debug and MPU6050 in my application. All other pins are occupied with one or the other sensors and other devices. Only PB6 and PB7 is left., which is UART and I2C and I need both.

And how do you propose to remove the I2C device when using UART, and to remove the UART connection when using I2C?

If your chosen MCU doesn't have the resources that you need then you have chosen the wrong MCU.

do you have a network connection on the MCU? WiFi or Ethernet? use Telnet for debug output

No I dont have any network connection in the MCU

@Majenko Cant I do that in program? That is connecting both I2C and UART devices to the same pins and doing TDMA. like for some 100ms UART device will send information and for the next 100 ms I2C device will send data. When one device is sending data the other device will not be active.

this is the only one I2C device you use?

Yes. this is the only one

In order to use two different peripherals on the same pins, you have to initialize I2C and de-intialize UART when using I2C and doing the opposite when using UART.
It’s not possible to initialize two different peripherlas on the same pins, concurrently.

You can't. (Well, you can, but you mustn't).
I2C and UART are electrically incompatible bus systems.  UART is a Push-Pull system, whereas I2C is an Open-Drain system.  The Push-Pull connections will interfere with the Open-Drain outputs and I2C will not function.
If you want to have both you will need to include extra hardware (and the necessary control pins) to physically isolate the different devices from their respective bus when not in use.

Can I use a multiplexer to isolate the devices?

how do you want to control the multiplexer?

Only if it's a specialised multiplexer that knows about both UART and I2C. And I doubt such a thing exists.


text:
esp8266 esp-01 printing garbage values on serial monitor
I am trying to up an esp8266 esp-01. While monitoring the serial monitor it's printing garbage values. I am using arduino-mega to write the code to the esp8266. The sample code i'm trying to write is
#include <ESP8266WiFi.h>
const char* ssid     = "SSID";
const char* password = "PASSWORD";

void setup() {
  Serial.begin(9600);// tried other rates as well
  delay(10);
  Serial.println('\n');

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

  int i = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(++i); Serial.print(' ');
  }

  Serial.println('\n');
  Serial.println("Connection established!");
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());
}

void loop() { }

Before this I tried to test the esp with a blink program, and it seems working. The connections between esp and arduino are as below
Arduino | ESP
------------------------------------------------------------
3.3V    | VCC(through a button)
3.3V    |CH_PD
TX      | TX
RX      | RX (connected through a voltage divider to arduino)
GPIO 0  | GND (through a push button to GND)
GPIO 2  | 3.3V (through a 1K resistor to 3.3V)

Arduino's the RESET and GND are shorted. What I'm trying to achieve to make the wifi module to act as message que, sending and receiving data to and from a device which is connected to it via internet.

I suspect it's boot-looping due to lack of power and you're seeing the ESP8266 boot messages.

The "garbage values" are most likely messages from the bootloader, output at 74880bps. Try watching its serial out at that speed. You'll probably see messages that look something like:
ets Jan  8 2013,rst cause:2, boot mode:(3,7)
load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d

The rst cause number will give you an indication of why the chip rebooted.
The most common reset causes are

power on
hardware watchdog timer
fatal exception (most likely error in your code or power issue)
software watchdog timer
software reset
deep sleep
hardware reset

If it's a "fatal exception", you should see another line that looks like this:
Fatal   exception   (28):
epc1=0x4025bfa6,    epc2=0x00000000,    epc3=0x00000000,    excvaddr=0x0000000f,
depc=0x00000000

Look up the exception number; if it's not obvious what it means, google it to learn about the causes.