message:
How to pause a loop

any ideas on how could i code this loop so when i press a button everything stops (Vernier stops reading temperature), and then when i press the button again it (Vernier reader) stars working.

       #include "VernierLib.h"
        VernierLib Vernier;
        #define led 13
        #define button 12
        int switchState = 0;
        float sensorReading;
        void setup() {
          Serial.begin(9600);
          Serial.println(Vernier.sensorName());
          Vernier.autoID();
          pinMode(12, INPUT);
        }
        void loop() {
          static float base_temp = 0;
          static float t = 0;
          t = Serial.parseFloat();
          if (t != 0) {
            base_temp = t;
          }
          sensorReading = Vernier.readSensor();
          Serial.print(sensorReading);
          Serial.print(" ");
          Serial.println(Vernier.sensorUnits());
          Serial.print("Željena temperatura: ");
          Serial.println(base_temp);
          if (base_temp > sensorReading) {
            digitalWrite(led, HIGH);
          } else {
            digitalWrite(led, LOW);
          }
          delay(1500);
        }

body:
For reading the button I suggest using the [Bounce2 library][1]. Then you can wire your button to a fitting digital pin, the other side to ground. Use

    button.attach( BUTTON_PIN ,  INPUT_PULLUP );

To use the internal pullup of the Arduino. Define a global state variable, that holds, if your code should run or not.

    bool code_running = true;

Then in your main code (additional to calling the update function of the library) use

    if(button.fell()){
        code_running = !code_running;
    }

to toggle the state variable on button presses. Then, still in `void loop()`, use an if statement with the state variable to execute your code:

    if(code_running){
        // put your code here
    }

Note, that your code should not block for long periods for this to work correctly. You should always write your code in a non-blocking way, meaning, that no function call or loop will take longer than a few ms to execute. Otherwise your button action will not be responsive enough.

  [1]: https://github.com/thomasfredericks/Bounce2


sender: user

sender: assistant

body:
Assume you did `#define BUTTON 12` as I suggested.

Somewhere inside your loop you could code:

    if (digitalRead(BUTTON) {        // First button press
      while (digitalRead(BUTTON));   // Wait till button release
      while (!digitalRead(BUTTON));  // Wait till second button press
      while (digitalRead(BUTTON));   // Wait till button release
    }

This "hangs" from the first button press to the second button release. The code assumes your button takes pin 12 HIGH when pressed and LOW otherwise. This is a bit difficult to realize in hardware (well, not really; but you will beed an external Pull-Down resistor). The easier way will be to connect pin 12 to GND when button is pressed, and use the internal PullUp-resistor: `pinMode(BUTTON, INPUT_PULLUP);`. Then the logic of the `while` condition has to be reverted:

    if (!digitalRead(BUTTON) {        // First button press
      while (!digitalRead(BUTTON));   // Wait till button release
      while (digitalRead(BUTTON));    // Wait till second button press
      while (!digitalRead(BUTTON));   // Wait till button release
    }


message:
button connection without connection to 5V pin

There are two types of tutorials for buttons:
[![no power][1]][1]
[![enter image description here][2]][2]

I don't understand how a button on the first image works. Do we just hope that there is some non zero voltage and hope its enough? I think the first image is really bad, but can't explain why.

  [1]: https://i.stack.imgur.com/FFe8I.png
  [2]: https://i.stack.imgur.com/UCrqw.png

body:
The digital pins of an Arduino UNO, or rather the AVR microcontroller used in the UNO, have optional internal pull-up resistors that can be enabled with the `INPUT_PULLUP` option to `pinMode`.  When you use `INPUT_PULLUP` (as opposed to `INPUT`) there is a functional resistor somewhere between 20kOhm and 50kOhm connected between VCC ("5V") and the digital pin.  When you account for this internal resistor enabled, the circuits in your two images are structurally mirror images of one another:

[![Images from original post combined and annotated for showing the mirrored circuit structures.][1]][1]
The boxed numbers here are just to clarify what nodes in the wiring diagram correspond to what nodes in the schematic representation.  Don't ask where box number 5 is; it's a mystery.  I chopped part of the original second image so a new GND connection was hand-drawn in.

In your first image (left) the code would have to enable the internal pull-up resistor to establish a default `HIGH` state on the digital pin.    With `INPUT_PULLUP` enabled you can imagine that internal resistor there when comparing with your second image (right).  Here I've drawn a resistor symbol over the board to represent the internal one when enabled.  When the button is pushed some current is drawn through that internal pull-up and the voltage at the pin falls to ground.  Note you could just as easily have an external resistor there and use plain `INPUT` mode.

Your second example image (right) is using an external pull-down resister to establish a default `LOW` state.  So when you push the button, the signal rises toward 5V/VCC or `HIGH`, and some current flows through the pull-down resistor. This would be used with `INPUT` mode rather than `INPUT_PULLUP`; I have not annotated an internal pull-up on the right to indicate that the pull-up is not enabled in this scenario (plain `INPUT` mode).  *Note that if you **were** to enable the internal pull-up in this second configuration it would form a voltage divider with external pull-down; for the 10K external pictured this **could** result default voltage at the pin which is only bordering on being a proper `LOW`*.

Some people find it less confusing to have a `HIGH` state when the button is pushed and also using an external resistor like this helps to explain the concept having a pull resistor altogether, because you can see it.  In practice though, it's nice to able to use the internal resistors even if they pull in a more confusing direction.  Note there do exist microcontrollers have optional internal pull-down resistors as well, but they're not as common; the UNO in particular does not have these.

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


body:
There is a pullup resistor you don't see in the diagram because it is internal to the Arduino. I have added it in red. To make pin 7 an input, you can write:

    digitalWrite(7, INPUT_PULLUP);

, which not only makes the pin an input but also engages the internal ~20K pullup  resistor.

So, you're right about the first diagram - it looks like the pin is left floating. Without the code, or an explanatory note, the pullup resistor isn't documented. In such a diagram, once you are familiar with the processor and know that there are optional pullups on the pin-drivers, you can assume that the optional pullup will be used.

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

  [1]: https://i.stack.imgur.com/wynTU.jpg
Update: I drew in the resistor assuming the red rail was connected to 5v - I should have drawn that in, too.


message:
Wire.endTransmission(false) hanging the program after running once when using MPU6050

For this project, I was using an *Elegoo Car V3* and I was trying to add a gyroscope onto it. When I run the code for the car, my loop code iterates once and it is always able to read the sensor data. But after that, the program starts hanging. I traced back the problem to the `Wire.endTransmission(false)` line in my code. For some reason, that line was not completing the second time.

I spent a few hours trying to find a solution online. I triple checked my wiring and still, I could not find a solution to this problem.

Thank you for taking the time to help me!

This is the output of the program
```
RawX= 82
RawY= 241
RawZ= -1
-----------------------------------------
AngleX= 195.41
AngleY= 216.93
AngleZ= 200.14
-----------------------------------------

```

And this is the code
```

#include <Wire.h>

const int MPU_addr = 0x68;
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

int minVal = 265;
int maxVal = 402;

double x;
double y;
double z;
int c = 0;

//www.elegoo.com

//     Right motor truth table
//Here are some handy tables to show the various modes of operation.
//  ENB         IN3             IN4         Description
//  LOW   Not Applicable   Not Applicable   Motor is off
//  HIGH        LOW             LOW         Motor is stopped (brakes)
//  HIGH        LOW             HIGH        Motor is on and turning forwards
//  HIGH        HIGH            LOW         Motor is on and turning backwards
//  HIGH        HIGH            HIGH        Motor is stopped (brakes)

// define IO pin
#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11

//set car speed
#define CAR_SPEED 100
typedef unsigned char u8;  //Change the name of unsigned char to u8

void forward(u8 car_speed)
{
  analogWrite(ENA, car_speed);
  analogWrite(ENB, car_speed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
}

void back(u8 car_speed)
{
  analogWrite(ENA, car_speed);
  analogWrite(ENB, car_speed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
}

void left(u8 car_speed)
{
  analogWrite(ENA, 250);
  analogWrite(ENB, 250);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);

  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
}

void right(u8 car_speed)
{
  analogWrite(ENA, 250);
  analogWrite(ENB, 250);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
}

void stop()
{
  digitalWrite(ENA, LOW);
  digitalWrite(ENB, LOW);
}

int getGyroData() {
    Wire.beginTransmission(MPU_addr);
    Wire.write(0x3B);
    Wire.endTransmission(false);

    Wire.requestFrom(MPU_addr,6,true);
    AcX = Wire.read()<<8|Wire.read();
    AcY = Wire.read()<<8|Wire.read();
    AcZ = Wire.read()<<8|Wire.read();

    int xAng = map(AcX, minVal, maxVal,-90, 90);
    int yAng = map(AcY, minVal, maxVal,-90, 90);
    int zAng = map(AcZ, minVal, maxVal,-90, 90);

    x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
    y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
    z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);

    Serial.print("AngleX= ");
    Serial.println(x);

    Serial.print("AngleY= ");
    Serial.println(y);

    Serial.print("AngleZ= ");
    Serial.println(z);
    Serial.println("-----------------------------------------");

}

void turn(int degrees) {
    int *originalData;
    originalData = getGyroData();
    int originalTurn = originalData[2];

    bool notDone = true;

    while (notDone) {

        int *newVal;
        newVal = getGyroData();
        int newTurn = newVal[2];

        int change = originalTurn - newTurn;
        Serial.println(change);
    }
}

void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);
  pinMode(IN1, OUTPUT);//before useing io pin, pin mode must be set first
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENA, OUTPUT);
  pinMode(ENB, OUTPUT);
  Serial.begin(9600);

}

void loop(){
    c++;

    Serial.println(c);
    Wire.beginTransmission(MPU_addr);
    Serial.println(c);
    Wire.write(0x43);
    Serial.println(c);
    Wire.endTransmission(false);

    Serial.println(c);
    Wire.requestFrom(MPU_addr,4,true);
    AcX = Wire.read()<<8|Wire.read();
    AcY = Wire.read()<<8|Wire.read();
    AcZ = Wire.read()<<8|Wire.read();
    Serial.println(c);

    Serial.print("RawX= ");
    Serial.println(AcX);

    Serial.print("RawY= ");
    Serial.println(AcY);

    Serial.print("RawZ= ");
    Serial.println(AcZ);
    Serial.println("-----------------------------------------");

    int xAng = map(AcX, minVal, maxVal,-90, 90);
    int yAng = map(AcY, minVal, maxVal,-90, 90);
    int zAng = map(AcZ, minVal, maxVal,-90, 90);

    x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
    y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
    z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);

    Serial.print("AngleX= ");
    Serial.println(x);

    Serial.print("AngleY= ");
    Serial.println(y);

    Serial.print("AngleZ= ");
    Serial.println(z);
    Serial.println("-----------------------------------------");
    delay(500);

}
```

This is a schematic of the car I found

[![This is a schematic of the car I found][1]][1]

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

body:
In the comments below, [@chrisl][1] makes something explicit that I hadn't in previous edits.  Reading it first may make the below easier to interpret:

> Useful fact about I2C on Arduino: `Wire.endTransmission()` is the
> function, that actually does the I2C communication. Before that (all
> the `Wire.beginTransmission()` and `Wire.write()` calls) no data will run
> over the bus, just placed inside the libraries buffer. Thus a hanging
> `Wire.endTransmission()` equals a blocked I2C bus.

---

On the UNO the A4 and A5 are SDA and SCL, the same signals that are available near AREF and pin 13 on the other side of the board.

So, the ultrasonic range finder in the picture is attached the signals that are needed to operate the I2C ("Wire") bus, and may easily be interfering with `Wire.endTransmission(false)`.  One of the I2C signals is probably causing the range finger to trigger during I2C traffic.  After each trigger, the echo signal from the range finder would then interfere with the connected I2C bus signal.

You could try [bit banging I2C using a library][2] instead of the native I2C that is on A4/A5, and use that to operate your gyroscope.  According to your diagram, A0 through A3 are unused, and seem to be the only signals unused from the UNO.  Despite being "analog" pins they function as digital pins also and should work fine for bit-banging.  Getting to them may be a pain though, since the shield doesn't seem to make them available again as pins.

Or you may be able to route the ultrasonic sensor away from A4/A5 either by not plugging it into the header on the shield and instead route the signals from the plug to where an unused set of pins is available (again A0 though A3) and then updating the code accordingly.  Another possibility might be leave it plugged into the shield but bend the A4 and A5 pins to the side so they don't enter the UNO below, and use jumpers to route them from the bent pins to some other pair of available pins; you won't be able to bend them back and forth more than once or twice, so I would be careful with trying that.

  [1]: https://arduino.stackexchange.com/users/42015/chrisl
  [2]: https://www.arduino.cc/reference/en/libraries/bitbang_i2c/


message:
couldn't connect to MQTT broker via esp8266/32 and pub/sub client

I want to use hiveMQ public broker in my project that's the same broker as what available in PubSubClient esp8266 examples but when I change WiFi SSID and password in example and upload it I got this output:

```
Connecting to <SSID NAME>
........
WiFi connected
IP address:
192.168.1.14
Attempting MQTT connection...failed, rc=-2 try again in 5 seconds
Attempting MQTT connection...failed, rc=-2 try again in 5 seconds
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...
```

**I tried this with pubsub client v2.8/v2.6/v2.4 and esp32 latest version and esp8266 latest version and 2.3**

in response to the comment as I said my code is esp8266_basic example in the PubSub client examples and here is my code:
```
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "<SSID>";
const char* password = "<PASS>";
const char* mqtt_server = "broker.mqtt-dashboard.com"; //tested with broker.mqttdashboard.com

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883); //8000 and 1883 tested
  client.setCallback(callback);
}

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  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 callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is acive low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }

}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 75, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);
  }
}
```

on esp32 I remove `pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output` and
``` // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is acive low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }
```
sections and includes

and sometimes output is like this:
```
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...connected
```

body:
all things are OK and the problem is about my network I think there blocked MQTT (cause I couldn't connect any broker and not just hiveMQ) or other related things cause also my notebook doesn't connect I changed my network provider and the problem fixed

if you ran into the same issue, check other stuff and finally check with a computer in your network (don't use things like http://www.hivemq.com/demos/websocket-client/)


body:
I found this video as a problem solver, This may help you.
All MQTT Errors explained very well and Suggester Different troubleshooting techniques
https://youtu.be/CbodTTk-D18


message:
l298n voltage loss when motor attached

Im trying to power a brushless DC Motor (Tamiya 300054358) through the l298n attached to an Arduino.

The l298n is powered by an external 9V source and the logic of the l298n is powered by the Arduinos 5V, wich is also powered by the 9v.

Both components using the same ground.

The code looks good and i can successfully adjust the power-output for the motor between 6-9V.

As soon as is attach the Motor, the volage drops do somewhere around 0-1V and the motor isnt turning.

When i attach the motor directly to the power source, it runs fine, so the power should be enough. (in the original RC car its powered by an 7V battery).

I tried some smaller motors just to be sure and the problem is similar. The motor is turning, but very slowly.

I also tried to connect the batterypack instead of the extern power source just ending up with the same result.

Do you have any ideas, where the problem could be at?

Thanks in advance

body: The problem is in the H driver. You lose about 1.4 volts on each leg so your loss from the battery is about 2.8 volts. The internal driver transistors are in a darlington configuration. If the bridge were Power MOS instead of bipolar transistors your voltage would be dependent on the resistance of the MOSFETs. Typically a few tenths of a volt in total. If your 9V source is a battery you probably are not getting the 9V you are expecting.


body:
From an [L298N datasheet][1]:

> TOTAL DC CURRENT UP TO 4 A

From [motor][3]'s ["datasheet":][4]

[![Motor datasheet graph showing current usage up to 150 Amps][2]][2]

I'm no expert in electric motors and driving them, not even sure I'm novice level, but I just don't see you driving a motor anything near this current draw with this part.  If by some miracle you can, it will be horribly inefficient owing to the losses associated with the voltage drops that Gil mentions.

For a motor that operates with this much current I would expect a practical h-bridge setup to have discrete mosfets, perhaps mounted to a heatsink.

  [1]: https://www.st.com/resource/en/datasheet/l298.pdf
  [2]: https://i.stack.imgur.com/WRPfC.jpg
  [3]: https://www.tamiya.de/en/accessories/tamiya-accessories/rc-spare-option-parts/spare-option-parts/e-motor-rs-540-torque-turned-300054358/
  [4]: https://cdn.simba-dickie-group.de/downloads/300054358/300054358_Torque_Tuned.pdf


message:
SIM7000E Waveshare can't do anything

Can someone help me? I'm using a sim7000e from Waveshare. One week ago it was working normally, but now it doesn't work at all; it even can't read the RX-TX communication.

```c++
#include <SoftwareSerial.h> //koneksi ke modem

#define TINY_GSM_MODEM_SIM7000
#define TINY_GSM_DEBUG SerialMon
#define BAUD 9600
#define SerialMon Serial

const byte rxpin = 2;
const byte txpin = 3;

SoftwareSerial SerialAT(rxpin, txpin); // RX, TX
```

That's  my code for connecting to the Arduino. I believe it from my Arduino, but I don't know if something wrong from Arduino.

My 5V (sim7000E) to 5V (arduino mega2560), GND to GND.

Because I'm using Putty on USB for reading my AT-cmd it doesn't and has some trouble.

body:
I'm having similar issues, although it could well be my fault!

I can't see any coding sending AT commands, or waiting for responses in your example.

Try running your TX pin to your RX pin on your Arduino (take the SIM7000e out of the equation completely).  If your code works, then the issue is elsewhere.

I've tried connecting via USB and that seems through a terminal.  I was able to connect to a mobile network using the AT command

AT+CSTT="cmnet"


message:
Program ESP01 and keep it after reboot

I am bit of a noob when it comes to ESP programming. I have an ESP01 and a USB programmer for it, but every time I unplug it, it resets, which makes me wonder how can I make it battery-powered since every reboot resets the program.

body:
The ESP-01 ... and all ESP8622 ... have two modes for operation.

1) Flash mode / Boot load mode - on bootup (at the time an electrical current is first applied, or after the reset pin is grounded), if the GPIO0 (GPIO Zero) pin {[On the ESP-01 this is the 7th pin](https://en.wikipedia.org/wiki/ESP8266#Pinout_of_ESP-01)} is connected to ground, the chip goes into non-run, receive program mode.  This is where you load the compiled program.

2) Normal - on bootup (as above), but GPIO0 is ***NOT*** ground, then the ESP-01 goes into run mode.


message:
Why do I get different results when compiling the same code with different ide?

I have a basic code about reading true rms.I compiled the same code with arduino ide and atmel studio, then ran it in a proteus simulation.I'm trying to measure how long the read_rms() function takes.

My mcu:attiny84

1.experiment)I have added board to arduino ide with board manager.And I chose attiny84 and internal 1Mhz from tools menu in arduino menu.
The result was that the read_rms() function took 23.25 milliseconds.

2.experiment)I compiled the same code without any changes in Atmel Studio.Device,attiny84 selected.
The result was that the read_rms() function took 44 milliseconds.

44 miliseconds vs 23.25 miliseconds. Why?

Note:The following settings are selected in the proteus.Internal RC Osc. 8 Mhz,and CKDIV8=Programmed.

My code:

    #define F_CPU 1000000UL
    #include <avr/io.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    #include <stdint.h>
    const uint8_t muxbits = 1<<MUX3 | 1<<MUX2 | 1<<MUX1 | 1<<MUX0;

    void adc_init()
    {
     ADMUX = 0;    //Vcc_ref_
     ADCSRA = (1<<ADEN)|(1<<ADPS1)|(1<<ADPS0); //adc_enable_and_prescaler_8_ 125000 Hz (1000000/8)
     //first_try
     ADCSRA |= (1<<ADSC);
     while ((ADCSRA & (1<<ADSC)) != 0);
    }

    uint16_t adc_read(uint8_t channel)
    {
     ADMUX = (ADMUX & ~muxbits) | channel;
     // start_single_convertion
     ADCSRA |= (1<<ADSC);

     // wait for conversion to complete
     while ((ADCSRA & (1<<ADSC)) != 0);

     return (ADC);
    }

    double read_rms()
    {
     uint16_t i=0;
     uint16_t a_data=0;
     uint32_t sum=0;
     float avarage=0;
     double rms=0;
     for(i=0;i<200;i++)
     {
      a_data=adc_read(1);

      sum=sum+(a_data*a_data);
     }
     avarage=(float)sum/200;
     rms=sqrt((double)avarage);

     return rms;

    }

    int main(void)
    {

     DDRA|=(1<<7);
     PORTA &=~ (1<<7);
     adc_init();

     while(1)
     {

     read_rms();
     PORTA ^= (1<<7);// TOOGLE_PA7   for_measure_time_of_read_rms()_with_oscilloscope

     }
    }

body:
Different compilers produce different machine code.

As Majenko pointed out, the Arduino IDE's compiler, which happens to be GCC, uses `float` even when you write `double`.

The Atmel Studio creates `double` for `double`, using twice as much bits.

Calculating with more bits takes longer.


message:
How can I operate the leds and neopixel strips together (at the same time)?

Here's the code I wrote:

```c++
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

int latchPin = 8;
int clockPin = 12;
int dataPin = 11;

int numOfRegisters = 2;
byte* registerState;

long effectId = 0;
long prevEffect = 0;
long effectRepeat = 0;
long effectSpeed = 30;

#define LED_PIN    2
#define LED_COUNT 24

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
  #endif

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)

  //Initialize array
  registerState = new byte[numOfRegisters];
  for (size_t i = 0; i < numOfRegisters; i++) {
    registerState[i] = 0;
  }

  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
  do {
    effectId = random(6);
  } while (effectId == prevEffect);
  prevEffect = effectId;

  switch (effectId) {
  case 0:
    effectRepeat = random(1, 2);
    break;
  case 1:
    effectRepeat = random(1, 2);
    break;
  case 3:
    effectRepeat = random(1, 5);
    break;
  case 4:
    effectRepeat = random(1, 2);
    break;
  case 5:
    effectRepeat = random(1, 2);
    break;
  }

  for (int i = 0; i < effectRepeat; i++) {
    effectSpeed = random(10, 90);

    switch (effectId) {
    case 0:
      effectA(effectSpeed);
      break;
    case 1:
      effectB(effectSpeed);
      break;
    case 3:
      effectC(effectSpeed);
      break;
    case 4:
      effectD(effectSpeed);
      break;
    case 6:
      effectE(effectSpeed);
      break;
    }
  }

  // Fill along the length of the strip in various colors...
  colorWipe(strip.Color(255,   0,   0), 1); // Red
  colorWipe(strip.Color(  0, 255,   0), 1); // Green
  colorWipe(strip.Color(  0,   0, 255), 1); // Blue

  // Do a theater marquee effect in various colors...
  theaterChase(strip.Color(127, 127, 127), 1); // White, half brightness
  theaterChase(strip.Color(127,   0,   0), 1); // Red, half brightness
  theaterChase(strip.Color(  0,   0, 127), 1); // Blue, half brightness

  rainbow(1);             // Flowing rainbow cycle along the whole strip
  theaterChaseRainbow(1); // Rainbow-enhanced theaterChase variant
}

void colorWipe(uint32_t color, int wait) {
  for (int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);          //  Set pixel's color (in RAM)
    strip.show();                           //  Update strip to match
    delay(wait);                            //  Pause for a moment
  }
}

void theaterChase(uint32_t color, int wait) {
  for (int a=0; a<10; a++) {  // Repeat 10 times...
    for (int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();          //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in steps of 3...
      for (int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show(); // Update strip with new contents
      delay(wait);  // Pause for a moment
    }
  }
}

void rainbow(int wait) {
  for (long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    for (int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}

void theaterChaseRainbow(int wait) {
  int firstPixelHue = 0;      // First pixel starts at red (hue 0)
  for (int a=0; a<30; a++) {  // Repeat 30 times...
    for (int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();          //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in increments of 3...
      for (int c=b; c<strip.numPixels(); c += 3) {
        // hue of pixel 'c' is offset by an amount to make one full
        // revolution of the color wheel (range 65536) along the length
        // of the strip (strip.numPixels() steps):
        int hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show();                // Update strip with new contents
      delay(wait);                 // Pause for a moment
      firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
    }
  }
}

void effectA(int speed){
  for (int i = 0; i < 16; i++) {
    for (int k = i; k < 16; k++) {
      regWrite(k, HIGH);
      delay(speed);
      regWrite(k, LOW);
    }

    regWrite(i, HIGH);
  }
}

void effectB(int speed) {
  for (int i = 15; i >= 0; i--) {
    for (int k = 0; k < i; k++) {
      regWrite(k, HIGH);
      delay(speed);
      regWrite(k, LOW);
    }

    regWrite(i, HIGH);
  }
}

void effectC(int speed){
  int prevI = 0;
  for (int i = 0; i < 16; i++) {
    regWrite(prevI, LOW);
    regWrite(i, HIGH);
    prevI = i;

    delay(speed);
  }

  for (int i = 15; i >= 0; i--) {
    regWrite(prevI, LOW);
    regWrite(i, HIGH);
    prevI = i;

    delay(speed);
  }
}

void effectD(int speed){
  for (int i = 0; i < 8; i++) {
    for (int k = i; k < 8; k++) {
      regWrite(k, HIGH);
      regWrite(15 - k, HIGH);
      delay(speed);
      regWrite(k, LOW);
      regWrite(15 - k, LOW);
    }

    regWrite(i, HIGH);
    regWrite(15 - i, HIGH);
  }
}

void effectE(int speed) {
  for (int i = 7; i >= 0; i--) {
    for (int k = 0; k <= i; k++) {
      regWrite(k, HIGH);
      regWrite(15 - k, HIGH);
      delay(speed);
      regWrite(k, LOW);
      regWrite(15 - k, LOW);
    }

    regWrite(i, HIGH);
    regWrite(15 - i, HIGH);
  }
}

void regWrite(int pin, bool state) {
  //Determines register
  int reg = pin / 8;
  //Determines pin for actual register
  int actualPin = pin - (8 * reg);

  //Begin session
  digitalWrite(latchPin, LOW);

  for (int i = 0; i < numOfRegisters; i++) {
    //Get actual states for register
    byte* states = &registerState[i];

    //Update state
    if (i == reg){
      bitWrite(*states, actualPin, state);
    }

    //Write
    shiftOut(dataPin, clockPin, MSBFIRST, *states);
  }

  //End session
  digitalWrite(latchPin, HIGH);
}
```

body:
This comes up ALL THE TIME. Don't use delay. Do a Google search on "arduino blinkwithoutdelay" and read one of the various write-ups on the subject.

Here's a writeup that looks pretty good:

https://learn.adafruit.com/multi-tasking-the-arduino-part-1/using-millis-for-timing


message:
7 segment 4 digit not showing numbers 2,3 and 0

https://www.instructables.com/Using-a-4-digit-7-segment-display-with-arduino/

I used this link to make my circuit and I used this code also but some numbers like 2,3 and 0 doesn't display correctly.[![(This is the error. First number is 1 second is 2 third is 3 and fourth is 0)][1]][1]

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

body:
It looks like you have the center segment and the top left vertical segment reversed. For the image you show, if you switched the on/off states of those 2 segments, you'd see `1230`.

I don't know if the problem is in your code or in your wiring. The simplest fix would be to swap the pins for those 2 segments.


message:
Connecting Seeeduino XIAO 3.3 V out to dual H-bridge driver module (L298N) with TTL compatible inputs

The H-bridge module uses TTL compatible logic, but the chip allows these values (based on the [L298N data sheet][1]):

| Symbol | Parameter | Min. | Max. |
| :----: | --------- | :--: | :---: |
| ViL    | Input Low Voltage (pin 5, 7, 10, and 12)   | -0.3 V | 1.5 V |
| ViH    | Input High Voltage (pin 5, 7, 10, and 12)  | 2.3 V  | VSS |

Am I correct to assume that I do not need to step-up the logic signal (from 3.3 V to 5 V) for this to work, but can I connect straight to the input?

Schematic in mind:

[![Enter image description here][2]][2]

  [1]: https://datasheets.diptrace.com/st_micro/CD00000240.pdf
  [2]: https://i.stack.imgur.com/lXkFb.gif

body:
> Am I correct to assume that I do not need to step-up the logic signal (from 3.3V to 5V) for this to work, but can connect straight to the input?

You are correct. The input has to be above 2.3V to register as HIGH and below 1.5V to register as LOW. You have 3.3V for HIGH and near 0V for LOW, which fits those criteria perfectly.


message:
Memory allocation on Arduino Due never returns NULL

I'm working on a project that uses quite a bit of RAM to store and analyze data that is sent from the PC. The program heavily relies on `malloc`/`free`, which normally works just fine. However, if the data set gets to big - which I can't tell beforehand - the Arduino just dies. Some analysis found that it has to do with memory management. Running a simple sketch which just does

```c++
void loop() {
  int SIZE_TO_TEST = (1024 * 10);
  int* mem = (int*)malloc(SIZE_TO_TEST);
  if (mem == nullptr)
  {
    // This never happens
    Serial.print("Allocation failed\r\n");
    return;
  }
  Serial.print("Allocation succeeded\r\n");
  Serial.print((int)mem, HEX); // this always prints 0x200712E0, regardless of the size
  Serial.println();
  for (int i = 0; i < SIZE_TO_TEST / 4; i++)
  {
    mem[i] = i;
  }

  for (int i = 0; i < SIZE_TO_TEST / 4; i++)
  {
    if (mem[i] != i)
    {
      // You better get a new board if this happens
      Serial.print("HARDWARE ERROR: Memory broken\r\n");
    }
  }
  free(mem);
}
```

works fine and repeatedly prints "Allocation succeeded". When I start increasing the `SIZE_TO_TEST`, the CPU crashes when the value is over the effective memory size of 96k. The weird thing is, that even when the value is 1000k (far beyond what the uP actually has), the pointer returned by `malloc()` is still the same memory address, not `NULL`, as one would expect. The crash also does *not* occur if the allocated memory is not used (if the two for loops are commented out), so I suspect the actual crash occurs because the program tries to write to memory that is not actually there.

How do I find out that the memory is exhausted? Why does `malloc()` never return `NULL`?

(Note: I know about the problems of memory fragmentation with small micro controllers, but I can work around that issue)

body:
Why
===

This is a partial answer, for now, mostly with regard to:
> Why does malloc() never return NULL?

So, the Due appears to use [Newlib][1] as its libc implementation; that is the systems C (standard and some non-standard) runtime that includes `malloc()`, or the greater part of `malloc()` anyway.  The Newlib `malloc()` relies on an  `sbrk()` function which is implemented by the specific system, the Due in this case.
This name and basic idea comes out of Unix; you can read about the interplay between [malloc and sbrk][2] some without it having to be in connection with Newlib or the Due specifically.  In short, `sbrk` extends the area that `malloc` has to work with and `malloc` divides that area into requested chunks.  [Here is Newlib's documentation for sbrk and a sample implementation][3].

The Due (SAM) core for Arduino [implements sbrk][4] as:

```c
extern caddr_t _sbrk ( int incr )
{
    static unsigned char *heap = NULL ;
    unsigned char *prev_heap ;

    if ( heap == NULL )
    {
        heap = (unsigned char *)&_end ;
    }
    prev_heap = heap;

    heap += incr ;

    return (caddr_t) prev_heap ;
}
```

This is a kind of degenerate implementation of `_sbrk` that just blindly says, "You want more memory, sure here you go" **without limit**.  If you look at the sample `sbrk` implementation for Newlib, you'll see it just calls `abort()` instead of a proper failure that would result in `malloc` returning `NULL`, which is admittedly not great, but at least it's not pretending that everything is fine.

There should be a condition somewhere in this code that check so see if there's any more space to be had and sets `errno = ENOMEM` and effectively does `return -1` if there is not.

I modified this code to allow me to set a variable from the sketch that could force the next call to `_sbrk` to fail as described above.  And sure enough, on the next call to `malloc()` it returned `NULL` because `_sbrk` had indicated failure.

So the `_sbrk` implementation provided by the Due/sam core should be changed so that `malloc` fails when appropriate.  That said, I'm not precisely sure how that should be done.  So I'm going to hold off on making specific recommendations about it.  Maybe I look into it more I'll come back and update this with something more useful, addressing your other question of:
> How do I find out that the memory is exhausted?

In rough terms though, the answer going to be that you modify that function so it returns `-1` with `ENOMEM` under the right conditions.

---

How
===

This is the previously mentioned update with some details on the *how*:
> How do I find out that the memory is exhausted?

So I've made something to give you an idea what the condition would look like.  I'm not strictly recommending you use it; for one thing it's barely been tested.

From the [ATSAM3X8E][5]'s family [datasheet][6]:

> SRAM0 is accessible over the system Cortex-M3 bus at address 0x2000 0000
> and SRAM1 at address 0x2008 0000. **The user can see the SRAM as
> contiguous thanks to mirror effect, giving 0x2007 0000 - 0x2008 7FFF
> for SAM3X/A8**

The stack pointer starts near the top of memory 0x2008 7FFF and grows
downward.  The `_end` symbol marks the end of the mutable static storage
duration variables or the beginning of the heap.  Somewhere closer to
0x2007 0000; the fewer of these variables the closer.

On this system, which has a fairly common layout, the heap grows up with positive increments to sbrk as the stack pointer grows down with stack frames (local variables, return addresses etc).  So, "the end" of memory happens when the heap would otherwise allocate over the stack or the stack runs into the heap as your pushing things onto it.

So a typical thing to do is to check to see whether or not the `sbrk`'s argument would cause the edge of the heap to get "too close" to the stack.

In the the `/.arduino15/packages/arduino/hardware/sam/1.6.12/cores/arduino/syscalls_sam3.c`, I've include some extra headers:

```c
#include <errno.h>
#include <stdlib.h>
```

And put the following as a replacement `_sbrk()`:

```c
size_t __malloc_margin = 4 * (size_t)1024;
extern caddr_t _sbrk (int incr) {
    static const unsigned char *       heap      = (unsigned char *)&_end ;
    /****/ const unsigned char * const prev_heap = heap;

    if (incr > 0) {
        // Extra checks for stack growing

        if (incr >= 96 * (size_t)1024) {
            // The Due only has 96K of ram,
            // so any request for 96K or greater
            // is a failure out of the gate.
            errno = ENOMEM;
            return (caddr_t)-1;
        }

        unsigned char *stack_ptr;

        asm volatile(
            "mov %[sp_out], sp"
            : [sp_out] "=r" (stack_ptr)
            :
        );

        if (stack_ptr < heap) {
            // We're already in real trouble.
            abort();
        }

        if (stack_ptr - heap  <  incr + __malloc_margin) {
            // Not enough memory considering safety margin.
            errno = ENOMEM;
            return (caddr_t)-1;
        }
    }

    heap      += incr ;
    return (caddr_t) prev_heap ;
}
```

`__malloc_margin` was used as a variable name just because it's the name that avr-libc uses for the same purpose, namely to tune the minimum distance between the stack and heap during an allocation that the break to increase.  *By the way, you can see this same kind of check happen in avr-libc's implementation of malloc (which also takes `sbrk`'s role.)*  Why is `__malloc_margin` 4K ?  No really scientific reason.  It's about 4% of memory, so it's not large, and it's not completely inconceivable *to me* that someone would try to put local variable(s) approaching 4k in a stack frame on a system that has 96kb total memory.  4K may not be an appropriate default though; more thought should go into that.  Having it in a variable like this allows it to be tuned at runtime; usually there would be a header that provides an `extern` declaration for it.

I may add more later to explain, but it short if the break is being increased, this `sbrk` looks to see if the new break would get within `__malloc_margin` of the stack pointer on a request, an if it would it returns the `-1` value and `errno = ENOMEM` to cause `malloc` to behave correctly from the user's perspective.

Before anyone bothers to mention: Yes, I know you can take the address of a local to get a stack pointer value.  Yes, the check to see if the single allocation is larger than 96K is probably unnecessary.  Yup, it has Due specific stuff in it even though it's not strictly a Due; there are probably identifiers that could be used instead.  It should probably `abort()` if sbrk tries to go below 0 sized heap.  It's just a somewhat working *illustration* of what should be in `_sbrk()`.  More thought and at least one change should be put into it before general use.

Regarding abort()
=================

It occurs to me in *some* cases `abort()` may be an appropriate way to handle this.  If you believe that you can characterize the system (or the sketch if you like) at runtime so well that `malloc()` failing can be regarded as a major oversight, then calling `abort()` in `sbrk()` could make sense.  Or at least providing the option to do that.

In the comments you asked:
> What does abort() exactly [do] on the Due?

Well, Newlib documentation [says][7]:
> Before terminating your program, abort raises the exception SIGABRT
> (using ‘raise(SIGABRT)’).

and then further down:
> Supporting OS subroutines required: _exit and optionally, write.

The `SIGABRT` and `_exit` parts are more or less standard behaviour.  So it will call your signal handler for `SIGABRT` if you have one.

So then what does `_exit` do?  It loops forever.

I called `abort()` in a sketch and dumped the following via an arm version of the binutils objdump with `-dS` command-line options.

Here's the relevant `abort()` code:

```#
00081b98 <abort>:
   81b98: b508       push {r3, lr}
   81b9a: 2006       movs r0, #6
   81b9c: f000 fb5c  bl 82258 <raise>
   81ba0: 2001       movs r0, #1
   81ba2: f7fe fec5  bl 80930 <_exit>
   81ba6: bf00       nop
```

`bl <raise>` would in turn call your signal handler.  and `bl <_exit>` calls exit which displays as:

```#
00080930 <_exit>:

extern void _exit( int status )
{
   80930: e7fe       b.n 80930 <_exit>

00080932 <_kill>:

    for ( ; ; ) ;
}
```

It appears the optimizer has combined some things here, but essentially `_exit` has an instruction that jumps (branches) to itself, equivelent to `for(;;);`.

I half-expected the `abort();` code to disable interrupts before calling `_exit()`.  If you do plan on `abort()` in your `_sbrk()` that might be something to think about.  You may also want to provide a global flag that can be inspected from `SIGABRT` that allows the signal handler to do something diagnostically appropriate specifically for `_sbrk()` failures.
Perhaps `sbrk` should set a flag in a no-init data section and then set the watchdog timer and let it expire (or provide the `SIGABRT` handler with the information to do that).  Lots of things to consider.

  [1]: https://en.wikipedia.org/wiki/Newlib
  [2]: https://en.wikipedia.org/wiki/Sbrk
  [3]: https://sourceware.org/newlib/libc.html#index-sbrk
  [4]: https://github.com/arduino/ArduinoCore-sam/blob/790ff2/cores/arduino/syscalls_sam3.c#L64
  [5]: https://www.microchip.com/wwwproducts/en/ATSAM3X8E
  [6]: https://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D5xE5x_Family_Data_Sheet_DS60001507F.pdf
  [7]: https://sourceware.org/newlib/libc.html#abort


body:
I think I found a workaround. It relies on the fact that on simple program architectures such as the one used on most microcontrollers, the heap grows upwards while the stack grows backwards.

```c++
const int MIN_FREE_STACK = 512;

void* mallocEx(int size)
{
  void* stackPtr = alloca(4); // This returns a pointer to the current bottom of the stack
  PrintAddress("StackPtr ", stackPtr);
  void* ptr = malloc(size);
  PrintAddress("NewInstance ", ptr);
  if ((byte*)ptr + size > ((byte*)stackPtr - MIN_FREE_STACK))
  {
    free(ptr); // This memory location is not really valid
    return nullptr;
  }
  return ptr;
}

```

The method checks, on each attempt to allocate memory, whether the newly allocated block would reach into the call stack (+ some safety margin). If so, the pointer is freed again and null is returned.

I tried with this a bit more demanding test, and it seems to work as expected (allocates a bunch of blocks until it fails at around 91k, then restarts)

```c++

void ValidateMemoryManager()
{
  const int oneK = 1024;
  const int maxMemToTest = 100; // the arduino due has 96k of memory
  void* ptrs[maxMemToTest];
  int idx = 0;
  int totalAllocsSucceeded = 0;
  while (idx < maxMemToTest)
  {
    void* mem = mallocEx(oneK);
    ptrs[idx] = mem;
    if (mem == nullptr)
    {
      break;
    }
    idx++;
  }

  // Happens in simulation
  if (idx == maxMemToTest)
  {
    idx--;
  }

  totalAllocsSucceeded = idx;
  while (idx >= 0)
  {
    free(ptrs[idx]);
    idx--;
  }

   Serial.print("Total usable memory: ");
   Serial.print(totalAllocsSucceeded * oneK, DEC);
   Serial.println();
}
```


message:
How do I resolve error message "assignment of function 'void digitalWrite (uint8_t, uint_8)"?

I am a beginner in using Arduino and programming in c/c++. I am trying to connect a 10-segment LED and a moisture sensor to my Arduino Uno, and when the moisture level is very low, the first 2 red LEDs will be turned on, when it is slightly higher, the next three orange LEDs will be turned on, when it is slightly higher the next three green LEDs will be turned on, and finally when the moisture level is above the threshold for the green LEDs, the final blue LED segment will turn on.

 I have written a program that works, and I have tested both the moisture sensor and the 10 segment LED separately to ensure they are working. Although the program works how I intend it, about 30-40% of the time I am unable to run the program due to an error message in the process of uploading. To be clear, I do not change the code at all from the working state of the code to the error message appearing. I wanted to know why this message appears, and how to avoid/resolve this issue.

 I have included my code below:

    /*
       Arduino LED Bar Graph with Moisture Sensor
       Started June 25, 2020

       edited 6/28
        (added blue LED)
    */

    int redLED = 13;
    int yellowLED = 12;
    int greenLED = 11;
    int blueLED = 10;

    #define SensorPin A0
    float sensorValue = 0;
    float moistureLevel = 0;

    void setup()
    {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(redLED, OUTPUT);
      pinMode(yellowLED, OUTPUT);
      pinMode(greenLED, OUTPUT);
      pinMode(blueLED, OUTPUT);
    }

    void loop()
    {
      if  (Serial.available() > 900)
      {
        moistureLevel = Serial.read();//set the var moistureLevel
        digitalWrite = (redLED, HIGH);
        digitalWrite = (yellowLED, LOW);
        digitalWrite = (greenLED, LOW);
        digitalWrite = (blueLED, LOW)
      }
      else if (Serial.available() > 750)
      {
        moistureLevel = Serial.read();//set the var moistureLevel
        digitalWrite = (yellowLED, HIGH);
        digitalWrite = (redLED, LOW);
        digitalWrite = (greenLED, LOW);

      }
      else(Serial.available() > 550)
      {
        moistureLevel = Serial.read();//set the var moistureLevel
        digitalWrite = (greenLED, HIGH);
        digitalWrite = (redLED, LOW);
        digitalWrite = (yellowLED, LOW);
        digitalWrite = (blueLED, LOW);
      }
      else(Serial.available() < 549)
      {
        moistureLevel = Serial.read();//set the var moistureLevel
        digitalWrite = (greenLED, HIGH);
        digitalWrite = (redLED, LOW);
        digitalWrite = (yellowLED, LOW);
        digitalWrite = (blueLED, HIGH);
      }
      for (int i = 0; i <= 100; i++)
      {
        sensorValue = sensorValue + analogRead(SensorPin);
        delay(1);
      }
      sensorValue = sensorValue / 100.0;
      Serial.println(sensorValue);
      delay(100);
    }

And here is a copy of the exact error message:

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino: In function 'void loop()':

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:33:33: error: assignment of function 'void digitalWrite(uint8_t, uint8_t)'

    digitalWrite = {redLED, HIGH};

    ^

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:33:33: error: cannot convert '<brace-enclosed initializer list>' to 'void(uint8_t, uint8_t) {aka void(unsigned char, unsigned char)}' in assignment

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:34:35: error: assignment of function 'void digitalWrite(uint8_t, uint8_t)'

    digitalWrite = (yellowLED, LOW);

    ^

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:34:35: error: cannot convert 'int' to 'void(uint8_t, uint8_t) {aka void(unsigned char, unsigned char)}' in assignment

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:35:34: error: assignment of function 'void digitalWrite(uint8_t, uint8_t)'

    digitalWrite = (greenLED, LOW);

    ^

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:35:34: error: cannot convert 'int' to 'void(uint8_t, uint8_t) {aka void(unsigned char, unsigned char)}' in assignment

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:36:33: error: assignment of function 'void digitalWrite(uint8_t, uint8_t)'

    digitalWrite = (blueLED, LOW)

    ^

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:36:33: error: cannot convert 'int' to 'void(uint8_t, uint8_t) {aka void(unsigned char, unsigned char)}' in assignment

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:41:36: error: assignment of function 'void digitalWrite(uint8_t, uint8_t)'

    digitalWrite = (yellowLED, HIGH);

    ^

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:41:36: error: cannot convert 'int' to 'void(uint8_t, uint8_t) {aka void(unsigned char, unsigned char)}' in assignment

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:42:32: error: assignment of function 'void digitalWrite(uint8_t, uint8_t)'

    digitalWrite = (redLED, LOW);

    ^

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:42:32: error: cannot convert 'int' to 'void(uint8_t, uint8_t) {aka void(unsigned char, unsigned char)}' in assignment

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:43:34: error: assignment of function 'void digitalWrite(uint8_t, uint8_t)'

    digitalWrite = (greenLED, LOW);

    ^

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:43:34: error: cannot convert 'int' to 'void(uint8_t, uint8_t) {aka void(unsigned char, unsigned char)}' in assignment

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:47:3: error: expected ';' before '{' token

    {

    ^

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:54:3: error: 'else' without a previous 'if'

    else(Serial.available() < 549)

    ^~~~

    /tmp/777165248/sketch_jun25a/sketch_jun25a.ino:55:3: error: expected ';' before '{' token

    {

    ^

    exit status 1

body:
You have:

    digitalWrite = (redLED, HIGH);

This is incorrect since digitalWrite is a function not a variable.  Instead you likely want:

    digitalWrite(redLED, HIGH);

This calls the digitalWrite function with the two arguments.


message:
L298N motor driver problems

(edited)

So sorry my bad. To make it clear:

From the picture that I posted, I need to press the PBA (as Button1) so that both motors can run in forward (CW-clockwise)  and backward (CCW-counterclockwise) and  a stop.

While on the other hand, PBB (as button2) is for another condition  both motors can run in left, right, and stop.

*Problems*:

1) When I run my code, it appears glitching from my LCD display.

2) I able to achieve for PBB side but for PBA side, both motors don't move at all.

3) I had use potentiometer to adjust my speed. The potentiometer are doing fine.

4) I use debounce for both my buttons and I am not sure whether the debounce effect my `void setmode(int Mode, int MotorMode1){}`

```c++
////////////////////////////////////////////////////////////////////////////////[![enter image description here][1]][1]

boolean lastButton=LOW;
boolean currentButton = LOW;

boolean last1Button = LOW;
boolean current1Button = LOW;

boolean debounce(boolean last){
    boolean current = digitalRead(PBA);
    if (last != current) {
      delay(5);
      current = digitalRead(PBA);
      return current;
    }
  }

  boolean debounce1(boolean last1) {
    boolean current1 = digitalRead(PBB);
    if (last1 != current1) {
      delay(5);
      current1 = digitalRead(PBB);
      return current1;
    }
  }

  int Mode = 0;
  int motorMode1 = 0;

  void loop() {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("SPEED:");
    lcd.setCursor(0, 1);

    // potentiometer LCD
    float inputValue = analogRead (pot);
    inputValue = map(inputValue, 0, 1023, 0, 100);
    lcd.setCursor(7, 0);
    lcd.print (inputValue);
    lcd.setCursor(12, 0);
    lcd.print ("%");

    //read values from potentiometer
    MotorSpeed = analogRead(SpeedControl);
    MotorSpeed = map(MotorSpeed, 0 , 1023 , 0 , 255);
    // adjust to prevent at low speed
    if (MotorSpeed < 8)MotorSpeed = 0;
    //set the motor speed
    //analogWrite (enA, MotorSpeed);
    //analogWrite (enB, MotorSpeed);
    // MotorLCD
    lcd.setCursor(0, 1);
    lcd.print("MOVE:");

    currentButton = debounce(lastButton);
    if (currentButton == HIGH && lastButton == LOW) {
      Mode++;
    }
    lastButton = currentButton;
    if (Mode == 3){
      Mode = 0;
    }

    current1Button = debounce1(last1Button);
    if (last1Button == HIGH && current1Button == LOW) {
      motorMode1++;

    }
    last1Button = current1Button;
    if (motorMode1 == 3){
      motorMode1 = 0;
    }

  setMode( Mode, motorMode1);

 }

  void setMode(int Mode, int motorMode1) {
    analogWrite (enA, MotorSpeed);
    analogWrite (enB, MotorSpeed);

    if (Mode == 1 ) {
      lcd.setCursor(5, 8);
      lcd.print("Forward");

      //MOTOR_A CLOCKWISE MAX SPEED
      digitalWrite(in1, HIGH);
      digitalWrite(in2, LOW);

      //MOTOR_B CLOCKWISE MAX SPEED
      digitalWrite(in3, HIGH);
      digitalWrite(in4, LOW);
    }
    if (Mode == 2) {
      lcd.setCursor(5, 8);
      lcd.print("Reverse");

      //MOTOR_A COUNTERCLOCKWISE MAX SPEED
      digitalWrite(in1, LOW);
      digitalWrite(in2, HIGH);

      //MOTOR_B COUNTERCLOCKWISE MAX SPEED
      digitalWrite(in3, LOW);
      digitalWrite(in4, HIGH);

    }

   if (motorMode1 == 1) {

      lcd.setCursor(5, 8);
      lcd.print("Right");
      //MOTOR_A CLOCKWISE MAX SPEED
      digitalWrite(in1, LOW);
      digitalWrite(in2, HIGH);
      //MOTOR_B COUNTERCLOCKWISE MAX SPEED
      digitalWrite(in3, HIGH);
      digitalWrite(in4, LOW);

    }
    if (motorMode1 == 2) {
      lcd.setCursor(5, 8);
      lcd.print("Left");
      //MOTOR_A COUNTERCLOCKWISE MAX SPEED
      digitalWrite(in1, HIGH);
      digitalWrite(in2, LOW);
      //MOTOR_B CLOCKWISE MAX SPEED
      digitalWrite(in3, LOW);
      digitalWrite(in4, HIGH);

    }
     if (Mode == 0 || motorMode1 == 0) {
      lcd.setCursor(5, 8);
      lcd.print("Stop");
      digitalWrite(in1, LOW);
      digitalWrite(in2, LOW);
      digitalWrite(in3, LOW);
      digitalWrite(in4, LOW);
    }
  }
```

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

body:
I hope I understood you correctly. The best way would be to tell you how you can use states to get the problem solved. But that would cost me too much time.

I decided to edit your program. I have no hardware to try it. So it is just an example to show you the idea. Perhaps it works as it is.

Please check the comments. If you are really interested in understanding to problem and the solution and things are unclear,  you (or others) can ask with comments below. And of cause, if you find an error, I would be happy to know about it and correct it. ;-)

    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    // These are the different movement states
    #define STATE_STOP 0
    #define STATE_LEFT 1
    #define STATE_RIGHT 2
    #define STATE_FORWARD 3
    #define STATE_BACKWARD 4

    // always use expressive names

    // The pin assignments
    //////////////////////////////////////////////

    // Analog
    int pinPotiSpeed = A0;

    // Motor A
    int pinEnA = 9;
    int pinInA1 = 8;
    int pinInA2 = 7;

    // Motor B
    int pinEnB = 3;
    int pinInB1 = 5;
    int pinInB2 = 4;

    // Buttons
    const int pinBtnDir = 10;
    const int pinBtnTurn = 11 ;

    int stateMotors = STATE_STOP;
    boolean flagBtnDirPressed = LOW;
    boolean flagBtnTurnPressed = LOW;

    int stateMotorsSpeed = 0;
    int speedPercent = map( stateMotorsSpeed, 0, 255, 0, 100 );

    LiquidCrystal_I2C lcd(0x27, 16, 2);

    // I have not the time to think a lot about this debouncing, but
    // I have a bad feeling. If the Arduino does not react on button presses
    // or the mode change to quick please let me know. I'll have a look on it, if
    // necessary. ;-)
    boolean readButtonAndDebounce(int btnPin, boolean lastState)
    {
        boolean actualState = digitalRead(btnPin);
        if (lastState != actualState)
        {
          delay(15);
          actualState = digitalRead(btnPin);
          return actualState;
        }

        // this return was missing in the original program
        return actualState;
    }

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

        pinMode(pinEnA, OUTPUT);
        pinMode(pinInA1, OUTPUT);
        pinMode(pinInA2, OUTPUT);

        pinMode(pinEnB, OUTPUT);
        pinMode(pinInB1, OUTPUT);
        pinMode(pinInB2, OUTPUT);

        pinMode(pinBtnDir, INPUT);
        pinMode(pinBtnTurn, INPUT);

        digitalWrite(pinInA1,LOW);
        digitalWrite(pinInA2,LOW);

        digitalWrite(pinInB1,LOW);
        digitalWrite(pinInB2,LOW);

        lcd.init();
        lcd.backlight();

        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("SPEED:");
        lcd.setCursor(0, 1);

        lcd.setCursor(7, 0);
        // convert 0-255 to 0%-100%
        lcd.print ("0 %");

        lcd.setCursor(0, 1);
        lcd.print("MOVE: Stop");
    }

    void loop()
    {
        stateMotorsSpeed = map( analogRead( pinPotiSpeed ), 0, 1023, 0, 255 );
        if ( stateMotorsSpeed < 8 ) stateMotorsSpeed = 0;
        speedPercent = map( stateMotorsSpeed, 0, 255, 0, 100 );

        boolean flagBtnDirPressedOld = flagBtnDirPressed;
        flagBtnDirPressed = readButtonAndDebounce( pinBtnDir, flagBtnDirPressed );

        boolean flagBtnTurnPressedOld = flagBtnTurnPressed;
        flagBtnTurnPressed = readButtonAndDebounce( pinBtnTurn, flagBtnTurnPressed );

        // this is a bit tricky, because I don't know if i understood the problem correctly.
        // My problem is, what happens if both button are pressed, I decided to give
        // the Direction button the precedence
        if ( flagBtnDirPressed && ! flagBtnDirPressedOld )
        {
          switch( stateMotors )
          {
            case STATE_STOP:
              stateMotors = STATE_FORWARD;
              break;

            case STATE_FORWARD:
              stateMotors = STATE_BACKWARD;
              break;

            case STATE_BACKWARD:
              stateMotors = STATE_STOP;
              break;

            default:
              // this happens if a state from the other button is active
              // The table does not include a rule what to do in this case.
              // Perhaps you could count button click modulo 3 for each button
              // and then you can switch to the correct state
              stateMotors = STATE_STOP;
          }

        }
        else if ( flagBtnTurnPressed && ! flagBtnTurnPressedOld )
        {
          // this is only entered if press state of the direction button has not changed
          switch( stateMotors )
          {
            case STATE_STOP:
              stateMotors = STATE_RIGHT;
              break;

            case STATE_RIGHT:
              stateMotors = STATE_LEFT;
              break;

            case STATE_LEFT:
              stateMotors = STATE_STOP;
              break;

            default:
              // this happens if a state from the other button is active
              stateMotors = STATE_STOP;
          }
        }

        controlMotorAndUpdateLcd();
    }

    void setMotorSignals( boolean sigA1 , boolean sigA2, boolean sigB1, boolean sigB2 )
    {
          //MOTOR_A
          digitalWrite(pinInA1, sigA1);
          digitalWrite(pinInA2, sigA2);

          //MOTOR_B
          digitalWrite(pinInB1, sigB1);
          digitalWrite(pinInB2, sigB2);
    }

    void controlMotorAndUpdateLcd()
    {
        lcd.clear();
        lcd.setCursor( 0, 0 );
        lcd.print( "SPEED:" );
        lcd.setCursor( 0, 1 );

        // potentiometer LCD
        lcd.setCursor( 7, 0 );
        lcd.print ( speedPercent );
        lcd.setCursor( 12, 0 );
        lcd.print ("%");

        analogWrite ( pinEnA, stateMotorsSpeed );
        analogWrite ( pinEnB, stateMotorsSpeed );

        // MotorLCD
        lcd.setCursor(0, 1);
        lcd.print("MOVE:");

        lcd.setCursor(5, 8);
        switch( stateMotors )
        {
          case STATE_STOP:
            lcd.print("Stop");
            setMotorSignals( LOW, LOW, LOW, LOW);
            break;

          case STATE_FORWARD:
            lcd.print("Forward");
            setMotorSignals( HIGH, LOW, HIGH, LOW);
            break;

          case STATE_BACKWARD:
            lcd.print("Reverse");
            setMotorSignals( LOW, HIGH, LOW, HIGH);
            break;

           case STATE_LEFT:
            lcd.print("Left");
            setMotorSignals( HIGH, LOW, LOW, HIGH);
            break;

          case STATE_RIGHT:
            lcd.print("Right");
            setMotorSignals( LOW, HIGH, HIGH, LOW);
            break;
        }
    }


message:
How to upload code to atmega32u4?

I recently created a pcb with the atmega32u4 to use it as a development board. The controller is connected to a micro usb port. Should I install the arduino bootloader instead of the deafult one? Or keep the default boot loader and find another way of flashing hex files? But bottom line what is the process to flash a hex file to the atmega32u4 via usb?

body:
Installing the Arduino bootloader would make it easier to upload you sketch from the Arduino IDE.

Installing the Arduino bootloader via DFU is probably the easiest method. Alternatively use ISP, but you'd need a programmer for that, or use a separate Arduino board with the ArduinoAsISP sketch running on it.


message:
Voltage, current measurement from solar panel using INA219 and ESP-12F

I recently started tinkering with ESP-12F thus I am a novice here. As a standard novice project, I am making a standalone weather station for my living room. I want to use solar panels to charge the batteries which power up the ESP-12F via USB. I am using ESP-12F as a controller and sending data to Rpi using MQTT.

I am using the following items:

1. ESP-12 F powered by USB
2. 2.5W 5V solar panel ( I want to connected two in parallel but for now using only one )
3. RPi 3B
4. INA219A to measure voltage and current generated by solar panel.
5. IN4001 diode as blocking
6. DHT11 sensor for temp and humidity values
7. Battery pack to charge 2 x 2500mAh batteries ( This is not done yet )

I am quite confused by the connections to INA219 and the data its providing. Thus, ESP-12F is still connected to independent usb power source and my goal is for now to understand and monitor the voltage and current generated by solar panel.

The INA219 Vcc, GND, SDA, SCL are connected to ESP-12F. I can read the values and observe them on serial monitor or mqtt panel.

***1. Below is the breadboard connection when INA219 Vin+ is NOT connected.***

[![INA219 Vin(+) Vin(-) not connected][1]][1]

The voltage measurement sent via MQTT is as below:

Ignore graph, I was pluging in/out Vin wire too many times thus very bizzare lines.

[![When INA219 Vin not connected][2]][2]

Current connections are as below:

Solar Panel (-) --> INA219 Vin (-) and breadboard to power LED

Solar Panel (+) --> Only to breadboard to power LED [INA219 Vin+ NOT connected]

ESP-12F 3V --> INA219 Vcc

ESP-12F GND --> INA219 GND

ESP-12F D1 --> INA219 SCL

ESP-12F D2 --> INA219 SDA

**ESP-12F is powered by separated USB power source**

Code using which the values are computed:
I have used Adafruit_INA219 library.

      shuntvoltage = ina219.getShuntVoltage_mV();
      busvoltage = ina219.getBusVoltage_V();
      current_mA = ina219.getCurrent_mA();
      power_mW = ina219.getPower_mW();
      loadvoltage = busvoltage + (shuntvoltage / 1000);

I dont understand the values sent by INA219 and have no idea how to interpret them. At this point, INA219 is connected to ESP-12F 3V power (Vcc) and GND. It does not have any Vin. Why there is a load voltage of -1.9 and current?

***2. When INA219 has Vin(+) and Vin(-) connected***

[![INA219 Vin is connected][3]][3]

When I connect the Vin+ and Vin- of INA219 I dont have any voltage/current on the breadboard. You can see the LED if OFF. I dont understand why this happens. The whole circuit on breadboard is redundant once I connect INA219 Vin pins to solar panel output pins.

Current connections are as below:

Solar Panel (-) --> INA219 Vin (-) and breadboard to power LED

Solar Panel (+) --> INA219 Vin(+) and breadboard to power LED

ESP-12F 3V --> INA219 Vcc

ESP-12F GND --> INA219 GND

ESP-12F D1 --> INA219 SCL

ESP-12F D2 --> INA219 SDA

**ESP-12F is powered by separated USB power source**

The voltage and current values at this point is shown below:

[![Voltage after INA219 Vin connected][4]][4]

The load voltage increases and the difference which is approx **2.1V**.
This delta voltage matches the voltage values from solar panel when measured by **multimeter** at this point. Thus, I would assume load voltage = current voltage generated by solar panel. But, current is unchanged and LED on breadboard if OFF the moment I connect INA219 Vin. Thus, I assume I have done wrong connections.

It will be great if you can point out my mistakes and make suggestions!

Thank you!

  [1]: https://i.stack.imgur.com/Cmt8u.jpg
  [2]: https://i.stack.imgur.com/MSO6j.png
  [3]: https://i.stack.imgur.com/DW0Oi.jpg
  [4]: https://i.stack.imgur.com/gvjQA.png

body:
You connected the V- and V+ probes of the INA module direct to the V- and V+ of the solar panel. That means you connect V+ with V- from solar panel  over a 0.1 Ohm resistor. That is like a short. The Solar panel gets overloaded and the voltage breaks down. Lucky you, the solar panel can not provide more current. If it could, then the shunt resistor would be grilled. RIP ;-). Try put the v+ and V- in series with the LED and LED_Resistor. e.g.

    Solar+ --> IN4001 --> INA+ |no connection| INA- --> LED --> R(LED) --> Solar-

That would make more sense. It'll show you how much current is drawn by the LED.

If you want to know how much current the panel can deliver, you would have to build a circuit with a potentiometer and measure the Voltage between V+ and V- of the Panel. You can also use the INA to mesasure the current through the potentiometer. Begin with a high resistancy, then turn the poti towards lower resistance and check when the voltage breaks down. The INA shows you the current. But be aware that, the max current depent on the amount of light the panel is exposed to and on the age of the panel itselves. So the values will change as these conditions change.


message:
MFRC522 Communication Failure

I'm using TTGO ESP32 and I've got an MFRC522 from AliExpress.

I've soldered connector pins to the board itself (both for ESP32 and MFRC522) and I'm using jumper wires female-to-female to connect themselves.

However, using an example sketch (DumpInfo) from miguelbalboa's RFID library, it says communication failure and scanning 3 different key cards or the key fob doesn't output anything.

    Firmware Version: 0xFF = (unknown)
    WARNING: Communication failure, is the MFRC522 properly connected?

This is my current pinout scheme:
```
(MFRC - ESP32)
SDA (SS) -> 33
SCK -> 25
MISO -> 27
MOSI -> 26
RST -> 32
```
And, of course also GND to G and 3.3V to 3.3V.

I've also tried SDA and SCK to connect to 21 and 22, respectively but no luck.
Though I have a DS1307 RTC module and microSD card adapter module and connected accordingly and it's working fine, by using Dupont wires, with the same method.

A manufacturer's defect or still I'm making an error somewhere?

You can see TTGO's ESP32 pinout diagram and also a picture of MFRC522 [here][1]  wired using jumper wires. I may be using (again) the wrong pins. The red LED on the MFRC522 is stable, though.

Thank you in advance.

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

body:
**UPDATE!**
The issue has been fixed, just after finding this [stackoverflow answer][1] by bat macumba. I'll leave the question here, in case someone stumbles into the same problem.

  [1]: https://stackoverflow.com/a/64998779/5847989


message:
Which Arduino-Board do I need?

I want to use a single Arduino board and link it to both the ANALOG CO2 GAS SENSOR (MG-811 SENSOR) and ANALOG PH SENSOR - METER KIT. I was wondering if the Uno Rev 3 had enough pins or do I have to go with the Mega.

body: Uno has enough pins. You'll probably need an analog pin for each measured quantity, and you might want a few digital pins to turn them on or off or make mode changes, if any. The next question is: what your project meant to do, and does the Uno have enough memory to accomplish it? You will probably go quite a way with an Uno before your project exceeds its capabilities, unless you have some unusually stringent requirements.


body: Nano board has a bunch of analog and digital pins. It does good and cheap. But for convenience UNO board is preferable for its large size easy handling and easy pin and wiring management.


message:
Arduino Pro Mini PWM issue

I want to create a small LED strip driver/controller with 2 channels (Cold/Warm white) using Arduino Pro Mini (5V/16MHz). I have connected the parts per the following diagram [![schematics][1]][1]
I have pins 5 and 6 setup as output, control them via analogWrite, and it all works great on Arduino UNO.

The problem comes with Arduino mini pro. When one channel is set to 255 and the other is 0, the LED strip does light only in one color, which is OK and when I swap the PWM channel's values, the other light color starts to shine. So far so good. When I set both to 0, the strip keeps on shining at about 30% (I don't have a scope, so I can't tell what the pwm signal is doing). Varying the channels' pwm in the range 0-255 does affect the light somehow but it never goes down to a complete off.

Looking at the arduino uno and pro mini I can't see anything obvious that should make them act differently from the hardware perspective so I'm guessing there's a problem in the libraries or perhaps my arduino pro mini (a [clone][2]) is somehow messed up.

Has anyone observed this kind of behavior in Arduino pro mini and has a solution for it?

**Edit**: Added some measurements per @Abel's request. I measured both DC and AC with and without the LED strip connected.

Connecting the LED strip really does mess things up, but WHY? UNO can handle it, but the pro mini can't! I thought mini was basically just shrunk down arduino uno (both have the same SMD version of MEGA328P), but apparently there are some differences.
[![DC/AC readings][3]][3]

  [1]: https://i.stack.imgur.com/xigpk.png
  [2]: https://www.aliexpress.com/item/32831029894.html
  [3]: https://i.stack.imgur.com/12Q5N.png

body: Nice clean design! Let's determine for sure what voltage it is outputting to the MOSFETs. Write a very simple sketch that cycles a pin every few seconds and measure the voltage. You should get ground and VCC. If it is less than 4.5 volts (guard band included) your FETs will give you problems as they will not be properly enhanced.  Here is why: The IRF520 is a Power Mosfet with 9.2A collector current and 100V breakdown voltage. The mosfet has a low gate threshold voltage of 4V and hence commonly used with microcontrollers like Arduino for switching high current loads. You may have to get a different MOSFET with a lower gate threshold. Note there is some variation in the devices so they will not all but the same but will meet the specification. The 10K pull down resistors is a great addition and guarantees your state during reset until it is set up.


body:
Thanks to comments I received from several people here I quadruple checked the wiring and eventualy found the problem. My recent Arduino Uno tests were done on a breadboard, but I had the Pro Mini prototype soldered on the prototyping board which has the holes connected in columns on the copper side. I made the cuts in all the necessary places ... but one! That one omission caused a short between pin 6 and the drain from the other channel's mosfet. The problem with these boards is that the parts are on one side and while flipping the board to the copper side, it is too easy to get lost in all the columns and miss something.
The morales of this story are: "Never be too certain about your wiring/soldering" and "Arduino is pretty resistent to my attempts to fry it :)".


body: Get a good digital O'scope. They are incredibly cheap these days, and pay for themselves pretty rapidly in reduced frustration and time spinning one's wheels.  I recently got a Hanmatek DOS1102 dual-channel 110MHz, and I haven't used my old analog Tek2236 since


message:
Arduino freezing frequently

I'm using an Arduino Nano for programing an automatic hand sanitizer that has a thermometer. But after running for some time the board freezes and only restarting can solve the issue. While checking the serial monitor it suddenly stops working.

The program includes reading distance from an ultrasonic sensor and temperature from an IR thermometer (distance and ambient temperature are read continuously and the serial monitor will constantly display values). At random when the temperature is read and is displayed on the OLED screen, the board freezes (board freezes only at this time) and restarting can make it work 1 more time and then freezes again.

Question 1
Is it something to do with the code or is it a hardware issue?

Question 2
Does a clone version of NANO cause such problem? (I'm using a clone version)

This is my code:

```c++
#include <Wire.h>
#include <Adafruit_MLX90614.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Adafruit_MLX90614 mlx = Adafruit_MLX90614();
Adafruit_SSD1306 display(-1);
//Adafruit_SSD1306 display(128, 64, &Wire, -1);

#define trigPin 12 // Trigger pin
#define echoPin 11 // echo pin

float roomTemp; // ambient temperature
float objectTemp, stemp; // object temperature

int readcount = 0;
float threshold= 3.5 ;

int maximumRange = 15; // Maximum range needed
int minimumRange = 3; // Minimum range needed
long duration, distance; // Duration used to calculate distance
int dtime;
unsigned long rememTime;

// motor coding
int set_time;
float distance_cm;
unsigned long ultra_time;
int set_cm = 20;
int motor = 2; // Output for Motor drive
int flag = 0;

void setup() {
  Serial.begin(9600);// initialize serial communication at 9600 bits per second:

  pinMode (trigPin, OUTPUT);
  pinMode (echoPin, INPUT);
  pinMode(motor, OUTPUT);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C) ;
  delay(200);
  display.clearDisplay();
  display.setTextColor(WHITE);
}

void loop() {
  // temperature sensor coding
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  //Calculate the distance (in cm) based on the speed of sound.
  distance= duration * 0.034/2;

  // reading object and ambient  temperature
  objectTemp = threshold + mlx.readObjectTempC() ;
  roomTemp = mlx.readAmbientTempC() ;

  // print to Serial port
  Serial.println("Object:" + String(objectTemp) + ", Ambient:" + String(roomTemp));
  Serial.println(distance);

  // display on OLED
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0, 25);
  display.print("Dis:" + String(distance) + "cm");
  display.setCursor(65, 25);
  display.print("Room:" + String(roomTemp).substring(0, 4) + "C");
  display.display();
  display.setTextSize(2);
  display.setCursor(0, 0);

  if (distance < minimumRange) {
    display.print("TOO CLOSE!");
  }
  if ((distance >= minimumRange) && (distance <= maximumRange)) {
    if (readcount == 5) { // after reading 5 consecutive time
      disptemp();
    } else {
      display.print("HOLD ON"); // when in range, ask user to hold position
      stemp = stemp + objectTemp;
      readcount++; // until approx. 5 x 200 ms = 1 sec
    }
  } else { // if user is out of range, reset calculation
    dtime = 100;
    readcount = 0;
    stemp = 0;
  }
  display.display();
  delay(dtime);
  Serial.println("count  :"+String(readcount));
}

void disptemp() {
  objectTemp = stemp / 5; // get the average reading of temp
  display.setTextSize(1);
  display.print("YOUR TEMP:");
  display.setTextSize(2);
  display.setCursor(60,5);
  display.print(String(objectTemp).substring(0, 4) + "C");
  display.display();
  readcount = 0;
  stemp = 0;
  if (objectTemp >= 38) {
    play_alert();
  } else {
    play_ok();
  }
  ultrasonicRead();
  dtime = 5000; // wait for 5 seconds
}

void play_ok() {  // play three sequential notes when object temperature is below 37.5C
  tone(3, 600, 1000);  // pin,frequency,duration
  delay(200);
  tone(3, 750, 500);
  delay(100);
  tone(3, 1000, 500);
  delay(200);
  noTone(3);
}

void play_alert() { // beep 3x when object temperature is >= 37.5C
  tone(3, 2000, 1000);
  delay(1000);
  tone(3, 3000, 1000);
  delay(1000);
  tone(3, 4000, 1000);
  delay(1000);
  noTone(3);
}

void ultrasonicRead() {
  if (distance < set_cm) {
    digitalWrite(motor, HIGH);
    Serial.println("Motor On");
    delay(500);
    digitalWrite(motor, LOW);
    Serial.println("motor off");
  }
}
```

body:
Any allocation / de- or re-allocation of memory[1] during run time, will cause the heap (the pool of memory from which those allocations are made) to expand until the heap and the stack grow toward each other enough to collide, at which point one overwrites part of the other with unpredictable results.

Strings are allocated from the heap. Strings that are built up little by little, as with:

`Serial.println("Object:" + String(objectTemp) + ", Ambient:" + String(roomTemp));`

 cause allocation several allocation / de-allocations.

As a simple-to-implement test, comment out the statements that use the String object and just print the raw data. Your program should run without crashes.

To recreate what you're now doing with Strings, I'd suggest using `snprintf()` to build up your output into a fixed-size output buffer, which can be a local character array (allocated on the stack and de-allocated when the containing function exits). This should be equally stable as the abbreviated experiment I proposed above.

[1] *Unless allocated memory is de-allocated most-recent-first. And even that assumes foreknowledge of the memory allocation algorithm in use, and so, is non-portable).

One way around this is to write one's own memory allocator/de-allocator, which has a pre-assigned pool of fixed-length blocks, one of which it supplies for *any* memory request of any size, so long as:

 1. there is a free block to allocate; and
 2. the requested size can fit in (the data-space of) a pre-assigned block.


body:
In addition to some of the above comments;

Your Nano may not support the watchdog. Please check [This post on the Arduino forum][1]

If you are looking for "There are many small programs..." I'll just post the functions I use for getting free memory, heap and stack information below.

<pre>
int freeRam()
{
 extern int __heap_start, *__brkval;
 int v;
 return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
}

uint8_t * stack()
{
  uint8_t * ptr;
  ptr = (uint8_t *)malloc(4);
  free(ptr);
  return ((uint8_t *)(SP));
}

uint8_t * heap()
{
       uint8_t * ptr;
       ptr = (uint8_t *)malloc(4);
       free(ptr);
       return(ptr);
}
</pre>

  [1]: https://forum.arduino.cc/index.php?topic=293300.0


message:
L293D motorshield with batteries doesn't power Arduino

Recently I came across a video about a guy building a remote Bluetooth-controlled Arduino car and I was quite amazed. So I decided I wanted to build it too. I have no Arduino or electronics experience at all other than being an IT professional.

So I bought the parts he used in the video (he advised a knockoff Arduino in the description).

After putting it all together the motors work through Bluetooth (yay!). But the issue is that the batteries connected to the motorshield don't give power to the Arduino at all (because the lights don't turn on).

When plugged in the laptop with the USB cable the Arduino gets powered and the motorshield light turns on just a bit, but not enough to make the motors and Bluetooth work.

So in short:

USB powered: Arduino works, motorshield light barely turns on, motors don't work, Bluetooth lights go on, but is not emitting a signal.

2x 18650 battery powered: motorshield light shines bright, Arduino doesn't work, Bluetooth lights don't flicker.

Both: everything works.

So for some reason, the batteries connected to the motorshield don't power the Arduino.

Video used:
https://youtu.be/Q36NbjPMV5k

Circuit diagram:
[![The motor shield is directly on the arduino][1]][1]

Knockoff arduino:
[![Arduino][2]][2]

L293D motor shield (I'm aware that the ground of the power isn't plugged in)

[![motorshield with bluetooth module connected to analog and +5 power and ground][3]][3]

Parts used:

 - Geekcreit UNO r3 ATmega16U2 AVR
 - L293D motor shield
 - Geekcreit HC-05 bluetooth
 - 4 TT motor
 - 2x 18650 3,7-4.2v 2200mah batteries

I really don't know what I did wrong, since I followed the video and did exactly what the person did. Maybe the batteries aren't powerful enough?

  [1]: https://i.stack.imgur.com/mT7G6.jpg
  [2]: https://i.stack.imgur.com/Voxmf.jpg
  [3]: https://i.stack.imgur.com/c9HAq.jpg

body: Nice project. The batteries are connected to the motor power which is correct but the motor shield does not output voltage to the 5V system.  Try connecting the batteries to the Vin on the board and all should work.


body:
The problem was that the 2 pins on which the jumper sits, the jumper or the board was broken (idk exactly). I might've caused that myself by turning on the batteries + powering it through usb at the same time.

I bought a new L293D board then made sure I didn't connect usb power to the arduino while the L293D was sitting on top of it. I uploaded the code, then disconnected the usb, put the L293D on top, powered it all and it works like a charm!


message:
Using Keyboard library for ISO-UK layout

I am creating a keyboard and the PC I use it with is configured for UK so the keyboard layout it expects is this

[![UK keyboard with UK - Us differences highlighted][1]][1]

I've highlighted the ISO-UK vs ANSI-US differences but the only key I am having real problems with is the backslash key.

My physical layout is actually this (ortholinear "Planck") but it's essentially the same except with two logical layers and variation in positioning.

[![Planck style keyboard][2]][2]

The above is a fully functional UK-layout keyboard with the exception of the "\\" key.

The sketch I am using is too large and distracting to post here but the following test sketch

~~~
#include "Keyboard.h"

byte keylist[] = { '`', '2', '3', '\'', '#', '\\' };

void setup() {
  Keyboard.begin();
  delay(1000);

  // unshifted
  for (byte i = 0; i < sizeof(keylist); i++) {
    Keyboard.press(keylist[i]);      delay(100);
    Keyboard.release(keylist[i]);    delay(100);
  }

  Keyboard.press(KEY_RETURN);
  Keyboard.releaseAll();

  // shifted
  for (byte i = 0; i < sizeof(keylist); i++) {
    Keyboard.press(KEY_LEFT_SHIFT);
    Keyboard.press(keylist[i]);
    delay(100);
    Keyboard.releaseAll();
    delay(100);
  }
}

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

Creates this output (in a Notepad window)

~~~
`23'£#
¬"£@£~
~~~

I did try switching focus to a keyboard diagnostic tool - KeyHitter by Elite Keyboards which showed different results

~~~
12:31.0675 ` (0xDF, BIOS 0x29) DOWN
12:31.0771 ` (0xDF, BIOS 0x29) UP -> 100ms
12:32.0772 2 (0x32, BIOS 0x03) DOWN
12:32.0871 2 (0x32, BIOS 0x03) UP -> 100ms
12:33.0872 3 (0x33, BIOS 0x04) DOWN
12:33.0972 3 (0x33, BIOS 0x04) UP -> 100ms
12:34.0972 ' (0xC0, BIOS 0x28) DOWN
12:35.0072 ' (0xC0, BIOS 0x28) UP -> 100ms
12:36.0072 LShift (0x10, BIOS 0x2A) DOWN
12:36.0082 3 (0x33, BIOS 0x04) DOWN
12:36.0172 LShift (0x10, BIOS 0x2A) UP -> 100ms
12:36.0182 3 (0x33, BIOS 0x04) UP -> 100ms
12:37.0172 \ (0xDE, BIOS 0x2B) DOWN
12:37.0272 \ (0xDE, BIOS 0x2B) UP -> 100ms
12:38.0271 Enter (0x0D, BIOS 0x1C) DOWN
12:38.0273 Enter (0x0D, BIOS 0x1C) UP -> 2ms
~~~
...

So the Arduino `Keyboard` library translates `'#'` into `shift`+`3` which is unhelpful for UK users but I'm mystified why Keyhitter sees that `'\\'` produces the expected `\` but other programs see it producing `#`! I guess Keyhitter intercepts keystrokes at a lower level than normal applications - for example it correctly shows `Win` being pressed but prevents Windows opening a start-menu.

The result in Notepad is typical of the effect produced in normal applications. So that's probably more relevant.

I can work around the `'#'` producing a `shift`+`3` since `'\\'` produces `#` but how then do I generate a `\`?

  [1]: https://i.stack.imgur.com/LcYFZ.png
  [2]: https://i.stack.imgur.com/FI1sI.jpg

body:
The USB keyboard protocol has no concept of characters. It doesn't know and doesn't care what character a key represents. Instead each code represents the *location* of the key on the keyboard, and it's down to the software on the computer to map those locations into characters through its own keyboard map.

So the Arduino has to do the opposite when you want to "print" text through the keyboard - convert that text into the locations of the keys on the keyboard. And it does that through the `_asciimap` array in `Keyboard.cpp`.

To use any other keyboard layout than US you need to modify that map so that each ASCII value points to the correct location for that character as defined in your computer's keyboard map.

You can find the list of keyboard location codes (named in this document after the US keycap decals) [here](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) (page 53) which you can then use to map any changes.

For example in `_asciimap` a double quote is listed as:

```c++
     0x34|SHIFT,    // "
```

Which maps to `Keyboard ' and "` in USB. But for UK you want that to be shift-2, which is `Keyboard 2 and @` in a US layout.  That entry is hex 1F.

So changing the quote to be a shifted 0x1F should give you the quote you desire:

```c++
    0x1F|SHIFT, // "
```

You would need to do the same to all other characters that need re-mapping (including \). Some may take a little trial and error to work out what the equivalent key on a UK keyboard is, since some keys are in physically different locations (most notably there is no key to the left of Z on a US keyboard, but there is an extra one to the right of ]).

Unfortunately the Arduino Keyboard library doesn't provide a way for a user to give their own keyboard map. Instead you have to modify the source code of the library itself.


body:
For completeness I am posting this answer. You can produce a UK backslash keystroke event by using something like

    #define KEY_BSLASH 0xEC

This was found rather more empirically than analytically so is not an especially informative result, but it might be of some use to others creating non-ANSI keyboard layouts using Arduinos.


message:
Can arduino nano drive two circuit

I am building a robot snake with a bunch of servos and ov7670. As I see, ov7670 operate with 3.3v and servos needs 5v. I will use Lipo battery for servos for this I need to connect ground pin of arduino and input of battery. But For ov7670, I already connect the ground pin of arduino. Can I connect ground with a jumper to another breadboard to connect with lipo battery and servos or I need two arduino nanos?

body: You can use a common ground in fact it's the normal thing to do with external circuits such as relays, servos etc


message:
I have made a Nano send 4 pot values to an Uno please help with code

Happy New Year!

So I have made a Nano send 4 pot values to an Arduino Uno over serial but I have a problem: I don't know how to separate these values. Here's the code:

Master:
```c++
    int Pot = A0;
    int Pot2 = A1;
    int Pot3 = A2;
    int Pot4 = A3;

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

    void loop() {
      int Value = analogRead(Pot);
      int Value2 = analogRead(Pot2);
      int Value3 = analogRead(Pot3);
      int Value4 = analogRead(Pot4);
      Serial.write(Value); //Write the serial data
      Serial.write(Value2); //Write the serial data
      Serial.write(Value3); //Write the serial data
      Serial.write(Value4); //Write the serial data
      delay(150);
    }
```

Slave:

```c++
    int incomingByte; // for incoming serial data

    void setup() {
      Serial.begin(115200); // opens serial port, sets data rate to 9600 bps
    }

    void loop() {
      // send data only when you receive data:
      if (Serial.available() > 0) {
        // read the incoming byte:
        incomingByte = Serial.read();

        // say what you got:
        Serial.print("I received: ");
        Serial.println(incomingByte, DEC);
      }
    }
```

And a bit from the serial logs:
<pre>
    I received: 255
    I received: 247
    I received: 11
    I received: 0
</pre>

It updates and sends these four values for the four pots, it can read them but they are together, and it sometimes also kind of lags if I can say it like that; it sometimes takes longer to update but then it goes to normal again.

Thanks!

body:
If your goal is to "talk" to a computer vs. a human, then a format that can be parsed easily is better than one that is easy to read.

For example, you have:

    I received: 255
    I received: 247
    I received: 11
    I received: 0

While this could be parsed by your Uno, it will be a lot simpler if you send the data something like:

    255|247|11|0

Now you can use a "C" string parsing function like strtok() to parse on the "|" character.  Of course there are many other ways to do this as well but this is one possible solution to your question.