message:
ESP-01 Deep Sleep not waking up properly

I have a temperature/humidity project using an ESP-01 and DHT11.  I want to be able to put t into deep sleep to preserve battery life.  I have soldered a wire from GPIO16 to RST.

    #include <SimpleTimer.h>  //https://github.com/jfturcot/SimpleTimer
    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>  //https://github.com/knolleary/pubsubclient
    #include <ESP8266mDNS.h>
    #include <WiFiUdp.h>
    #include <ArduinoOTA.h>  //https://github.com/esp8266/Arduino/tree/master/libraries/ArduinoOTA
    #include "DHT.h"

    //USER CONFIGURED SECTION START//
    #define DHTPIN 2     // what digital pin we're connected to

    const char* ssid = "mySSID";
    const char* password = "password";
    const char* mqtt_server = "mqttserverip";
    const int mqtt_port = 1883;
    const char *mqtt_user = "usser";
    const char *mqtt_pass = "pass";
    const char *mqtt_client_name = "DryerMCU"; // Client connections can't have the same connection name
    //USER CONFIGURED SECTION END//

    // Uncomment whatever type you're using!
    #define DHTTYPE DHT11   // DHT 11
    //#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
    //#define DHTTYPE DHT21   // DHT 21 (AM2301)

    // Initialize DHT sensor.
    // Note that older versions of this library took an optional third parameter to
    // tweak the timings for faster processors.  This parameter is no longer needed
    // as the current DHT reading algorithm adjusts itself to work on faster procs.
    DHT dht(DHTPIN, DHTTYPE);

    WiFiClient espClient;
    PubSubClient client(espClient);
    SimpleTimer timer;

    bool boot = true;
    int status = WL_IDLE_STATUS;

    //Functions
    void setup_wifi()
    {
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED)
      {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
    }

    void getTemperature()
    {
      // Reading temperature or humidity takes about 250 milliseconds!
      // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
      float h = dht.readHumidity();
      // Read temperature as Celsius (the default)
      float t = dht.readTemperature();
      // Read temperature as Fahrenheit (isFahrenheit = true)
      float f = dht.readTemperature(true);

      // Check if any reads failed and exit early (to try again).
      if (isnan(h) || isnan(t) || isnan(f)) {
        Serial.println("Failed to read from DHT sensor!");
        return;
      }

      // Compute heat index in Fahrenheit (the default)
      float hif = dht.computeHeatIndex(f, h);
      // Compute heat index in Celsius (isFahreheit = false)
      float hic = dht.computeHeatIndex(t, h, false);

      Serial.print("Humidity: ");
      Serial.print(h);
      Serial.print(" %\t");
      Serial.print("Temperature: ");
      Serial.print(t);
      Serial.print(" *C ");
      Serial.print(f);
      Serial.print(" *F\t");
      Serial.print("Heat index: ");
      Serial.print(hic);
      Serial.print(" *C ");
      Serial.print(hif);
      Serial.println(" *F");

      char temperature[50];
      char humidity[50];

       // Update temperature and humidity
      String temp_str = String(f);
      temp_str.toCharArray(temperature, temp_str.length() + 1);
      client.publish("dryer/temperature", temperature);

      String hum_str = String(h);
      hum_str.toCharArray(humidity, hum_str.length() + 1);
      client.publish("dryer/humidity", humidity);

    }

    void setup() {
      Serial.begin(38400);
      delay(2000);
      Serial.println("Booting");

      dht.begin();
      setup_wifi();
      client.setServer(mqtt_server, mqtt_port);
      getTemperature();

      Serial.println("Going to sleep");
      ESP.deepSleep(10000000,RF_DEFAULT);
    }

    void loop() {

    }

When I start it up it takes one measurement, goes to sleep and then wakes up, but nothing happens once it wakes up.  Serial output:

    Booting

    Connecting to SSID
      ......
    WiFi connected
    IP address:
    mqttip
    Humidity: 51.00 % Temperature: 20.00 *C 68.00 *F Heat index: 19.39 *C 66.90 *F
    Going to sleep

    ets Jan  8 2013,rst cause:5, boot mode:(3,7)

    ets_main.c

body:
I guess you have a race condition between automatic connection to WiFi by the Espressif SDK and your WiFi.begin(). You have two options how to solve it.

**1. option:** Don't use WiFi.begin in this sketch. Use an utility sketch to set the SSID and password and the SDK remembers it persistent on flash. Then it is able to connect fast to WiFi specially on reset, because it has the WiFi channel number in RTC memory which is not cleared at reset (only on power down).

**2. option:** turn of remembering of the SSID and password and the automatic connection at start. Then the esp8266 will connect to the WiFi only with your `WiFi.begin` call. The commands are [`WiFi.persistent(false)`][1] and [`WiFi.setAutoConnect(false)`][2].

You can turn of the SoftAP too. At default it starts automatically. The command is [`WiFi.softAPdisconnect()`][3]

  [1]: https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/generic-class.html#persistent
  [2]: https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/station-class.html#setautoconnect
  [3]: https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/soft-access-point-class.html#softapdisconnect


sender: user

sender: assistant

body:
*In the question the OP said:*

>  I have soldered a wire from GPIO16 to RST.

*But, I'm going to post an answer for the people who find this question and need the ESP-01 modification instructions in order to wake an ESP-01 module up from deep-sleep:*

The ESP8266 mounted on an ESP-01 board will not wake up from deep-sleep because the ESP8266 wake up signal is not connected to the reset pin of the ESP8266 on an ESP-01 board.  You need to add this connection which can be difficult for most people.  You can see the modification in this picture:
[![enter image description here][1]][1]
...which comes from [this instructables posting][2].

If this is too difficult, consider using a different ESP8266 board which brings these ESP8266 pins to board edge connectors.

  [1]: https://i.stack.imgur.com/bdHi8.jpg
  [2]: https://www.instructables.com/id/Enable-DeepSleep-on-an-ESP8266-01/


message:
Distance Measurement - between 6 points, individually moving in (almost) any direction within 1m

I'm trying to find a solution for a given task in a problem I want to solve.
Assume I have 6 individual Points in a 3D environment of about 1m³. Each point will be able to change position (almost) freely.
Is there a way I can get the information of which distance each point is to any of the remaining 5 points?
Background Idea for understanding: Say its 2 wooden triangles (one of those points on each angle) and I need to calculate how far and in which direction one is moving from or towards the other.
By comparing all those distances, direction and step-width may be easily calculated.
Are there like "coded" distance-sensors so they don't mix their signals?
Any thoughts highly appreciated.

body:
The vertices of two (wooden) triangles already constrains the problem - in a positive way - since the inter-point distances of each triangle's vertices is constant. If they were 6 individual, free-floating points, the job would be that much more complex -- 30 unknown distances (each point to each other point), instead of only 18 (each vertex to each of 3 vertices on the other triangle). That's the math part.

The technology part - what kind of sensors - will need more specifics to answer. For instance, ultrasonic sensors may have an interference problem with wooden triangles drifting about. Light and radar may have visibility issues - i.e., can't see certain of the points, depending on the physical shape and implementation of the drifting objects.


body:
You may try to implement some kind of ultrasonic [transponders][]. The
emitter sends a code addressing a specific receiver. Upon recognizing
its address, the receiver replies after a short, fixed delay. The
emitter measures the time it took the response to reach it, and from
there computes the distance.

You may need some kind of omnidirectional transducers (e.g. [this
models][sensortech]) if you want the measurement to work in any
direction. And also a protocol to avoid several emitters talking at the
same time.

This seems to me like a very complex project though.

[transponders]: https://en.wikipedia.org/wiki/Transponder
[sensortech]: https://sensortechcanada.com/products/custom-acoustic-transducers/omnidirectional/


message:
Unable to compile SimpleTimer code - Exit status 1

I downloaded the SimpleTimer library from the Arduino's library manager and navigated to Arduino Playground website for some sample code for testing - [SimpleTimer - Arduino Playground][1]. After copying the following code into the Arduino IDE:

    #include <SimpleTimer.h>

    // the timer object
    SimpleTimer timer;

    // a function to be executed periodically
    void repeatMe() {
        Serial.print("Uptime (s): ");
        Serial.println(millis() / 1000);
    }

    void setup() {
        Serial.begin(9600);
        timer.setInterval(1000, repeatMe);
    }

    void loop() {
        timer.run();
    }

I receive the following error:

    exit status 1
    no matching function for call to 'SimpleTimer::setInterval(int, void (&)())'

Please help me out here as I am doing everything according to the instructions given in the arduino playground page of SimpleTimer.

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

body:
There are quite a few Arduino libraries called “SimpleTimer”. [According
to arduinolibraries.info][arduinolibraries], the one you get through the
library manager is [Alexander Kiryanenko's SimpleTimer][kiryanenko]. The
one described in Arduino Playground is [Marcello Romani's
version][marcelloromani]. You should try the examples that come with the
specific library you install.

[arduinolibraries]: https://www.arduinolibraries.info/libraries/simple-timer
[kiryanenko]: https://github.com/kiryanenko/SimpleTimer
[marcelloromani]: https://github.com/marcelloromani/Arduino-SimpleTimer


message:
How to declare a pointer for arduino neopixels library so I can set it up in the setup function with dynamic variables?

I am using NeoPixel strips, and I want to be able to declare a pointer to them, but not initialize them until the `setup` function (because they will initialize with certain variables only made available in `setup`).

For simpler data types, I am just doing:

    int totalNumColors = 4; //number of colors user can cycle through`
    uint32_t* colorArray = new uint32_t[totalNumColors];
    void setup() {
      for (int i=0;i<totalNumColors;i++){
        colorArray[i] = totalColorArray[i];
      }
    }

How do I do this for NeoPixel strip intializers? I tried:

    Adafruit_NeoPixel* pixels = new Adafruit_Neopixel;`

but I get the error:

    expected type-specifier before 'adafruit neopixel'

body:
You can assign the pointer to NULL, and in the `setup` function give it a value. Note you have to add () for the arguments, even if there are none like in this case. Also you have to include the library (but probably you did but not added in your question).

    #include "Adafruit_NeoPixel.h"

    Adafruit_NeoPixel* pixels = NULL;

    void setup()
    {
      pixels = new Adafruit_NeoPixel();
    }


message:
Pseudo-code of a program

I have written a code but I am facing a problem in pseudo-code that I am not able to change this code, so can anyone help me in translating the Arduino IDE program code to pseudo-code?

```c++
#define BLYNK_PRINT Serial
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include<DHT.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
char auth[] = "py0oKurvtk_Rv2GGkKtghpKqlxLQug8F";
char ssid[] = "Hostal1";
char pass[] = "shakajutt7867";
DHT dht(D4, DHT11);
SimpleTimer timer;
int Relay = D5;
int PIR = D3;
void sendSensor()
{
  float humi = dht.readHumidity();
  float temp = dht.readTemperature();
  int value = digitalRead(PIR);
  if (value == 1)
  {
  digitalWrite(Relay, HIGH);
  Serial.print("Detected");
  Serial.print('\n');
  lcd.setCursor(0,0);
  lcd.print("PIR = Detected");
  lcd.setCursor(0,1);
  lcd.print("T: ");
  lcd.print(temp);
  lcd.setCursor(7,1);
  lcd.print(" H:");
  lcd.print(humi);

  }
  else if (value== 0)
  {
    digitalWrite(Relay, LOW);
    Serial.print("Not Detected");
    Serial.print('\n');
  lcd.setCursor(0,0);
  lcd.print("PIR = Not Det");
  lcd.setCursor(0,1);
  lcd.print("T:");
  lcd.print(temp);
  lcd.setCursor(7,1);
  lcd.print(" H:");
  lcd.print(humi);

  }
  Blynk.virtualWrite(V7, value);
  Blynk.virtualWrite(V5, humi);
  Blynk.virtualWrite(V6, temp);
  delay(1500);
}
void setup()
{
  pinMode(Relay, OUTPUT);
  pinMode(PIR, INPUT);
  digitalWrite(Relay,LOW);
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  dht.begin();
  lcd.begin(16,2);
  lcd.init();
  lcd.clear();
  lcd.backlight();
  lcd.setCursor(0,0);
  timer.setInterval(1000L, sendSensor);
}
void loop()
{

  Blynk.run();
  timer.run();
}
```

body: "Pseudo-code" isn't a programming language. It is just a term that we use when we write code that looks like code but can't be compiled, because it's half-English, half-code. You write pseudo code when you want to communicate to another human how code is supposed to work without getting bogged down in the details.


message:
LSB/MSB and shiftOut

Here is the shiftOut function code from wiring_shift.c
```
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
     uint8_t i;

     for (i = 0; i < 8; i++)  {
           if (bitOrder == LSBFIRST)
                 digitalWrite(dataPin, !!(val & (1 << i)));
           else
                 digitalWrite(dataPin, !!(val & (1 << (7 - i))));

           digitalWrite(clockPin, HIGH);
           digitalWrite(clockPin, LOW);
     }
}
```
Does this mean that least significant bit is on the left and most significant bit is on the right? Or LSBFIRST means that will be the last outputted bit so it will be "first" in outputted sequence?

One more thing

here is a sample code:
```
shiftOut(dataPin, clockPin, LSBFIRST, B00101001);
shiftOut(dataPin, clockPin, LSBFIRST, B11010011);
```

Why does this
```
union
{
     word uniform;
     byte separate[2];
} state;

state.uniform = 54057; // aka 11010011 00101001
shiftOut(dataPin, clockPin, LSBFIRST, state.separate[1]);
shiftOut(dataPin, clockPin, LSBFIRST, state.separate[0]);
```
have different output but if i swap last two lines it works correctly?

body: Integer values of the Arduino have the MSB left and the LSB right. The `shiftOut()` function let's you choose, how the order should be timewise. If you provide `LSBFIRST`, the function will start the transmit with the LSB (on the right) and then go left to the MSB. Otherwise it will start with the MSB and then go right to the LSB. So this effects only the time order of the bits, in that they get transmitted.


body:
There is no "left" or "right" in a binary number, only in the human representation of that number.

It is traditional for us to place the most significant bit on the left, purely because that his how we represent other numbers - like 1234 (1 is the most significant digit, the thousands).

Given the pseudo-number `12345678` if you shift out LSBFIRST the 8 gets output first, then the 7, then the 6, etc. In MSBFIRST the 1 gets output first, then the 2, then the 3, etc.


message:
ESP8266 unresolved mDNS host in .local domain

I am trying to implement a mDNS for esp8266 in Arduino IDE following this guide.

https://tttapa.github.io/ESP8266/Chap08 - mDNS.html

I cannot get the esp8266.local name to work - when i ping it it returns an error unresolved host and putting it in a browser also does not resolve...

The IP address does resolve though. Any advice would be greatly appreciated. I am using Mac OS High Sierra and have seen that many people have experienced this problem on both windows and mac but there does not seem to be a solution yet.

Any ideas?

Thanks x

body:
There is a known bug in the example code you are using.  The author has been notified on github but has apparently chosen to not update their published code.

You need to add the following line to the loop() { } ; section of the code :    **MDNS.update();**

```
 void loop() {
    MDNS.update();
 }
```
Once you do that. it should start working. And without that there is not way to get it working.

Adding this comment for anyone following and searching for a solution to this same problem.


message:
how to combine two code of arduino uno

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

    void loop() {
      int sensorValue = analogRead(A0);
      Serial.println(sensorValue);
      if(sensorValue>550)digitalWrite(mamank,HIGH);
      else if(sensorValue<500)digitalWrite(mamank,LOW);
      delay(100);
    }

-----------------------------------------------AND this code----------------------

    int red=2;
    int green=3;
    int blue=4;

    void setup () {
      pinMode (red,OUTPUT);
      pinMode (green,OUTPUT);
      pinMode (blue,OUTPUT);
      Serial.begin (9600);}

    void loop() {
      // read the input on analog pin 0:
      int value = analogRead(A1);

      if (value > 500) {
        Serial.println("Very heavy Rain");
        digitalWrite (red,HIGH);
        digitalWrite(green,LOW);
        digitalWrite(blue,LOW);}
      else if ((value > 300) && (value <= 500)) {
        Serial.println("AVERAGE Rain");
        digitalWrite (green,HIGH);
        digitalWrite (red,LOW);
        }
      else{
        Serial.println("Dry Weather");
        digitalWrite (blue,HIGH);
        digitalWrite (red,LOW);
        digitalWrite (green,LOW);
      delay(100);
      }
      }

body:
Put the stuff before setup() together, fix any duplicates:

    int mamank=13; <<< pin assignment? If yes, this can be byte
    int red=2; <<< pin assignment? If yes, this can be byte
    int green=3; <<< pin assignment? If yes, this can be byte
    int blue=4; <<< pin assignment? If yes, this can be byte

Put the stuff in setup() together, fix any duplicates

    void setup() {
    pinMode (mamank,OUTPUT);
    Serial.begin(9600);
    pinMode (red,OUTPUT);
    pinMode (green,OUTPUT);
    pinMode (blue,OUTPUT);
    Serial.begin(9600);  <<< duplicate, so delete this line
    }

Put the stuff in loop() together, then check the desired functionality:

    void loop() {
    int sensorValue = analogRead(A0);
    Serial.println(sensorValue);
    if (sensorValue>550) {
    digitalWrite(mamank,HIGH);
    }
    else if (sensorValue<500) {
    digitalWrite(mamank,LOW);
    }
    delay(100);
    // read the input on analog pin 0:
    int value = analogRead(A1);
    if (value > 500) {
    Serial.println("Very heavy Rain");
    digitalWrite (red,HIGH);
    digitalWrite(green,LOW);
    digitalWrite(blue,LOW);
    }
    else if ((value > 300) && (value <= 500)) {
    digitalWrite (green,HIGH);
    digitalWrite (red,LOW);
    }
    else {
    Serial.println("Dry Weather");
    digitalWrite (blue,HIGH);
    digitalWrite (red,LOW);
    digitalWrite (green,LOW);
    delay(100);
    }

    }


message:
I can't use buffer without printing in my Nodemcu esp8266

```
#include <ESP8266WiFi.h>

#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>

#define WIFI_SSID "ssid"
#define WIFI_PASSWORD "password"

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

  std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
  client->setInsecure();
  HTTPClient http;

  http.begin(*client, "https://jsonplaceholder.typicode.com/photos");
  http.addHeader("Accept", "*/*");

  int httpCode = http.GET();
  Serial.print("HTTP CODE: "); Serial.println(httpCode);

  //reading response with buffer
  static char buff[128] = { 0 };
  while (http.connected() ) {
    size_t size = client->available();
    if (size) {
      int c = client->readBytes(buff, ((size > sizeof(buff) ) ? sizeof(buff) : size));
      //if i uncomment this next line, everything is fine.
      //Serial.write(buff, c); Serial.println();

      //but if i dont use serial.write program never gets here
      if (char * pch = strstr (buff, "quis fuga")) {
        char str[20] = { 0 }; int g =   0 ;
        while (pch[g] != '\"') {
          str[g] = pch[ g];
          g++;
        }
        Serial.print("FOUND IT: "); Serial.println(str);
      }

    }
    else if (!size) {
      Serial.println( "reading done");
      break;
    }
    delay(1);
  }

}

void loop() {

  delay(222222);

}

```
**EDIT**
here i created a compilable runnable code. basically i am trying to find a word in a http response. my real example`s response isnt json and it is as long as this example`s response. one other problem is i cant read all of the repsponse. it unexpectedly finishes reading sometimes after a few lines sometimes after a few hundred. in this particular request my nodemcu cant read after id 258. or id 8. object in the json response: <https://jsonplaceholder.typicode.com/photos>

if i dont use serial.write print buffer content, it finishes reading immideatly and thats exactly where i have the problem.

body:
The Serial printing creates a delay. That delay enables to collect more characters in the buffer. If you read the input in small pieces (3 to 10 bytes) then the buffer doesn't contain the searched substring because it splits into two subsequent buffers. Even if you could read full buffers, it still can happen that the search string will be split.

To search for a string in a stream of data you can use function `find(string)`. The networking Client class inherits this function from Arduino Stream class. `find` will read the stream until it finds the searched string. Then the next read from the stream will read the data right after the searched string.


message:
Help with debugging code

This is NOT my code; was [posted on Project Hub](https://projects.digilentinc.com/Shaeroden/humidity-controller-c13dad).   I tried to use the code (humidity controller) but it returns an error on line 270:

    else if (DHT.humidity >= setpoint + 3 and syson == true) { //if humidity is 3% above setpoint
Error: expected primary-expression before '.' token

The OP is not responding to comments and I'm no expert.   Would appreciate if someone could help debug the code;
Thanks!

           //HUMIDITY CONTROLLER 1.1
    //written for NANO

    //controls and displays relative humidity
    //sesnor used is DHT11
    //uses active-low relay module to control live lines for 2 standard electrical outlets
    //uses i2c lcd to display humidity and humidity setting
    //turns display off during inactivity
    //setting is adjustable from 10%-90% using 2 buttons
    //backlight of LCD is controlled by pin 4, connected to top LED jumper pin on i2c backpack
    //serial communications to monitor to ensure all code is working.

    //added: "system off" function - allows both outlets to be turned off

    // █ G █ L █ O █ B █ A █ L █ S █
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    #include <dht.h>

    // set the LCD address to 0x27 for a 16 chars and 2 line display
    LiquidCrystal_I2C lcd(0x27, 16, 2);

    dht DHT;

    #define DHT11_PIN A2

    //buttons and variables to adjust calibration
    int calupbtn = A0;
    int calup;
    int caldownbtn = A1;
    int caldown;

    //i2c PINS A4, A5

    //pin for turning on humidifier relay
    int humidifier = 3;
    //pin for turning on the fan relay
    int fan = 2;
    //pin for turning on LCD backlights
    int lcdlight = 4;

    //calibration variable
    int setpoint = 50;  //feedback setpoint.
    bool calstate = false;  //enables calibration adjustments only when LCD is ON.

    //backlight timing variables
    int displtime = 12000;  //amount of time the display is to be on before turning off
    unsigned long displtimeon;  //last recorded time display timer was reset
    int calunlock = 0;   //loop counter for unlocking calibration

    //sensor timing variables
    unsigned long lastcheck;  //last time DHT was read
    long interval = 30000;      //time between DHT readings

    //system variables
    bool syson = true;    //reference for system on/off.
    byte systog = 2;       //even number toggles on, odds toggle off
    int syslock = 0;     //loop counter for unlocking system toggle

    // █ S █ E █ T █ U █ P █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █
    void setup(){

      Serial.begin(9600);  //serial communication used to ensure code is working correctly.

      lcd.init();  //initialize LCD
      lcd.backlight(); //enable LCD backlight, but doesn't turn it on

      lastcheck = 0;
      digitalWrite(lcdlight, HIGH);
      Serial.println("STARTING");
      lcd.print("   STARTING");

      //pin assignments
      pinMode(calupbtn, INPUT);
      pinMode(caldownbtn, INPUT);
      pinMode(humidifier, OUTPUT);
      pinMode(fan, OUTPUT);
      pinMode(lcdlight, OUTPUT);
      delay(1000);

      //test fan
      lcd.setCursor(0,1);
      lcd.print("<FAN>     HMDFR  ");
      digitalWrite(fan, LOW);
      digitalWrite(humidifier, HIGH);
      delay(6000);
      //test humidifier
      lcd.setCursor(0,1);
      lcd.print(" FAN     <HMDFR> ");
      digitalWrite(fan, HIGH);
      digitalWrite(humidifier, LOW);
      delay(6000);
      //stop startup test
      digitalWrite(humidifier, HIGH);
      digitalWrite(fan, HIGH);
      lcd.clear();

      displtimeon = millis();

      int chk = DHT.read11(DHT11_PIN);
      lastcheck = millis();

      lcd.setCursor(0,0);
      lcd.print("Humidity: ");
      lcd.setCursor(13,0);
      lcd.print(DHT.humidity);
      lcd.setCursor(15,0);
      lcd.print("%  ");
      lcd.setCursor(0,1);
      lcd.print("setting: ");
      lcd.setCursor(13,1);
      lcd.print(setpoint);
      lcd.setCursor(15,1);
      lcd.print("%  ");
      delay(100);
    }

    // █ L █ O █ O █ P █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █
    void loop(){

      //check calibration buttons
      calup = digitalRead(calupbtn);
      caldown = digitalRead(caldownbtn);

      if(calup == HIGH and caldown == HIGH){  //--------SYSTEM TOGGLE
        syslock ++;
        Serial.println(syslock);
        if(syslock == 20){  //if both buttons held down for this many loops
          systog++;
          if(systog % 2 == 1){  //--------SYSTEM OFF
            syson = false;
            digitalWrite(fan, HIGH);
            digitalWrite(humidifier, HIGH);
            digitalWrite(lcdlight, HIGH);
            Serial.println("SYSTEM TURNED OFF");
            lcd.clear();
            lcd.print("   SYSTEM OFF");
            lcd.setCursor(0,1);
            lcd.print("  hold both btns");
            delay(2000);
            lcd.setCursor(0,1);
            lcd.print("  to turn on    ");
            displtimeon = millis();
          }
          if(systog % 2 == 0){  //--------SYSTEM ON
            syson = true;
            Serial.println("SYSTEM TURNED ON");
            digitalWrite(lcdlight, HIGH);
            lcd.clear();
            lcd.print("   SYSTEM ON");
            delay(2000);
            lcd.clear();
            displtimeon = millis();
          }
          syslock = 0;
        }
      }
      else(syslock = 0);

      //read humidity at appropriate intervals
      if(millis() > lastcheck + interval and syson == true){  //read the DHT humidity
        int chk = DHT.read11(DHT11_PIN);
        lastcheck = millis();
        Serial.print("DHT read = ");
        Serial.print(DHT.humidity);
        Serial.print("%");
        Serial.println(" ");
        }

      //turn on the led lights when calibration buttons are pressed
      if(calup == HIGH xor caldown == HIGH){
        digitalWrite(lcdlight, HIGH);
        calstate = true;
        displtimeon = millis();  //set display timer
        Serial.println("cal btn ACTIVE");
        if(syson == false){
          digitalWrite(lcdlight, HIGH);
          lcd.clear();
          lcd.print("   SYSTEM OFF");
          lcd.setCursor(0,1);
          lcd.print("  hold both btns");
          delay(3000);
          lcd.setCursor(0,1);
          lcd.print("  to turn on    ");
          displtimeon = millis();
        }
      }

      if(calstate == true and syson == true){  //--------DISPLAY ROUTINE
        Serial.println("printing display");
        //display variables on LCD
        lcd.setCursor(0,0);
        lcd.print("Humidity: ");
        lcd.setCursor(13,0);
        lcd.print(DHT.humidity);
        lcd.setCursor(15,0);
        lcd.print("%  ");
        lcd.setCursor(0,1);
        lcd.print("setting: ");
        lcd.setCursor(13,1);
        lcd.print(setpoint);
        lcd.setCursor(15,1);
        lcd.print("%  ");
        delay(100);

        calunlock ++;
        //keeps calibration locked until display cycles 5 times after initially turned on
        //prevents adjustments on initial button press.
      }

    //--------CALIBRATION ADJUSTMENTS
      if(calup == HIGH and caldown == LOW and calstate == true and syson == true){
        if(setpoint < 90 and calunlock > 5){
          setpoint = setpoint + 5;  //increase setpoint
          Serial.println("adj setpoint up");
        }
        Serial.println(setpoint);
        delay(100);
        displtimeon = millis();     //reset backlight timeout
      }

      if(caldown == HIGH and calup == LOW and calstate == true and syson == true){
        if(setpoint > 10 and calunlock > 5){
          setpoint = setpoint - 5;  //decrease setpoint
          Serial.println("adj setpoint dn");
          }
        Serial.println(setpoint);
        delay(100);
        displtimeon = millis();     //reset backlight timeout
      }

      if(millis() > displtimeon + displtime){  //-----------------BACKLIGHT TIMEOUT
        digitalWrite(lcdlight, LOW); //turn off the screen
        calstate = false;
        Serial.println("displ + backlights off");
        lcd.clear();
        calunlock = 0;  //lock calibration
      }

      if(millis() < lastcheck){
        lastcheck = millis();  //reset timers in a millisecond rollover
      }

                                          //--------SETPOINT ERROR PROCEDURE
      if(setpoint > 91 or setpoint < 9){  //in case setpoint is ever out of bounds
        Serial.println("O/B ERROR");
        digitalWrite(lcdlight, HIGH);
        lcd.clear();
        lcd.print("O/B ERROR");  //display error message on lcd
        lcd.setCursor(0,1);
        lcd.print("RESETTING");
        delay(1000);
        for(int count = 9; count >= 0; count = count - 1){
          lcd.setCursor(15,1);
          lcd.print(count);     //count down from 10
          delay(1000);
        }
        setpoint = 50;        //reset setpoint at 50.
        displtimeon = millis();
      }

      //turn on humidifier relay if below setpoint  --------RELAY CONTROL
      //RELAY MODULE IS ACTIVE LOW
      if(DHT.humidity <= setpoint - 3 and syson == true){  //if humidity is 3% lower than setpoint
        Serial.println("humidifier ON, fan OFF");
        digitalWrite(humidifier, LOW);  //turn on humidifier
        digitalWrite(fan, HIGH);
      }
      else if(DHT.humidity >= setpoint + 3 and syson == true){  //if humidity is 3% above setpoint
        Serial.println("humidifier OFF, fan ON");
        digitalWrite(humidifier, HIGH);  //turn on fan
        digitalWrite(fan, LOW);
      }
      else{
        Serial.println("all off");  //if humidity is within 3% of setpoint
        digitalWrite(humidifier, HIGH);  //turn both off
        digitalWrite(fan, HIGH);
      }
      //delay(700);  //un-comment for serial debugging

      Serial.print("setpoint = ");
      Serial.println(setpoint);

      //delay(700);  //un-comment for serial debugging
    }

    /*  WIRING DIAGRAMS
     https://66.media.tumblr.com/98426b566744beacdd42bc0221092b76/tumblr_pvr0u8kvZy1yrmjh9o1_1280.png
     */

body:
You have installed the Adafruit DHT library via the Arduino library manager

[![Adafruit library][1]][1]

The source code does not work with that library. It is written to use the DHT library written by Rob Tillaart, named [DHTLib](https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib). That library is not included in the Library Manager of the Arduino IDE. Instead, you have to download [the library as a ZIP file](https://lastminuteengineers.com/libraries/DHTlib.zip) and install it via Sketch / Include Library / Add .ZIP library.

[![How to install][2]][2]

I don't know why you have changed the source code in the meanwhile. Using DHTLib with the source code of [revision 1](https://arduino.stackexchange.com/revisions/72003/1) of your question works fine. In the meanwhile you have tried to adapt the code to match the Adafruit library, which eventually might be ok as well after some hard work. I suggest rolling back to the code of revision 1 and installing the correct library.

  [1]: https://i.stack.imgur.com/QCuJx.png
  [2]: https://i.stack.imgur.com/AnEM4.png


message:
Arduino MKR 10100 control DC Motor

Thank you for reading my post. I have been stuck on this for several weeks now! I am trying to turn ON/OFF a DC motor from Arduino IOT Cloud. I have set up the cloud and added the switch. Everything works well with an LED: it lights on and off as needed, but the motor does not turn on or off. Below is the circuit I have set up.

[![Circuit Design][1]][1]

My circuit specs are as follows:

 1. I'm not using a UNO as the image illustrates, rather I'm using an [Arduino MKR WiFi 1010][2], but the connections of the pins are exactly the same: LED at PIN 3 and Motor at 7.
 2. The diode I am using is [1N4001][3].
 3. The transistor I'm using is [TIP120][4].
 4. The motor I'm using is [5V DC Motor][5].
 5. 270 Ohm resistor on the transistor circuit and 220 Ohm on the LED circuit.

The Arduino code I made is as follows:

```
#include "thingProperties.h"

#define LED_PIN 3
#define MOTOR_PIN 7

void setup() {
  pinMode(LED_PIN, OUTPUT);
  pinMode(MOTOR_PIN, OUTPUT);

  setDebugMessageLevel(2); // For debugging of cloud integration
  Serial.begin(9600);
  delay(1500);

  initProperties(); // initialize cloud properties
  ArduinoCloud.begin(ArduinoIoTPreferredConnection); // Connect to cloud
}

void loop() {
  ArduinoCloud.update(); // Update cloud background services
}

void onMotorChange() {
  if (motor) {
    // Motor & LED ON
    digitalWrite(LED_PIN, HIGH);
    digitalWrite(MOTOR_PIN, HIGH);
  } else {
    // Motor & LED OFF
    digitalWrite(LED_PIN, LOW);
    digitalWrite(MOTOR_PIN, LOW);
  }
}
```

All my setup seems to be be correct, but it just is not working. I have researched a lot but to no avail. I have tested with a different motor just to be sure, but it also does not work. I'm not sure where I have made a mistake.

Please help me. Thank you very much.

  [1]: https://i.stack.imgur.com/4jDRa.png
  [2]: https://www.seeedstudio.com/ARDUINO-MKR-WiFi-1010-p-46.html
  [3]: https://www.amazon.com/Switching-Rectifier-14-Electronic-Assortment/dp/B07BTY8FD2/ref=sr_1_5?keywords=1N4001 DIODE&qid=1576622652&sr=8-5
  [4]: https://www.amazon.com/Bridgold-TIP120-Darlington-Bipolar-Transistor/dp/B07LG2C3MY/ref=sr_1_1?keywords=TIP120 60V 5A NPN Darlington Bipolar Power Transistor TO&qid=1576622562&sr=8-1
  [5]: https://www.amazon.com/gp/product/B07P18SQSR/ref=ppx_yo_dt_b_asin_title_o00_s02?ie=UTF8&psc=1

body:
The TIP120 is a poor choice because of the approximate 10% - 14% voltage drop across it. Try the circuit with a logic level, low Rds MOSFET.

For a more in-depth answer, please see this answer: https://electronics.stackexchange.com/a/388468/165322


body:
Okay i managed to solve it, the issue was actually my circuit wiring. Below is an image with the correct setup for the transistor or MOSFET.

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

I have changed the TIP120 to RFP30N06LE as [VE7JRO][2] suggested:

> The TIP120 is a poor choice because of the approximate 10% - 14% voltage drop across it. Try the circuit with a logic level, low Rds MOSFET.

but that with the circuit in question does not work. I have not tested the circuit attached with this answer using a TIP120 but i suspect it would work as well.
Finally i added a 9V battery as [jsotola][3] suggested:

> never use an arduino as a power supply ... there is a good chance that the arduino will become an expensive fuse

but i have not tested using the 5V Arduino pin again i suspect it would work as well.

## Bonus: ##
If anyone was wondering how i made these images i used [TinkerCAD][4]

Thank you all

Hope this Helps!

  [1]: https://i.stack.imgur.com/JOEGk.png
  [2]: https://arduino.stackexchange.com/users/37523/ve7jro
  [3]: https://arduino.stackexchange.com/users/40318/jsotola
  [4]: https://www.tinkercad.com


message:
Set the wall clock time or change GMT offset without ntp server?

I have been able to get the current time from an NTP server and set what appears to be an internal clock using the `configTime()` function from the ESP32 core.  I can then get the current time with the function `getLocalTime()`.

I would like to be able to set the time returned by `getLocalTime()` from user input rather than from an NTP server.  I would also like to be able to update the GMT Offset without needing to reconnect to the server.

How do I interact with the clock value used by `getLocalTime()`? Is there documentation for this clock somewhere?

-----

per request the `SimpleTime` example from the ESP32 [install][1]:

    #include <WiFi.h>
    #include "time.h"

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

    const char* ntpServer = "pool.ntp.org";
    const long  gmtOffset_sec = 3600;
    const int   daylightOffset_sec = 3600;

    void printLocalTime()
    {
      struct tm timeinfo;
      if(!getLocalTime(&timeinfo)){
        Serial.println("Failed to obtain time");
        return;
      }
      Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
    }

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

      //connect to WiFi
      Serial.printf("Connecting to %s ", ssid);
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
          delay(500);
          Serial.print(".");
      }
      Serial.println(" CONNECTED");

      //init and get the time
      configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
      printLocalTime();

      //disconnect WiFi as it's no longer needed
      WiFi.disconnect(true);
      WiFi.mode(WIFI_OFF);
    }

    void loop()
    {
      delay(1000);
      printLocalTime();
    }

  [1]: https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/

body:
The functions configTime and getLocalTime are from ESP32 core file [esp32-hal-time.c][1]. This wraps the ESP32 SDK functions. You can use the SDK functions to set the time and zone. They work with the RTC peripheral of the ESP32.

You can use setTimeZone to set the time zone.

The time.h is standard C time library. The ESP32 SDK makes it to work with the built in RTC ([reference][2]). To set the time it gets complicated. You would have to use undocumented SDK [time functions][3].

  [1]: https://github.com/espressif/arduino-esp32/blob/f41beb92bf4434f52209bd15655c1b2f2447447f/cores/esp32/esp32-hal-time.c
  [2]: https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/system_time.html#get-current-time
  [3]: https://github.com/espressif/esp-idf/blob/master/components/newlib/time.c


message:
Why are the PWM variables in this RC code snippet handled this way? What are the magic numbers?

tcommand=(pwm_value-480.0)/8.22;
    flapmag=(pwm_value-880)/41.0+10;
In this piece of code used in arduino radio control aircraft, I don't understand why PWM value is subtracted and divided like this. This is not my code, it came from [here][1]. Any explanation would be of great help. I have read about PWM but all have different explanations.

    //Arduino servo flap system
    //copyright Steve Morris 10-25-16
    #include <Servo.h>
    volatile int pwm_value = 0;
    volatile int prev_time = 0;
    static int servo_comm1 = 0;
    static int servo_comm2 = 0;
    volatile int flapangle1 = 0;
    volatile int flapangle2 = 0;
    volatile int millisold = 0;
    int millinow = 0;
    float dt = 0;
    float flapmag = 0;
    static float flapdeg = 0;
    float tcommand = 0;
    float floattime = 0;
    float temp = 0;
    float glide_deg = -10.0;
    static int pwm_value_temp = 0;
    float omegadot = 0.0;
    float thetadot = 0.0;
    static float omega = 0.0;
    static float theta = 0.0;
    static float k0 = 1.0;
    static float k2 = 10.0;
    static float servo_zero1 = -4;
    static float servo_zero2 = 0;

    Servo myservo1, myservo2; // create servo object to control a servo

    void setup() {
      //Serial.begin(115200);
      // when pin D2 goes high, call the rising function
      attachInterrupt(0, rising, RISING);
      myservo1.attach(5); // attaches the servo on pin 5 to the servo object
      myservo2.attach(6); // attaches the servo on pin 6 to the servo object
    }
    void loop() {

      millinow = millis();
      floattime = millinow / 1000.0;
      dt = (millinow - millisold) / 1000.0;
      millisold = millinow;

      tcommand = (pwm_value - 480.0) / 8.22;
      omegadot = k0 * tcommand - k2 * omega;
      thetadot = omega;
      flapdeg = sin(theta);
      theta = theta + omega * dt;
      omega = omega + omegadot * dt;

      flapmag = (pwm_value - 880) / 41.0 + 10;
      flapdeg = flapmag * sin(theta); //variable amplitude+freq

      flapangle1 = (int)((30.0 - flapdeg + servo_zero1) * 2.0 + 25.0);
      flapangle2 = (int)((30.0 + flapdeg + servo_zero2) * 2.0 + 25 .0);

      if (pwm_value > 930) {
        servo_comm1 = flapangle1;
        servo_comm2 = flapangle2;
      }

      //Glide Lock
      if (pwm_value < 910) {

        servo_comm1 = (int)((30.0 - glide_deg + servo_zero1) * 2.0 + 25.0);
        servo_comm2 = (int)((30.0 + glide_deg + servo_zero2) * 2.0 + 25.0);

      }

      myservo1.write(servo_comm1); // tell servo to go to position in variable 'pos'
      myservo2.write(servo_comm2); // tell servo to go to position in variable 'pos'

      //Serial.println(servo_comm1);
      //Serial.println(floattime);
      //Serial.println(dt);
      //Serial.println(flapangle);
      //Serial.println(flapdeg);
      //Serial.println(temp);
      //Serial.println(tcommand);
      //Serial.println(pwm_value);

    }

    void rising() {
      attachInterrupt(0, falling, FALLING);
      prev_time = micros();
    }

    void falling() {
      attachInterrupt(0, rising, RISING);
      pwm_value = micros() - prev_time;
    }

  [1]: https://www.rcgroups.com/forums/showthread.php?2765781-Arduino-Servo-Flap-System/page6

body:
There is not enough context to be certain, but given the variable names I can assume that this is code from a sketch that receives information from an RC controller and is intended to control parts of some form of flying craft.

So with that in mind, let's take this line:

    flapmag=(pwm_value-880)/41.0+10;

I assume that this is to calculate the amount the flaps should be extended or retracted.

RC controllers, or rather the receivers that pick up the signals, usually output a PWM signal (square wave with a variable duty cycle) where the duty cycle is directly related to the position of the joystick.

A joystick is usually zero in the center and goes plus or minus for up and down (or right and left). But you can't have a negative PWM value, since that makes no sense (how can you have a signal that is off for *less* that 0% of the time?!).  So the output is "offset" by a certain amount (that's not quite true - actually the joystick is 0 for fully down, and 100% for fully up, with "0" being somewhere in the middle, so the offset is applied by the joystick, not the receiver, but that really doesn't matter for us right now).

So we have a signal that is at any time somewhere between 0% and 100%, with "zero" being somewhere in the middle.  What actual value the "100%" is, or exactly where "zero" is, can vary depending on many many factors, so we'll just use "100" for the maximum, and "50" for the middle "zero" offset.

The first thing you want to do, then, is remove that "zero" offset. And that is as simple as subtracting it.  With our example numbers above, if you subtract the "zero" offset of "50" from the incoming signal it now goes between -50 and +50 instead of 0 and 100. That now relates much better to how a joystick appears - 0-50 in an upwards direction (+) and 0-50 in a downwards direction (-).

And that is exactly what is happening with `pwm_value-880` in your code.  The middle "zero" value of 880 is being subtracted from the incoming joystick position to give you an "up" or "down" value that is positive or negative respectively.

Next comes the division.  This scales the incoming value to the right size for the device you are driving. In our example we have a ±50 signal. But what if our flaps require a ±10 signal to give the correct movement range. So simply dividing the value by 5 will change ±50 into ±10. That's exactly what the `/41.0` is doing - scaling the result to fit the range of the target device.

Then there's one final `+10` in there. This simply adds a small offset to the result. You can think of this as a "trim" value. It sets the actual "zero" point of the target device - in this case when the joystick is centered it means the flaps are set to a +10 position.

As to how the `pwm_value` itself is created, that is usually done through capturing the rising and falling edges of the incoming waveform from the receiver and timing how long the signal is in the HIGH or LOW state. That may be performed by some unspecified library.


message:
How to create an inverted PWM on the Due via software

Hello I am i need of a piece of code that lets me invert a PWM signal of two PWM pins on the due. Example D1 will be 101010 and D2 will be 010101. Is it possible?

Im pretty limited in my options because, doing it externally is not an option because there will be a time where a change in mode is needed and both pins will be sending signal independently. Manually pulling the pins High and Low is also not an option for me because this will make the code blocking other codes.

body:
Not using the Arduino API, no. But you can by direct manipulation of the SAM3X8E registers.

You should study section 38 of [the datasheet](https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf), where it mentions in the list of facilities:

> * Independent Complementary Outputs with 12-bit Dead-Time Generator (Also Called Dead-Band or Non-Overlapping Time) for Each Channel


message:
Half-duplex for Atmel SAMD21

I'm using an Arduino MKR GSM 1400. I know this board uses the Atmel SAMD21 and the SAMD21 supports half-duplex (USART with full-duplex and single-wire half-duplex configuration). My question is, how can I configure one of the SERCOMs to use it as half-duplex (use one pin for rx and tx)?

body:
> Up to six Serial Communication Interfaces (SERCOM), each configurable
> to operate as either:
>
>  -   USART with full-duplex and single-wire half-duplex configuration
>  -   I2C up to 3.4 MHz
>  -   SPI
>  -   LIN slave

It is an error in the overview of the SAM D21 features in the datasheet. The SERCOM is half-duplex for I2C. USART can't be configured half-duplex.

see [Application Note about SERCOM configuration][1]

> 1 Introduction to Serial Communication Interfaces (USART, I2C, and
> SPI)
>
> ... The exchange of data can be half-duplex or fullduplex depending on
> the serial module specification. ...
>
> 1.1 USART
>
> ... It is full-duplex in operation. ...
>
> 1.2 I2C
>
> ... It is half-duplex in communication. ...

[1]: https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en590861


body:
You can use USART in half duplex mode.

SERCOMx.PAD0 or SERCOMx.PAD2 are available for this. Refer to document "AT03256: SAM D/R/L/C Serial USART (SERCOM USART) Driver" section "10. SERCOM USART MUX Settings".

Below is a piece of code for ATXMEGA32E5, SERCOM0, PAD0. I am tested - it works:

Pull-up will help keep the line at 1 when the device’s transmitter is turned off and there is no other transmitter on the line, or it has not turned on yet. In the GPIO setup procedure:

    // PA08 - SERCOM0/PAD[0]
    PORT->Group[0].PINCFG[8].bit.PULLEN=1;   // Pull Enable
    PORT->Group[0].PINCFG[8].bit.PMUXEN=1;    // Peripheral Multiplexer Enable
    PORT->Group[0].PMUX  [4].bit.PMUXE=0x02;  // PMUX function C - SERCOM0/PAD[0]

In the SERCOM setup procedure, configure TX and RX on one pad:

    while(SERCOM0->USART.SYNCBUSY.reg & 0x07) { ; }
    SERCOM0->USART.CTRLA.bit.TXPO = 0x00; // SERCOM PAD[0] Transmit Data Pinout
    while(SERCOM0->USART.SYNCBUSY.reg & 0x07) { ; }
    SERCOM0->USART.CTRLA.bit.RXPO = 0x00; // SERCOM PAD[0] is used for data reception

If at the time of your transmission both the receiver and the transmitter are turned on at the same time, you will hear your echo.

When you get up for reception, do not forget to turn off your transmitter so that it does not interfere with reception:

    SERCOM0->USART.CTRLB.bit.TXEN=0x00; while(SERCOM0->USART.SYNCBUSY.bit.CTRLB ) { ; }
    SERCOM0->USART.CTRLB.bit.RXEN=0x01; while(SERCOM0->USART.SYNCBUSY.bit.CTRLB ) { ; }

Before transmitting, do not forget to turn on the transmitter:

    SERCOM0->USART.CTRLB.bit.TXEN=0x01; while(SERCOM0->USART.SYNCBUSY.bit.CTRLB ) { ; }
    SERCOM0->USART.CTRLB.bit.RXEN=0x00; while(SERCOM0->USART.SYNCBUSY.bit.CTRLB ) { ; } // If you don't want to receive your own transmission

Hope it helps.


message:
Level shifting 5V <-> 3.3V

My main goal is to use connect the **HC-SR04** ultrasonic sensor with **ESP8266**.

Problem is, HC-SR04 works with **5V** while the ESP8266 works with **3.3V**
In order to solve this, idea would be to use a logical level converter.

I bought some of this [3.3V 5V TTL Bi-directional Logic Level Converter(s)][1] a good while ago, and thought they would fit best for this project.

**Here's my setup**

- 5V from arduino
- 3.3V from digital power supply
- GND connected together
- **Nothing** connected to TX0 (HV side)
- Voltmeter connected to TX1 (LV side), **still getting a 3.3V**

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

**Here's a closer look at the breadboard connections**
[![enter image description here][3]][3]

Am I doing something wrong ? Any suggestions would be appreciated !

  [1]: https://www.banggood.com/3_3V-5V-TTL-Bi-directional-Logic-Level-Converter-p-949438.html?cur_warehouse=CN
  [2]: https://i.stack.imgur.com/ktAWZ.jpg
  [3]: https://i.stack.imgur.com/8tdB4.jpg

body:
No, you're not doing anything wrong.  Those simple MOSFET level shifters work by having both sides pulled up by resistors to their respective power supplies. When one side gets pulled low by a digital signal that LOW is mirrored to the other side of the MOSFET.

If you connect your TX0 pin to GND you will see the TX1 pin go to 0V.


body:
Edit: Forget the post above if you just want to know how your board is working. Your board is a retired Spurkfun product - clone.

Here you can see the schematics and all info about your board:

https://learn.sparkfun.com/tutorials/retired---using-the-logic-level-converter

<b>Original post</b>:

The module you got, use the BSS138 MOSFET.
The circuit is easy, and how @Majenko said, it has just 2 pullups:
See https://electronics.stackexchange.com/questions/367052/replace-bss138-with-ao3400a-in-level-shifter-circuit

[![level shifter][1]][1]

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

But this board is really strange: what means TX0, TX1, RX0, RX1 on the same MOSFET? It is better if you can measure it to be sure how to connect the sensor to the TX.

But there is a better way to solve it: Since you just have 1 input to your ESP, why not use 2 resistors?
5V--- 1k --- 2k --- GND
And connect the ESP input between the 2 resistors? It is even faster, because the MOSFET need up to 20ns to change state.


body:
Check this out:
https://learn.sparkfun.com/tutorials/bi-directional-logic-level-converter-hookup-guide/all
This article gives a comprehensive explanation about the bi-directional logic level converter and it's connection in a circuit.


message:
Can't get actual output when, both input logic is high

I want
When,

 - light=0, ir=0 then output will pin 8 high & pin 12 low.

 - light=0, ir=1 then output will pin 8 high & pin 12 high.

 - light=1, ir=0 then output will pin 8 low & pin 12 low.

 - light=1, ir=1 then output will pin 8 low & pin 12 low (This statement
   does not work).

Please find the code & suggest me, if any modification is needed.

    void setup() {

        pinMode(8,OUTPUT); //logic output.
        pinMode(12,OUTPUT); //logic output.
        pinMode(2, INPUT); //value input.
        pinMode(4, INPUT); //value input.

        Serial.begin(9600);
    }

    void loop() {

        int light = digitalRead(2); //value input.
        int ir = digitalRead(4); //value input.

        if (light == LOW && ir == LOW)
        {

          digitalWrite(8, HIGH);
          digitalWrite(12, LOW);
          delay(2000);

        }

        if (light == LOW && ir == HIGH)
        {

          digitalWrite(8, HIGH);
          digitalWrite(12, HIGH);
          delay(2000);

        }

        if (light == HIGH && ir == LOW)
        {

          digitalWrite(8, LOW);
          digitalWrite(12, LOW);
          delay(2000);

        }

        if (light == HIGH && ir == HIGH) //This condition does not work.
        {

          digitalWrite(8, LOW);
          digitalWrite(12, LOW);
          delay(2000);

        }

        digitalWrite(8, LOW);
        digitalWrite(12, LOW);
        delay(2000);

    }

body:
You can simplify your requirements somewhat by splitting your inputs up.

> light=0, ir=0 then output will pin 8 high & pin 12 low.
>
> light=0, ir=1 then output will pin 8 high & pin 12 high.

If `light` is 0 then pin 8 is high. AND `ir` is echoed to pin 12.

> light=1, ir=0 then output will pin 8 low & pin 12 low.
>
> light=1, ir=1 then output will pin 8 low & pin 12 low

If `light` is 1 then both pins 8 and 12 are low, and you don't care what `ir` does, since it doesn't have any effect on the outputs.

So your structure could look more like:

    if (light == 0) {
        digitalWrite(8, HIGH); // 8 will always be high with light == 0
        digitalWrite(12, ir); // echo the ir value to pin 12
    } else {
        digitalWrite(8, LOW); // if light is 1 then everything
        digitalWrite(12, LOW);// is low regardless of ir.
    }


body:
Note this is not an answer to the question (I don't see any problem initially), but to clean the code it might help to debug it (using print statements as Sim Son suggests).

Instead of all the `if` statements, check when pin 8 and pin 12 needs to be HIGH:

     pin 8:  (light == LOW && ir == LOW)
     pin 12: (light == LOW && ir == LOW)  or (light == LOW && ir == HIGH)

For pin 12, the condition can be rewritten as

     pin 12: (light == LOW) || (ir == LOW or ir == HIGH)

which is equal to

     pin 12: light == LOW

So now you can change the code from the `loop` function to:

    void loop()
    {
       digitalWrite(8 , (light == LOW && ir == LOW) ? HIGH : LOW);
       digitalWrite(12, (light == LOW             ) ? HIGH : LOW);
       delay(2000);

       digitalWrite(8, LOW);
       digitalWrite(12, LOW);
       delay(2000);
   }

the x ? : z statements means: if x is true, do y, else z.

The last three statements are fixed (copied from your code).

Now we can even further reduce it, by removing the duplicated code

    void loop()
    {
       processLeds((light == LOW && ir == LOW), (light == LOW));
       processLeds(False                      , False         );
    }

    void processLeds(int conditionLed8, int conditionLed12)
    {
        digitalWrite( 8, conditionLed8  ? HIGH : LOW);
        digitalWrite(12, conditionLed12 ? HIGH : LOW);
        delay(2000);
    }

You pass the condition when led 8 and 12 have to be high or log to a function, which sets the LEDs.

Now you can also use much less print statements for finding your problem.


message:
qsort is not really sorting

I'm working with Arduino and getting some strange errors. qsorting is not sorting correctly.

    //using this libraries
    #include <ESP8266WiFi.h>
    #include <inttypes.h>

    //the red struct is

    typedef struct {
        int32_t rssi;
        int id;
    } red;

    //Here is my compare function
    int compare (const void * a, const void * b)
    {
      yield();
      red *redA = (red *)a;
      red *redB = (red *)b;
      //Serial.printf("redA->rssi: %d, redB->rssi: %d\n",redA->rssi,redB->rssi);
      //Serial.flush();

      return redA->rssi > redB->rssi ? 1 : (redB->rssi < redA->rssi ? -1 : 0);
      //return ( redB->rssi - redA->rssi );
    }

    void showNetworks(){
      int n = WiFi.scanNetworks(false,false);
      red listOfRedes[n];

      for (int i = 0; i < n; i++) // ...initialize it
      {
        yield();
        listOfRedes[i].rssi = WiFi.RSSI(i);
        listOfRedes[i].id = i;
        Serial.printf("%d: RSSI%d\n", i, listOfRedes[i].rssi);
        Serial.flush();
      }
      Serial.printf("salio\n");
      Serial.flush();
      qsort (listOfRedes, n, sizeof(red), compare);
      Serial.printf("ordeno\n");
      for (int i = 0; i < n; i++) // ...initialize it
      {
        yield();
        Serial.printf("%d: RSSI:%" PRId32 "\n", listOfRedes[i].id, listOfRedes[i].rssi);
      }
    }

and this is the output i get

    0: RSSI-69
    1: RSSI-65
    2: RSSI-72
    3: RSSI-50
    4: RSSI-60
    5: RSSI-87
    6: RSSI-87
    7: RSSI-79
    8: RSSI-80
    9: RSSI-88
    10: RSSI-74
    11: RSSI-77
    12: RSSI-78
    13: RSSI-83
    14: RSSI-79
    15: RSSI-60
    16: RSSI-85
    17: RSSI-86
    18: RSSI-66
    19: RSSI-88
    20: RSSI-80
    21: RSSI-74
    22: RSSI-81
    23: RSSI-87
    salio
    ordeno
    4: RSSI:-60
    1: RSSI:-65
    0: RSSI:-69
    3: RSSI:-50
    18: RSSI:-66
    15: RSSI:-60
    2: RSSI:-72
    10: RSSI:-74
    11: RSSI:-77
    21: RSSI:-74
    19: RSSI:-88
    20: RSSI:-80
    22: RSSI:-81
    23: RSSI:-87
    12: RSSI:-78
    5: RSSI:-87
    6: RSSI:-87
    7: RSSI:-79
    8: RSSI:-80
    9: RSSI:-88
    13: RSSI:-83
    14: RSSI:-79
    16: RSSI:-85
    17: RSSI:-86

As you can see the sorting is not OK and I don't get why.
Thank you in advance and sorry for my poor English.

body:
In your program there is this line of code:

      return redA->rssi > redB->rssi ? 1 : (redB->rssi < redA->rssi ? -1 : 0);

Which appears to return a 1 if A is greater then B other wise it will return a 0.  This code can not tell the difference between A < B and A == B.  Consider altering this line of code to allow returning 1 for A > B, 0 for A == B and -1 for A < B:

      return redA->rssi > redB->rssi ? 1 : (redA->rssi < redB->rssi ? -1 : 0);


message:
Declaring and using array of structures in Arduino

Printing structure variables, I get default values. What is wrong with my code?

```
struct SCENARIO
{
  int Lamp_Pin = -1;
  int PB_Pin = -1;
} ;

SCENARIO  _red;
SCENARIO  _yellow;
SCENARIO  _white;
SCENARIO  _stop;
SCENARIO btns[4] = { _red,  _yellow, _white, _stop};

void setup()
{
  _stop.Lamp_Pin = 8;
  _stop.PB_Pin = 4;

 ///// initializing other 3 objects i.e. red & white & yellow
 ////
for (int i = 0; i < 4; i++)
  {
    Serial.print(i);Serial.print(":");
    Serial.print(btns[i].Lamp_Pin);Serial.print(":");
    Serial.println( btns[i].PB_Pin );
    //pinMode(  btns[i].Lamp_Pin, OUTPUT);
    //pinMode(  btns[i].PB_Pin, INPUT);
  }
}
```
The image below shows what I get. It seems I have not initialized the variables!

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

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

body:
The problem is that a struct is handled as a value type, not as a reference type.

This means that a copy of `_stop` is made and put in `btns` (`btns[3]` actually).

So what you need to do is putting pointers into the `btns` array:

    SCENARIO* btns[4] = { &_red, &_yellow, &_white, &_stop};

The symbol * denotes a pointer, and & means the address of a variable (so it points to the variable and is not a copy).

Now when you change `_stop`, also `btns[3]` which points to `_stop` will show the correct initialized value.

For printing you should use:

    Serial.println( (*btns[i]).LampPin);Serial.print(":");
    Serial.println( (*btns[i]).PB_Pin );

Because *btns[i] is a pointer, but because this is a very often used feature, a special notation can be used:

    Serial.print(btns[i]->Lamp_Pin);Serial.print(":");
    Serial.println( btns[i]->PB_Pin);


body:
In this line:

    SCENARIO btns[4] = { _red,  _yellow, _white, _stop};

you are making 4 copies of the structures and placing them in an array.

Instead you should either create the array directly with the values:

    SCENARIO btns[4] = {
        {-1, -1},
        {-1, -1},
        {-1, -1},
        {8, 4}
    };

And only use the array, or use pointers in the array:

    SCENARIO *btns[4] = { &_red,  &_yellow, &_white, &_stop };

and then access the entries as pointers:

    Serial.print(btns[i]->Lamp_Pin);
    Serial.print(":");
    Serial.println( btns[i]->PB_Pin );


message:
Behaviour of tone() not as expected within while loop

I have a smoke detector with a piezo buzzer. I want to operate the arduino in low power mode so that it will last on a 9V battery. I've attached an interrupt, and when the digital output of the MQ-2 sensor goes high, it switches to a monitor function.

In the while loop, I check to see if the analog sensor has reached the threshold value, and I output to serial to see if I am in the conditional. If I use:

    digitalWrite(buzzer, HIGH);
then the piezo sounds, however if I use

    tone(buzzer, 1000,200);
    delay(200);
it does not. I'm confused as to why this would be the case.

Full code as follows:

    #include "LowPower.h"

    int redLed = 12;
    int greenLed = 11;
    int buzzer = 10;
    int smokeA0 = A5;
    // Your threshold value
    int sensorThres = 50;
    int smokeD0 = 2;

    void setup() {
      pinMode(redLed, OUTPUT);
      digitalWrite(redLed, LOW);
      pinMode(greenLed, OUTPUT);
      digitalWrite(greenLed, HIGH);
      pinMode(buzzer, OUTPUT);
      pinMode(smokeA0, INPUT);
      pinMode(smokeD0, INPUT);

    }
    void switchToMonitor() {
      Serial.begin(9600);
      int digitalSensor = digitalRead(smokeD0);
      if (digitalRead(smokeD0) == HIGH)
      {
        digitalWrite(redLed, HIGH);
        digitalWrite(greenLed, LOW);
      }
      else {
        digitalWrite(redLed, LOW);
        digitalWrite(greenLed, HIGH);
      }
      //This will be updated later to use the analog input
      //Using digital to make debugging easier
      while (digitalSensor == HIGH) {
        int analogSensor = analogRead(smokeA0);
        Serial.print("Pin A0: ");
        Serial.println(analogSensor);
        Serial.print("Pin D0: ");
        Serial.println(digitalSensor);
        // Checks if it has reached the threshold value
        if (analogSensor > sensorThres) {
          digitalWrite(buzzer, HIGH);
          //tone(buzzer, 1000,200);
          Serial.println("here");
          delay(1000);
        }
        else {
    //      digitalWrite(redLed, LOW);
    //      digitalWrite(greenLed, HIGH);
          noTone(buzzer);
          Serial.println("also here?");
        }
        //delay(100);
        digitalSensor = digitalRead(smokeD0);
      }
      noTone(buzzer);
    }

    void loop() {
      //delay(100);
      //LowPower.standby();
      attachInterrupt(0, switchToMonitor, CHANGE);
      LowPower.powerDown(SLEEP_FOREVER, ADC_ON, BOD_ON);
      detachInterrupt(0);
    }

body: You can't use delay() or timer based tone() function in interrupt handler. Set a flag in interrupt and run the code  in loop() conditionally based on the flag state. Do not forget to have the flag variable volatile.


message:
TX pin sends wrong data in Arduino Uno

I want to send some data to an IP Modem from Arduino Uno. That IP Modem has TTL levels TX and RX inputs.

I used this connection between Arduino to the IP Modem:

[![Schematics of connections][1]][1]

I am powering Arduino with 12 V plugged in the barrel.

This is the photo of the connections:

[![Actual photo][2]][2]

I connected the PC to the USB connector of Arduino and I uploaded the following sketch to send "AABB" to the Modem:

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

    void loop(void) {
     Serial.print("AABB");

     delay(5000); // Envía la temperatura cada 5 segundos
    }

When monitoring what is received by the modem, it is

0x5F 0x5F 0xAF 0x2F

If I send just "A", the character received each 5 seconds is 0x5F.

Of course, both ends are configured as 115,200bps, 8N1.

In order to discard Modem problem, I connected RX, TX and GND in Arduino to a DB9 female connector and then to a RS232 - USB converter and started monitoring with my PC.

My surprise was that the data received is exactly the same as the received by the modem when it was connected. As seen in the following picture:

[![Serial monitoring from PC][3]][3]

As you see in the picture, "_" twice was shown (ASCII 0x5F), {\xaf} and finally "/" (ASCII 0x2F).

Above test confirms Arduino is sending wrong data.

Something to note. When I monitor using USB cable connected to Arduino and using Monitor Serie in the Arduino IDE, I  see correctly "AABB". The problem is when using TX and RX pins (the same happened if I used other pin along with SoftwareSerial library)

What may be going on?

  [1]: https://i.stack.imgur.com/6XmzZ.png
  [2]: https://i.stack.imgur.com/WzvK8.jpg
  [3]: https://i.stack.imgur.com/HApKw.png

body:
Since you have already tried SoftwareSerial, also try inverting the serial protocol via SoftwareSerial.  Sometimes a device uses inverted serial protocol and you don't know it.

So initialize inverted add 1 to the end of the contructor like so :
```
SoftwareSerial mySerial(RXPIN, TXPIN,1); // RX, TX, inverted
```


message:
Addressable LEDs vs Multiplexing for a Matrix

I would like to building a 8x64 RGB Matrix and connect it to my Arduino.
As this form factor does not really exist I would need to build one myself but now I am wondering if I should use addressable LEDs like WS2813 or APA107 and use FastLED or rather use 'dumb' LEDs and just multi-/charlieplex them using a MAX7221 or comparable chip.

What are some pros and cons I should consider with each one? I read that to many WS2813 can make problems but APA107 seem to fix that. But on the other hand most bigger matrices just use multiplexing........

body:
The smart RGB LEDs will be brighter. Each device has its own control chip that controls the 256 PWM level for each of the 3 LEDs. So for an 8x64 array, you send in 3 bytes/device, 8x64x3 = 1535 btyes, pause a few microseconds, and the array updates itself.

Going the multiplexing route, you would do something like have 64x3 = 192 anode drivers (or up to 192, if not all are LEDs are lit up) to enable the LEDs across the display, and then 8 common cathode drivers to turn on each row one at a time for 1/30 to 1/24 of a second for minimal flicker. So 192 LEDs, 20mA each, the common cathode needs to be able to sink 3.84A

On the otherhand, 8x64 LEDs, each needing up to 60mA at full on, = 30.72A.


message:
How to calibrate MPU 6050 thermometer?

I'm using MPU 6050 and there's a thermometer onboard. However, I looked through [the chip set data sheets][1] but could not find the instruction for temperature sensing.

Could you tell me how to calibrate the data string from the two address started from 0x41?

  [1]: https://www.invensense.com/products/motion-tracking/6-axis/mpu-6050/

body:
The temperature sensor is likely included to keep the gyroscope and accelerometer better calibrated over the specified temperature range.  The temperature may not be the ambient temperature should the chip warm up.

The temperature sensor specifications are in section 6.3 on page 14 of the [specification sheet][1] indirectly pointed to in the question.

    TEMPERATURE SENSOR
    Range -40 to +85°C
    Sensitivity Untrimmed 340 LSB/ºC
    Temperature Offset 35ºC -521 LSB
    Linearity Best fit straight line (-40°C to +85°C) ±1°C

So, when the chip is at 35C the chip temperature register is supposed to read about -521.  To convert that into C you need to make a calculation:

> chip_temperature = ((value_read + 521) + (35 * 340)) / 340

Simplified:

> chip_temperature = (value_read + 12421) / 340

  [1]: https://43zrtwysvxb2gf29r5o0athu-wpengine.netdna-ssl.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf


message:
How to determine minimum and maximum angle for cheap servos?

I have some cheap KY66 (seems to be SG90 clone) servos.

When I turn them to 0°, the servo tries moving and moving, without actually getting to 0°. I read that they are reaching the endpoint but the built-in potentiometer does give a reading of 0.

By changing the code and fiddling with the angle, I find that the minimum for one particular servo is 25°.

I'm now trying to figure out how the Arduino could determine this value automatically. I have tried

    servo.write(0);
    delay(3000);
    int direction = servo.read();

and expected to get back a value near 25, but it was 0 instead. So the result of `read()` does not seem to be an actual reading, but more the "last known" setpoint.

I've also tried to relax the servo before reading:

    servo.write(0);
    delay(3000);
    int direction = servo.read();

with no better result.

I like to figure out the minimum and maximum angle of the servo

* because I don't like the servo to make much noise (it really doesn't sound healthy)
* without having the user to figure out by himself and the need of re-programming the Arduino.

I know that these cheap servos only have 3 pins. 2 pins are for power supply only, so there's only 1 pin left.

My questions:

* Is the data pin uni-directional (PWM output from Arduino to servo)?
* Will it ever be possible to implement what I want without additional hardware?
* How do people solve this issue? Do more expensive servos either have better calibration to actually go from 0° to 180° or do they provide a way to read the potentiometer with another pin?

body:
I think you have 2 choices: either measure and store for each one individually, or find the worst case for all of them and code around that.

Do you really need the full travel? If you're using the servo to push/pull, the servo-travel endpoints are pretty weak anyway.

> I wanted a robot look left and look right, which is 0° or 180°.

Maybe you can make up the limited angular travel of the servo in the linkage between the it and the camera platform.


body:
> Is the data pin uni-directional (PWM output from Arduino to servo)?

As you found out, standard servos have only three pins. And yes, two of them provide ground and power, and the third is a unidirectional signal.

This signal is commonly a pulse of 1 ms to 2 ms, repeated every 20 ms.

`servo.read()` can therefore only return the last value set by `servo.write()`.

> Will it ever be possible to implement what I want without additional hardware?

I don't think so.

You could insert a shunt into the power line and measure the current. If it stays high for extended periods, it means that the servo is still powering its motor. But this could be true also for other reasons than being at its own mechanical limit.

> How do people solve this issue? Do more expensive servos either have better calibration to actually go from 0° to 180° or do they provide a way to read the potentiometer with another pin?

Since servos are used as a closed (sub-)system, I don't think that they are opened to read their potentiometer. And even if you do this, you might affect the internal working of the servo.

Eventhough I built several model aircrafts since the late 70s and used different servos, I have no feeling about the calibration of cheap or expensive servos. IIRC some data sheet documented ranges of only +/- 45°.

So the values `0` to `180` for `servo.write()` is just a mapping for 1 ms to 2 ms.

To make a long story short, I have no idea how people solve this.

You might like to limit your range to some "healthy" values, or ask the user to help in calibration. The calibration results can be stored in EEPROM, there is no need to reprogram the Arduino.

If you need the robot's head to turn from 0° to 180°, consider using some gear so that the servo just needs to move between, let's say, 30° to 150°. This is the way modellers go.


message:
Is the shiftOut code depending on the (low) speed of an Arduino?

In the (official) file `wiring_shift.c` I found the following code for shiftOut:

    void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
    {
     uint8_t i;

     for (i = 0; i < 8; i++)  {
      if (bitOrder == LSBFIRST)
       digitalWrite(dataPin, !!(val & (1 << i)));
      else
       digitalWrite(dataPin, !!(val & (1 << (7 - i))));

      digitalWrite(clockPin, HIGH);
      digitalWrite(clockPin, LOW);
     }
    }

However, the last two `digitalWrite` commands occur directly after each other. I wouldn't hope that `digitalWrite` depends on some time or delay, so how can it be assumed that the slave device sees the clockPin is HIGH if the Arduino immediately sets the clockPin to LOW again?

(My plan is to convert the shiftIn/shiftOut code to STM32 using HAL/CubeIDE).

body:
Some time ago, I timed digitalWrite() and direct port write commands by looping over 10,000 executions of each and timing them with millis(). I made both tests on a 16MHz Atmega 328p at 16MHz.

For `digitalWrite(13, LOW)`, I got 2.7usec / call.

For `PORTB &= 0x20;`, I got 0.15usec / statement. (The direct port access was executed 10 times within the loop to further pad it out for the `millis()` result to have any significance.)

[In my notes I wrote that I timed `PORTB &= 0x20;`, but the correct equivalent to the `digitalWrite()` version is `PORTB &= ~0x20;`. That is probably what I actually did, but note that the bit-mask would be generated at compile time, so either way should have produced the same result.]

> how can it be assumed that the slave device sees the clockPin is HIGH

It would depend on the specifics of the slave, but it is quite likely triggered by a pulse, rather than polling its input until it finds a high-level.

Update:
To confirm my timing data, I redid my 2.5-years-ago experiment. I put 10 statements in each of 2 loops of 10,000 iterations, either:

    digitalWrite(13, LOW);

or

    PORTB &= ~0x20;

And got these total times in msec for the 100,000 executions:

digitalWrite(): 305  // digitalWrite(13, LOW);
PORTB (correct): 15  // PORTB &= ~0x20;

These translate to single execution times in 10s of nanoseconds:

3050 nsec == 3.05 usec for the function call,

150 nsec for direct port I/O, making port I/O about 20x faster.


message:
If-statement matches but doesn't give a result

I just started two weeks ago with Arduino and I'm hooked!

I got off to a good start and went through some online tutorials quite easily. Then came the RGB LED, which I couldn't get to work all of a sudden (it required putting in a color through the serial monitor, which would then be given by the RGB).

And the strange thing is, I can't get anything to work anymore that requires input through the serial monitor, where I used to get it working immediately...

I presume it's something with the if-statement, because if I remove it and just say digitalwrite HIGH to a certain pin, it works fine....

Checks I did:

- Full re-install of Arduino (didn't solve it).
- Check the LEDs by hooking them up to 5V directly (they all work).
- Reconnecting the Arduino (didn't solve it).
- Use a multimeter to measure current (there isn't, although the if-statement matches...

Here's my code. Does anybody see it? Because I don't...

Regards,

nannev (using Mac and Arduino Uno)

```
int yellowPin=8;
int redPin=9;
int greenPin=10;
String myLED;

void setup() {
  Serial.begin(9600);
  pinMode(yellowPin,OUTPUT);
  pinMode(redPin,OUTPUT);
  pinMode(greenPin,OUTPUT);
}

void loop() {
  Serial.println("Your color?");
  while (Serial.available()==0) {
  }

  myLED=Serial.readString();
  Serial.print(myLED); //check if the input came through correctly, which it did
  delay(1000);
  if(myLED == "yellow"){ .    //nothing happens at yellow....
    digitalWrite(yellowPin, HIGH);
    digitalWrite(redPin, LOW);
    digitalWrite(greenPin, LOW);
  }

  if(myLED == "red"){             //nothing happens at red....
    digitalWrite(yellowPin, LOW);
    digitalWrite(redPin, HIGH);
    digitalWrite(greenPin, LOW);
  }

  if(myLED == "green"){       //nothing happens at green....
    digitalWrite(yellowPin, LOW);
    digitalWrite(redPin, LOW);
    digitalWrite(greenPin, HIGH);
  }
}
```

body:
The Arduino IDE uses the C and C++ programming languages.

***Some string comparison basics using C:***

In the C programming language, a string can be thought of as an array of 8 bit values.  One way to compare two strings is to compare each 8 bit value and consider the strings different (not equal) upon finding the first not-matching 8 bit value.  [Here is an example from programmingsimplified.com][1]:

    int compare_strings(char a[], char b[])
    {
       int c = 0;

       while (a[c] == b[c]) {
          if (a[c] == '\0' || b[c] == '\0')
             break;
          c++;
       }

       if (a[c] == '\0' && b[c] == '\0')
          return 0;
       else
          return -1;
    }

There is a common function called strcmp() which can be used instead.  Here is another example from the same web page which uses strcmp():

    #include <stdio.h>
    #include <string.h>

    int main()
    {
       char a[100], b[100];

       printf("Enter a string\n");
       gets(a);

       printf("Enter a string\n");
       gets(b);

       if (strcmp(a,b) == 0)
          printf("The strings are equal.\n");
       else
          printf("The strings are not equal.\n");

       return 0;
    }

Note that in both cases the array of strings is assumed to end with a NULL or zero value byte.  If you do not wish to follow this format you can use an alternate version of the function called [strncmp()][2] where the number of characters to be compared is passed along with pointers to the 2 strings.

***Some string comparison options using C++:***

There are C++ ways to compare 2 strings which make coding Arduino Sketches easier.  But C++ string manipulation usually requires more RAM.  And RAM is usually in short supply on inexpensive embedded processors.

As the code in the question is written using type String we can explore that approach. And, as there is some concern the strings may have unexpected trailing characters, we will continue to check only the necessary number of characters. In this slightly modified [code example from geeksforgeeks.org][3] string s1 is compared with string s2.  But only the first 6 characters are compared:

    void compareOperation(string s1, string s2)
    {
        // Compares 5 characters from index number 3 of s2 with s1
        if((s2.compare(0, 6, s1)) == 0)
            cout << "Here, "<< s1 << " are " << s2;

        else
            cout << "Strings didn't match ";
    }

The number 6 was chosen because "yellow" contains 6 printable characters.  In this way, we can avoid the uncertainty of what character(s) follow the characters that make up "yellow" as received from the serial port.

  [1]: https://www.programmingsimplified.com/c-program-compare-two-strings
  [2]: https://www.tutorialspoint.com/c_standard_library/c_function_strncmp.htm
  [3]: https://www.geeksforgeeks.org/stdstringcompare-in-c/


message:
Cannot call function in call back for onRequest()

I am a NOOB!  Trying to use the ZS-042 RTC module to retrieve the current time and send it back to the RPi over I2C.  I can call the function and spool it to Serial but when I try to call the function to update the global variables from within the call back function for onRequest() the Ardiuno (Micro) crashes.

```ino
#include <Wire.h>

// LED on pin 13
const int TEMP_PIN1 = A0;
const int RELAY_PIN1 = 4;
const int SAMPLE_TIME = 100;
const byte RPI_I2C_ADDRESS = 0x08;
const int DS3231_I2C_ADDRESS = 0x68;

byte number = 0;
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

/*
 * RTC Setup
 */
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return( (val/10*16) + (val) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return( (val/16*10) + (val) );
}
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
      dayOfMonth, byte month, byte year)
{
  // sets time and date data to DS3231
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(second)); // set seconds
  Wire.write(decToBcd(minute)); // set minutes
  Wire.write(decToBcd(hour)); // set hours
  Wire.write(decToBcd(dayOfWeek)); // set day of week (0=Sunday, 6=Saturday)
  Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
  Wire.write(decToBcd(month)); // set month
  Wire.write(decToBcd(year)); // set year (0 to 99)
  Wire.endTransmission();
}

/*
void readDS3231time(byte *second,
    byte *minute,
    byte *hour,
    byte *dayOfWeek,
    byte *dayOfMonth,
    byte *month,
    byte *year)
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}
*/

void readDS3231time()
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  second = bcdToDec(Wire.read() & 0x7f);
  minute = bcdToDec(Wire.read());
  hour = bcdToDec(Wire.read() & 0x3f);
  dayOfWeek = bcdToDec(Wire.read());
  dayOfMonth = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read());
  year = bcdToDec(Wire.read());
}

void displayTime()
{
  //byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  //readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  readDS3231time();
  // send it to the serial monitor
  Serial.print(hour, DEC);
  // convert the byte variable to a decimal number when displayed
  Serial.print(":");
  if (minute<10)
  {
    Serial.print("0");
  }
  Serial.print(minute, DEC);
  Serial.print(":");
  if (second<10)
  {
    Serial.print("0");
  }
  Serial.print(second, DEC);
  Serial.print(" ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print(year, DEC);
  Serial.print(" Day of week: ");
  switch(dayOfWeek){
  case 0:
    Serial.println("Sunday");
    break;
  case 1:
    Serial.println("Monday");
    break;
  case 2:
    Serial.println("Tuesday");
    break;
  case 3:
    Serial.println("Wednesday");
    break;
  case 4:
    Serial.println("Thursday");
    break;
  case 5:
    Serial.println("Friday");
    break;
  case 6:
    Serial.println("Saturday");
    break;
  }
}

void flash_data(int loops)
{
   for (int i = 0; i < loops; i++)
   {
      digitalWrite(LED_BUILTIN, HIGH);
      Serial.println("LED Pin HIGH: "+String(digitalRead(LED_BUILTIN)));
      delay(50);
      digitalWrite(LED_BUILTIN, LOW);
      Serial.println("LED Pin LOW: "+String(digitalRead(LED_BUILTIN)));
      delay(50);
   }
}

// callback for received data
void receiveData(int byteCount)
{
  Serial.println("Receiving Data... ");
  if ( Wire.available() ) {
    number = Wire.read();
  }
  Serial.println("Data Received: "+String(number));
}

void sendData() {
  Serial.println("Sending Data on Request");
  //byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  //readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  readDS3231time();
  //char buf1[20];
  //sprintf(buf1, "d:d:d d/d/d",  hour, minute, second, dayOfMonth, month, year);
  //Serial.print(buf1);
  Wire.write("Hello");
}

void setup() {
  Serial.begin(57600);
  do {
    delay(500);
  } while (!Serial);

  delay(500);
  Serial.println("Initializing Wire I2C on "+RPI_I2C_ADDRESS);
  // Join I@c bus as slave with RPI_I2C_ADDRESS 8
  Wire.begin(RPI_I2C_ADDRESS);

  Serial.println("Setting call back for Wire.onReceive");
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData);

  //Setup pin 13 as output and turn LED off
  Serial.println("Setting LED Pin up for Output");
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(RELAY_PIN1, OUTPUT);
  pinMode(TEMP_PIN1, INPUT);
  Serial.println("Turning LED off");
  digitalWrite(LED_BUILTIN, LOW);
}

float getVoltage(int pin)
{
  // This function has one input parameter, the analog pin number
  // to read. You might notice that this function does not have
  // "void" in front of it; this is because it returns a floating-
  // point value, which is the true voltage on that pin (0 to 5V).
  return (analogRead(pin) * 0.004882814);
  // This equation converts the 0 to 1023 value that analogRead()
  // returns, into a 0.0 to 5.0 value that is the true voltage
  // being read at that pin.
}

/*
 * MAIN LOOP
 */
void loop() {

  if ( number > 0 ) {
    //Serial.println("Flash Data: "+String(number));
    flash_data(number);
    float voltage, avgVoltage, degreesC, degreesF;
    if (number == 1) {
      digitalWrite(RELAY_PIN1, HIGH);
    } else if (number == 2) {
      digitalWrite(RELAY_PIN1, LOW);
    } else if ( number == 3 ) {
      voltage = getVoltage(TEMP_PIN1);
      //gets and prints the raw data from the lm35
      Serial.print("Voltage: ");
      Serial.print (voltage);
      Serial.println(" ");
      // Now we'll convert the voltage to degrees Celsius.
      // This formula comes from the temperature sensor datasheet:
      degreesC = (voltage - 0.48) * 100.0;
      Serial.print("CELSIUS: ");
      Serial.print(degreesC);
      Serial.println("*C ");
      //converts celsius into fahrenheit
      degreesF = degreesC * (9.0/5.0) + 32.0;
      Serial.print("FAHRENHEIT: ");
      Serial.print(degreesF);
      Serial.println("*F");
    } else if ( number == 4 ) {
       displayTime();
    }
    number = 0;
  } else {
    byte pinValue = bitRead(LED_BUILTIN, 3);
    if ( digitalRead(LED_BUILTIN) == HIGH ) {
      digitalWrite(LED_BUILTIN, LOW);
    }
  }
  delay(SAMPLE_TIME);
}
```
Any guidance would be appreciated!
THanks

body:
The onRequest and onReceive callback functions are called from inside an ISR. Thus you cannot use any code in there, that relies on interrupts to work. Serial writes or prints for example will only work, as longs as the buffer is not full (since the actual communication is handled by interrupts). If the buffer is full, the serial code will either block or loose data (depending on the version of the Arduino core. Not blocking in an ISR is a relatively new change). Such things also hapoen with other interrupt driven functions.

Let's take your codes logic particular in the onRequest callcack function. As written above, this is called from an ISR. The Wire library was contacted by the master to send data to it. With this callback the library uis asking you, what to answer the master. During that time, the current transmission (master read, slave send) is already active, but the slave is stalling the transaction, until the data is ready, meaning until you exit the onRequest callback. Now inside the callback you try to initiate another transaxtion on the same I2C bus, now as a master. The same I2C bus, where there is already a transaction going on. That cannot work. The former slave cannot take the control over the bus, since the first master haven't released it yet (as you tried this in the middle of it's transaction. So you are not only using interrupt driven functions in an ISR, you are also trying to reconfigure hardware, that you just got an interrupt from (which is a bad idea, unless you really know, what you are doing). The library has configured the hardware as slave and in the middle of the transaction you try to configure it as master.

I don't know, why you even try to do this. Since you already have the RTC on the same bus as the Pi, why not making the Pi the only master and let it directly poll the RTC? Why do you need the Arduino between them?

If you really really need the multi master setup for whatever reason (though I cannot think of one), you have to do the transactions independent of one another. The Arduino could poll the RTC regularly, when the bus is free, and buffer the results. Then it could send these results to the Pi, when it requests the Arduino to do that.

---

Note: I'm currently not up to date, how good the multi master support in the Wire library is these days. It incorporated the possibility for multi master since a long time, but when I checked last time, the bus arbitration was not implemented (meaning that if 2 masters try to send at the same time, the bus gets stalled). If it is still this way, you shouldn't use multi master with the Wire library.


message:
How to set a time out like Serial.setTimeout() for Serial.read()?

I read a comment form [here][1]:

"Serial.setTimeout() sets the maximum milliseconds to wait for serial data when using Serial.readBytesUntil(), Serial.readBytes(), Serial.parseInt() or Serial.parseFloat(). It defaults to 1000 milliseconds."

According to the [latest webpage][2],

"Serial functions that use the timeout value set via Serial.setTimeout():

    Serial.find()

    Serial.findUntil()

    Serial.parseInt()

    Serial.parseFloat()

    Serial.readBytes()

    Serial.readBytesUntil()

    Serial.readString()

    Serial.readStringUntil()

"

So apparently, there's no direct indication to set a timeout option for Serial.read().

How to set a time out like Serial.setTimeout() for Serial.read()?

  [1]: https://forum.arduino.cc/index.php?topic=439572.0
  [2]: https://www.arduino.cc/reference/en/language/functions/communication/serial/settimeout/

body:
You can't set timeout for read(), but you can use readBytes() to read one byte.

    byte b;
    int count = Serial.readBytes(&b, 1); // read one byte with timeout
    if (count) { // 0 or 1
      Serial.write(b); //echo
    }


message:
If Arduino connected to computer and opened up Serial Monitor, will Tx and Rx pin still be working?

Suppose one connected two of the Arduino Uno boards through Rx and Tx pins. Then, if one or both of the Arduino boards were connected to computer, and possibly opened up Serial Monitors, will Tx and Rx pin still be working? i.e. will Arduino still communicate through Rx and Tx pin when it's communicating to computer? If not how to make them working while connect to computer?

body:
You should't connect two TX Pins together. The Arduino has some protection resistors but even it is not recommended to connect two output pins.

The only save way to use the RX / TX pins directly is to remove the protection resistors (RN4A and RN4B in the reference design) or at least the RN4A  and use only one connection at a time. It doesn't help if you do not use the PC connection or doesn't open the Serial Monitor since the pins is still an output.

(Multiple RX Pins are no problem since they are inputs)

(And of course I know it could work with multiple TX pins together most of the time, but I would recommend it)


body:
> Suppose one connected two of the Arduino Uno boards through Rx and Tx
> pins.

I assume you will connect the TX of one Arduino to the RX of the other
one and vice versa, which is the right way to connect them. As
theSealion explained in his answer, you shouldn't connect two TX Pins
together.

> if one or both of the Arduino boards were connected to computer, and
> possibly opened up Serial Monitors

If you do that, the Arduino won't even notice.

Well, to be more accurate... there is a small chip on the Uno, near the
USB connector, labeled “MEGA16U2”. This chip is used as a USB/serial
converter, and it _will_ notice when you connect the USB link and when
you open the port. However, the main chip (the big PDIP28), which is the
microcontroller that runs your sketch, will neither know nor care.

> will Tx and Rx pin still be working?

Absolutely.

> will Arduino still communicate through Rx and Tx pin when it's
> communicating to computer?

The RX will not communicate with the computer. What will happen is:

* Whatever your Arduino writes to its serial port will be received by
  both the other Arduino and the serial monitor.
* Whatever you send through the serial monitor will be lost.
* When you `Serial.read()`, you will get whatever was set by the other
  Arduino.

The reason of this behavior is a 1 kΩ resistor that sits between
the Mega16U2's TX and the main microcontroller's RX. When you connect
this RX to the other Arduino's TX, which is low impedance (≈ 25 Ω),
that TX will “win”: a low impedance output overwhelms a high impedance
one.


body:
> how to make [two Arduinos communicating with each other] working while connect to computer?

There are a variety of ways for 2 Arduinos to directly communicate with each other while one or both are communicating with the Serial Monitor of a laptop computer over USB.

* Use a UART for the Arduinos to communicate that is independent of the USB connection. (See https://www.arduino.cc/reference/en/language/functions/communication/serial/ )
    * Several Arduino-compatible boards such as the Arduino Mega 2560, Arduino Due, Arduino Uno Wifi Rev.2, etc. have 4 hardware UARTs; the pins of Serial1 (note the "1") could be used to communicate with another Arduino without interfering with the Serial (without a "1") UART communication over USB to a laptop. (Alas, the Arduino Uno has only 1 hardware UART).
    * The ATmega32u4-based Arduino Micro and Arduino Leonardo and ATmega32u4-based Arduino derivatives such as [FLORA](https://www.adafruit.com/index.php?main_page=category&cPath=92) and many of the ARM-based Arduino derivatives such as the [Teensy series](https://www.pjrc.com/teensy/td_uart.html) have a USB interface that doesn't use *any* of the UART pins; so the pins of Serial1 (note the "1") could be used to communicate with another Arduino without interfering with the Serial (without a "1") non-UART communication over USB to a laptop. (Alas, the Arduino Uno has a USB interface that *does* use its only hardware UART pins).
    * Even the Arduino Uno, which has only 1 hardware UART whose pins are hard-wired to the USB interface chip, can bit-bang a slow simulation of a UART on other pins. See https://arduino.stackexchange.com/questions/34126/whats-the-difference-between-all-the-software-serial-libraries-which-one-is-ar .

* Rather than try to simulate a UART in software (the timing is kind of tricky), it may be easier/faster to use some other less time-sensitive ways of communicating between Arduino Unos or other Arduinos, such as
    * SPI between 2 Arduinos [(a)](https://forum.arduino.cc/index.php?topic=120049.0); [(b)](https://circuitdigest.com/microcontroller-projects/arduino-spi-communication-tutorial)
    * I2C between 2 Arduinos [(a)](https://www.instructables.com/id/Communication-Between-Two-Arduinos-I2C/) [(b)](https://dronebotworkshop.com/i2c-arduino-arduino/)
    * [PJON between 2 Arduinos][1]
    * a few [asynchronous communication](https://en.wikipedia.org/wiki/asynchronous_circuit#Communication) protocols have no timing dependencies at all
    * etc.

  [1]: https://hackaday.com/2016/03/31/pjon-fancy-one-wire-arduino-communications-protocol-for-home-automation/


body:
I got exactly the same problem! I was using the Arduino Uno board with an Jtag ICE mkii for debugging which was working nice. As I begann to use the UART it was a heavy mess. The transmitting from Arduino to an external TTL-USB adapter was working but not in the other direction. I played hours before I saw this thread and that gave me the idea for looking into the shematic -> Bang! I saw the two resistors.
Lesson learned: Do not use the Arduino hardware without the rest of the tools! Thought it was a good idea to use the hardware for rapid development. Now it costs me more time that I thought...


message:
Unconsistent time in arduino loop

I have this code:

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

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

The output looks like this:

[![output][2]][2]

Why are there non-periodically some extremely large values?

Thanks

  [1]: https://i.stack.imgur.com/p0XtM.png
  [2]: https://i.stack.imgur.com/mGbnf.png

body:
There are be several "tasks" and interrupts that run in the background and they influence how often the loop() function is called.

For example timer, usart ...

They all need some attention from time to time. If the need some really fixed execution time you must use something like a hardware timer.

and by the way: a maximum of ~1.1ms is not bad for such a small controller. :-)

And as a addition to your question in your comments: I don't think there is a way to make the loop faster. As long as you need the other tasks, you have do give them some time.