message:
Device Signature Error uploading to ATMEGA168PA

I keep getting a device signature error and can't program my Atmega168pa chip.

I'm using the board from: https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json

I've pasted the error below from an attempt to upload a new sketch:

```
void setup() {
  // put your setup code here, to run once:

}

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

}
```

```
Arduino: 1.8.13 (Linux), Board: "ATmega168, No bootloader, EEPROM retained, 168P / 168PA, BOD disabled, LTO Disabled, Internal 8 MHz"

Sketch uses 412 bytes (2%) of program storage space. Maximum is 16384 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 1015 bytes for local variables. Maximum is 1024 bytes.
/home/rick/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude -C/home/rick/.arduino15/packages/MiniCore/hardware/avr/2.0.7/avrdude.conf -v -patmega168p -cstk500v1 -P/dev/ttyUSB0 -b19200 -Uflash:w:/tmp/arduino_build_51999/sketch_nov15a.ino.with_bootloader.hex:i

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

         System wide configuration file is "/home/rick/.arduino15/packages/MiniCore/hardware/avr/2.0.7/avrdude.conf"
         User configuration file is "/home/rick/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

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

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

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000 (retrying)

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000 (retrying)

An error occurred while uploading the sketch
Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.

avrdude done.  Thank you.

```
Pictures of my wiring:

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

I have:
* D13 -> (PCINT0/CLKO/ICP1) PB0 [Pin 14]
* D12 -> PB4 (MISO/PCINT4) [Pin 18]
* D11 -> PB3 (MOSI/OC2A/PCINT3) [Pin 17]
* D10 -> (PCINT14/RESET) PC6 [ Pin 1]

I have a 100n capacitor between vcc & gnd and between avcc & gnd. I have a 10 uF capacitor between “Reset” and “Ground” pins on the Arduino. Power is fed via the 5v pin from Arduinio.

I know this nano works (I programmed an ATTiny84 with it before and after my attempts on the Atmega). I've checked pwr & gnd. I'm not 100% sure of the wiring. These chips are new from China so I'm not sure if they are configured for internal or external clock, although I believe they are set to internal by default.

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

body:
The ISP pins are usually all next to each other. The connection D13 to PB0 is unlikely to be correct. It should be connected to PB5.

You can check your connections here: https://www.arduino.cc/en/Tutorial/BuiltInExamples/ArduinoToBreadboard (there is UNO, but pin numbering/wiring is exactly the same as for Nano)

Another possible mistake is burning wrong fuses (with bootloader) for external xtal setting (also mentioned in the article)


sender: user

message:
Infamous white squares for LCD display

I would like to know what I've done wrong. I configured my circuit using the "Hello world tutorial. I got the infamous white square pattern

* D7 to pin 2
* D6 to pin 3
* D5 to pin 4
* D4 to pin 5
* E to pin 11

My code:

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

    // include the library code:
    #include <LiquidCrystal.h>

    //LiquidCrystal lcd(RS, E, D4, D5, D6, D7);
    LiquidCrystal lcd(2, 3, 4, 5, 11, 12);      // put your pin numbers here

    void setup() {
      // set up the LCD's number of columns and rows:
      lcd.begin(16, 2);
      // Print a message to the LCD.
      lcd.print("hello, world!");
    }

    void loop() {
      // set the cursor to column 0, line 1
      // (note: line 1 is the second row, since counting begins with 0):
      lcd.setCursor(0, 0);
      // print the number of seconds since reset:
      lcd.print("hello, world!");
    }

[![the infamous squares][1]][1]

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

sender: assistant

body:
Your picture does not give a clear view of the connections between the Arduino Uno and the LCD module.  However, if we are to follow your description of your connections ...

>     D7 to pin 2
>     D6 to pin 3
>     D5 to pin 4
>     D4 to pin 5
>     E to pin 11

... and we assume D7, D6, D5 & D4 are pins on the LCD, then we see that the code is incorrect ...

    LiquidCrystal lcd(2, 3, 4, 5, 11, 12);      // put your pin numbers here

... given the [LiquidCrystal description here][1] of the syntax of the overloaded (means there are more than one pattern to the passed parameters to the identically named constructor) class ...

    Syntax

    LiquidCrystal(rs, enable, d4, d5, d6, d7)
    LiquidCrystal(rs, rw, enable, d4, d5, d6, d7)
    LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7)
    LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)

... instead, try:

    LiquidCrystal lcd(?, 11, 5, 4, 3, 2);      // put your pin numbers here

... as you didn't tell us how you connected the RS line I have left that value above as a "?".  So this will not compile until you fill in the missing information.

It should be added, based on what can be seen in the picture, that a connection has been made to the LCD's RS & RW pins and no connection has been made to the LCD's E (enable) pin.  But in all the constructor's overloaded versions, there is always an E (enable) pin.  Please take a closer look at your design to determine if this is a problem.

  [1]: https://www.arduino.cc/en/Reference/LiquidCrystalConstructor


body:
In my case the issue was trivial: the LCD pins were not making good contact with the breadboard.

By firmly inserting them and reuploading you should be able to see "hello world!"


message:
Dimming this ~30V led with PWM, what do I need?

I have a street lamp with a led and simple driver in it, I don't know the exact led voltage but the driver (image attached) says `27-36V DC output`, `MODEL: 50W`.

Is there a part I could place between this driver and the led, so I can control dimming by Arduino via PWM ?

**The led driver specs** (large image below) says: `INPUT; AC 85-285V` and `OUTPUT: DC 27-36V 1500mA`, `MODEL: 50W`

I thought it would work to put this "*PWM power module*" between the driver output and the led, but (I tested months ago) I remember it started to blink, I think only when decreasing power but not on full power (controlled by PWM with arduino).

- Should it work with this module or I am trying something very wrong ?
- Are there any other parts that should work for sure in this situation ?

**The specs on the PWM module** are these:

```
Voltage: 5 V - 36 V DC;
Power: 400 W;
Current: 30 A;
PWM Voltage: 3.3-20V;
PWM frequency: 0-20kHz ;
```

[![PWM power module][1]][1]

[![Led driver][2]][2]

  [1]: https://i.stack.imgur.com/h2nJe.jpg
  [2]: https://i.stack.imgur.com/KLkNr.jpg

body:
It will not be possible for you to PWM dim your LED with that LED driver (power supply).

That is a *constant current* driver with under/over-voltage protection. It delivers a specific amount of current (1.5A) and varies the voltage to allow that to happen.

If the voltage rises too high or falls too low then there must be a fault, so it shuts the power off. This is usually because there is either a short (LEDs tend to "fail short") or an open circuit. The former causes the voltage to drop too low and the latter for it to be too high.

When you insert PWM control you alternate between driving the LEDs and an open circuit. If that open circuit persists too long (low duty cycles) the driver will shut off.

You will need to replace the LED driver (the power supply) with one which includes PWM control internally to it.


body:
If you buy a 30V current-limiting power supply set to limit the current to 1.5A, you should be able to use it to power your LED light through a high power logic level MOSFET. You could control the MOSFET with a PWM signal from an Arduino and use that to vary the brightness of your light. With a little googling I found an adjustable power supply with an output ranging from 0-30V and a power rating of 0 - 1.5A https://www.canakit.com/r182-0-30v-0-1.5a-adjustable-regulated-power-supply.html

It does not look to be weather-proofed like the one you show however, and you'd need to make sure the heat-sink was able to dump enough heat to prevent it from overheating.


message:
How to override automatic control in Blynk app?

I am a beginner to Blynk, and have successfully built a simple water temperature control project. It consists of an ESP32, a plug-in water heater, and an AC relay board. The ESP32 controls the relay board, while the water heater is plugged into the relay board.

The code I have will turn on the relay once the water temperature dips below 16°C. On the Blynk app, I want to add a button that allows the user to manually control the operation of the relay. But I am stumped as to how to code it. Since I have programmed the ESP to turn off the relay once the temperature is above 16°C, if I try to switch it on manually at 20°C, for example, the relay will not remain on, because the `if` statement will fail.

How can I code this to have a manual override capability, so that once the user turns on the button inside the Blynk app, the ESP will allow manual control of the digital pin (delay trigger), and will only revert back to automatic temperature control mode once the button is turned off?

```c++
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 14        //data wire connected to pin 14
#define RELAY_PIN 23           //IoT relay connected to pin 23

OneWire oneWire(ONE_WIRE_BUS); //instance to communicate with any OneWire device

DallasTemperature sensor(&oneWire); //pass reference to Dallas Temperature object

BlynkTimer timer;       //create Blynk timer object for timed intervals
float waterTemp;        //temperature from DS18B20 in C

char auth[] = "xxxxxxx";
char ssid[] = "xxxxxxx";
char pass[] = "xxxxxxx";

void setup() {
  Serial.begin(9600);
  sensor.begin();
  Blynk.begin(auth, ssid, pass);
  sensor.setResolution(9);           //default is 9 bit
  timer.setInterval(1000L, sendTemp);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);
}

void sendTemp() {
  sensor.requestTemperatures();      //must request reading first
  waterTemp = sensor.getTempCByIndex(0);
  if (waterTemp != DEVICE_DISCONNECTED_C) {
    Serial.print("Temp = ");
    Serial.println(waterTemp);
    Blynk.virtualWrite(V1, waterTemp);
    if (waterTemp < 16) {
      digitalWrite(RELAY_PIN, HIGH); //turn on IoT relay
    } else {
      digitalWrite(RELAY_PIN, LOW);  //turn off IoT relay
    }
  } else {
    Serial.println("Error: Could not read temperature data");
    Blynk.notify("Error: Could not read temperature data");
    digitalWrite(RELAY_PIN, LOW);
  }
}

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

body:
Roughly like this:

Make a global variable `int mode`;

Read a Blynk app 3-way switch in the `loop()`;

Set `mode` to the 1, 2, or 3 received from the Blynk app (for ON/OFF/AUTO);

Replace this bit of code:
```c++
if (waterTemp < 16) {
  digitalWrite(RELAY_PIN, HIGH); //turn on IoT relay
} else {
  digitalWrite(RELAY_PIN, LOW);  //turn off IoT relay
}
```
with
```c++
if (mode == 1) {
  digitalWrite(RELAY_PIN, HIGH);
} else if (mode = 2) {
  digitalWrite(RELAY_PIN, LOW);
} else {
  if (waterTemp < 16) {
    digitalWrite(RELAY_PIN, HIGH); //turn on IoT relay
  } else {
    digitalWrite(RELAY_PIN, LOW);  //turn off IoT relay
  }
}
```

You will still have to decide what happens when `DEVICE_DISCONNECTED_C == TRUE`, etc, but that is the gist of it.


message:
Form a signal from an array of bits

I need to reproduce with a digital pin of an Arduino such a key in the form of a sequence of 1's and 0's, where a one takes 2 ms high and 2 ms low, and a zero takes 1 ms high and 1 ms low.
[![enter image description here][1]][1]

      int key = 0b101100001111;

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

    void loop()
    {
      for (int n = 0; n < 12; n++)
      {
        if (bitRead(key, n) == 1) //execute if bit value == 1
        {
          sendSignal(2000);
        }

        else //execute if bit value == 0
        {
          sendSignal(1000);
        }
      }
    }

    void sendSignal(int duration)
    {
      digitalWrite(13, HIGH);
      delayMicroseconds(duration);
      digitalWrite(13, LOW);
      delayMicroseconds(duration);
    }

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

This sketch really works! I figured out what my problem is: I actually need a longer key (64 bits). I am using long type: long key = 0b1000011110001101111100011111001010110001101101111011011100110100; but long only allows 32 bits. What do you recommend to do? Maybe you need to arrange it as an array? I think you can make it easier somehow. thank you

body:
You should make

    byte key = 0b101100001111;

global, i.e. put it BEFORE the `setup` function and not within it.

Also, a byte only can contain 8 bits, you need 12, so make it an int (thanks to ocrdu, see comment below):

    int key = 0b101100001111;

If you need more bits, you can use uint32_t or uint64_t, and count further than the current 12.

Now `key` is a local variable which is removed after exiting the `setup` function.

I'm not sure where 'key' comes from in:

    switch (bitRead(key, n)) {

Do you get a compiler error, or did you ALSO define a global variable named `key` ?
Anyway, if you make `key` global it will fix either way.

A few other remarks:

- Try to align your parenthesis, like the 3 }'s at the end, indent them properly, this makes your code much more readable
- Instead of the `switch`/`case`, you could use an `if` statement in this case, as the re are only (and always) two possible values (0 and 1):

Thus:

     if(bitRead(key, n) == 0)
     {
         ...
     }
     else // 1
     {
         ...
     }
- Try also comments to write in English instead of Greek, you never know when your comments will be read by non Greek readers (like now).

- You can make the following fragment shorter and less duplicated:

Original:

    digitalWrite(13, HIGH);
    delayMicroseconds(1000);
    digitalWrite(13, LOW);
    delayMicroseconds(1000);

If you wrap this in a function:

    void sendSignal(int duration)
    {
        digitalWrite(13, HIGH);
        delayMicroseconds(duration);
        digitalWrite(13, LOW);
        delayMicroseconds(duration);
    }

Then you can write a 1 by calling:

    sendSignal(2000);

and a 0 by calling:

    sendSignal(1000);


body:
If you modify the code slightly, you can use an array of characters of any length, so need to worry about digital word length.

Here's a modified version of your program that does this.

Note that I also took the liberty of replacing the 'magic number' 13 with LED_PIN, and the 'magic number' 12 with KEY_LEN.  I would suggest you do the same with your pulsewidth values - maybe something like PULSE_WIDTH_ONE_USEC and PULSE_WIDTH_ZERO_USEC?  That way someone else (or you 3 months later) looking at your code can easily see what the values are intended to do

    const int KEY_LEN = 62;
    const char key[KEY_LEN] = { "10110110110101111001011010110100101011011100110110101101101100" };
    const int LED_PIN = 13;

    //int key = 0b101100001111;
    void setup()
    {
      Serial.begin(115200);
      pinMode(13, OUTPUT);
    }

    void loop()
    {
      for (int n = 0; n < KEY_LEN; n++)
      {
        if (key[n]== '1') //execute if bit value == 1
        {
          Serial.print("1");
          sendSignal(200);
        }

        else if (key[n] == '0')//execute if bit value == 0
        {
          Serial.print("0");
          sendSignal(100);
        }
        else
        {
          Serial.print("x");
        }
      }
      Serial.println();
    }

    void sendSignal(int duration)
    {
      digitalWrite(LED_PIN, HIGH);
      //delayMicroseconds(duration);
      delay(duration);
      digitalWrite(LED_PIN, LOW);
      //delayMicroseconds(duration);
      delay(duration);
    }


message:
Looking for information and/or how to connect the RF433Mhz module (WL101-341/WL102-341)

I'm trying to find information about this 433MHz RF module: [QIACHIP][1]

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

Apparently it can be connected to an Arduino with the [RadioHead][3] library, but I don't have diagrams of how to connect them togheter in order to send/recieve data, becasue the module have 4 pins (Vcc, Gnd, Dat and En). I guess Dat pin should be connected to any Arduino pin, but as I only have one module I dont wanna risk it. I have no previous experience with RF modules :-(

I have found some [Youtbe][4] video, but the language of the video is in russian, and I don't know that langauge (I even ask the owner of the chanel for subtitles).

Please, if anyone have worker whit this module before, share:

 - How to connect the module with an arduino?
 - A simple example of how to send a simple word (let's say: "Hello") from the transmitter to the reciever

  [1]: http://www.ozeki.hu/p_6034-information-about-433-mhz-modules.html
  [2]: https://i.stack.imgur.com/Uacb7.jpg
  [3]: http://www.airspayce.com/mikem/arduino/RadioHead/
  [4]: https://www.youtube.com/watch?v=BmfmnfHpapo

body:
You're right not to just go ahead and wire things up. There's a couple of nuances that you need to take into account.

**Transmitter**

* Ignore the EN pin - that does nothing on that module
* The transmitter is 1 3.3V device. You need to power it from the 3.3V pin and use logic level (5V -> 3.3V) translation on the Data pin

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/fYPRP.png)

<!-- End schematic -->

**Receiver**

The receiver is much simpler as it is a 5V device:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/Z8lzX.png)

<!-- End schematic -->

On the Arduino it shouldn't matter what IO pin you use, the Radiohead library should work fine with any of them.  These modules are pretty dumb - you raise DAT high on the TX and DO on the RX goes HIGH. Very simple.


message:
Arduino "Maximum Power point tracker" (MPPT) Problem

I need an IV curve for a solar panel. As far I know, solar-panel and Diode IV curve pretty much the same. Here, I am using diodes(6A10-1) as a solar-panel. Where each Diode voltage drops 0.6volt. I provide 4.8v across the diodes from a power supply and limited the current at 1amp of the power supply for acting like a solar panel.
The number of diodes is 8 for a 4.8V drop. A 1-ohm resistor for measuring the current. I am using Arduino to measure the value of current and voltage by varies the MOSFET(IRF540) gate voltage. A low pass filter is connected between D2 and Mosfet Gate. A0 for measuring the solar voltage and Current, Id=A0-A1.
But Arduino gives incorrect values of A1 and current, Id, and sometimes negative values with respect to a multimeter.

[![circuit][1]

```c++
const int V1 = A0;
const int V2 = A1;
float SolarVolt = 0.0;
float V1_VOLT = 0.0;
float V2_VOLT = 0.0;
float Id  = 0.0;
int V1_value = 0;
int V2_value = 0;
double gateVoltage=150; //For Gate volt
double mstep=5.1;
int GatePin=2;

void setup() {
  pinMode(GatePin,OUTPUT);
  Serial.begin(9600);
  pinMode(V1,INPUT);
  pinMode(V2,INPUT);
}

void loop() {
  analogWrite(GatePin,gateVoltage);
  gateVoltage=gateVoltage+mstep;
  Serial.print("GateVolt = ");
  Serial.print(gateVoltage);
  Serial.print("    ");
  if (gateVoltage <= 0) {
    mstep = 1;
  } else if (gateVoltage>=255){
    gateVoltage = 255;
    mstep = -1;
    delay(50);
  }

  V1_value = analogRead(V1);
  V1_VOLT = (V1_value * 5.0) / 1024.0;

  Serial.print("V1_VOLT= ");
  Serial.print(V1_VOLT);
  Serial.print("    ");

  V2_value = analogRead(V2); // for Id1
  V2_VOLT= (V2_value * 5.0) / 1024.0;

  Serial.print("V2_VOLT= ");
  Serial.print(V2_VOLT);
  Serial.print("    ");

  Id=V1_VOLT-V2_VOLT;

  Serial.print("ID= ");
  Serial.print(Id);
  Serial.println();

  delay(1000);
}
```

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

body: Your current signal will also show PWM, so you will need to filter that before measuring.  It would be much simpler if you could rearrange your circuit to put the sense resistor on the ground side of the MOSFET, since then you can use a simple RC filter and a single A0 measurement.   Also, you wouldn't have to worry about the no-load voltage from the solar panel (when the MOSFET is off) going above the 5V limit of the A0 pin.


message:
How to increase the frequency of data transmission of SIM900A GSM Module connected to Arduino Uno?

I have a SIM900A GSM Module hooked onto an Arduino Uno board. The Arduino is connected to a MPU6050 Accelerometer which is constantly monitoring data at 1 second interval. I am trying to transmit the gathered data to ThingSpeak server. I have successfully established the connection with the server and the transmission is occurring. However, the interval between two transmitted readings are very large, varying between 1 to 3 minutes. That interval is too large to use the data. Is there any way I can enhance the transmission frequency so that the data points are close enough? At least to a few seconds distance?

body:
There does not appear to be a complete description of how ThingSpeak throttling works.  However there is this text on the [Thing Speak License FAQ web page][1]:

> As a reference, one unit provides the ability for a device sending
> data to ThingSpeak at once per second to send data to ThingSpeak for
> one year.

Assuming your code is working as expected and the ThingSpeak throttling is to suspend your service for 15 minutes, it may be that you are sending data faster than ThingSpeak will allow.

To test this, try to send messages slower than once per second.

  [1]: https://thingspeak.com/pages/license_faq


message:
Problem with L293D controlled motors using IR pilot remote

I have a problem with my line follower:
=

My robot has 4 wheels with DC motors connected to L293D shield (Arduino Uno).

The robot is a line follower controlled by IR pilot with an IR receiver, it has 4 IR sensors(two in the back and two in the front). The robot goes forward if none of sensors sees the black line.

When I click > button, the robot should use only the sensors in the front and follow the line until the end of the road made of black tape, and when I click < it should use only the sensors on the back and run CarBackward() (go backwards).

The robot should only stop working if I click 0 button on the pilot (CarStop() function). So without the IR remote code the robot drives normally, but when I add the code for the pilot only two right motors work, they spin forward and nothing else happens no matter if one, two or none sensors see the line.

Everything is powered by two 18650 batteries.

The IR pilot receiver is connected to A0 pin on the shield - pin 14 (which can be used as digital).

```c++
#include <IRremote.h>
#include <AFMotor.h>

int IRsensorPin = 14;
AF_DCMotor motor1(1);
AF_DCMotor motor2(2);
AF_DCMotor motor3(3);
AF_DCMotor motor4(4);

IRrecv irrecv(IRsensorPin);
unsigned long key_value = 0;
decode_results results;

const int back_left_sensor_pin = A0;
const int left_sensor_pin = A1;
const int back_right_sensor_pin = A2;
const int right_sensor_pin = A3;
int left_sensor_state;
int back_left_sensor_state;
int right_sensor_state;
int back_right_sensor_state;

void CarBackward()
{
  if (back_left_sensor_state > 500 && back_right_sensor_state < 500)
  {
    Serial.println("turn right");
    motor1.run(BACKWARD); // LP
    motor2.run(RELEASE); // LT
    motor3.run(BACKWARD); // PT
    motor4.run(FORWARD); // PP

    motor1.setSpeed(160);
    motor2.setSpeed(130);
    motor4.setSpeed(180);
    delay(20);
  }

  if (back_left_sensor_state < 500 && back_right_sensor_state > 500)
  {
    Serial.println("turn left");
    motor1.run(FORWARD); // LP
    motor2.run(BACKWARD); // LT
    motor3.run(RELEASE); // PT
    motor4.run(BACKWARD); // PP

    motor1.setSpeed(180);
    motor4.setSpeed(160);
    motor3.setSpeed(130);
    delay(20);
  }

  if (back_left_sensor_state < 500 && back_right_sensor_state < 500)
  {
    Serial.println("forward");
    motor1.run(BACKWARD); // LP
    motor2.run(BACKWARD); // LT
    motor3.run(BACKWARD); // PT
    motor4.run(BACKWARD); // PP

    motor1.setSpeed(110);
    motor2.setSpeed(110);
    motor3.setSpeed(110);
    motor4.setSpeed(110);
    delay(20);
  }

  if (back_left_sensor_state > 500 && back_right_sensor_state > 500)
  {
    Serial.println("stop");
    motor1.setSpeed(0);
    motor2.setSpeed(0);
    motor3.setSpeed(0);
    motor4.setSpeed(0);
    delay(20);
  }
}

void CarForward()
{
  if (right_sensor_state > 500 && left_sensor_state < 500)
  {
    Serial.println("turn right");
    motor1.run(FORWARD); // LP
    motor2.run(FORWARD); // LT
    motor3.run(RELEASE); // PT
    motor4.run(BACKWARD); // PP

    motor1.setSpeed(160);
    motor2.setSpeed(130);
    motor4.setSpeed(180);
    delay(20);
  }

  if (right_sensor_state < 500 && left_sensor_state > 500)
  {
    Serial.println("turn left");
    motor1.run(BACKWARD); // LP
    motor2.run(RELEASE); // LT
    motor3.run(FORWARD); // PT
    motor4.run(FORWARD); // PP

    motor1.setSpeed(180);
    motor4.setSpeed(160);
    motor3.setSpeed(130);
    delay(20);
  }

  if (right_sensor_state < 500 && left_sensor_state < 500)
  {
    Serial.println("forward");
    motor1.run(FORWARD); // LP
    motor2.run(FORWARD); // LT
    motor3.run(FORWARD); // PT
    motor4.run(FORWARD); // PP

    motor1.setSpeed(110);
    motor2.setSpeed(110);
    motor3.setSpeed(110);
    motor4.setSpeed(110);
    delay(20);
  }

  if (right_sensor_state > 500 && left_sensor_state > 500)
  {
    Serial.println("stop");
    motor1.setSpeed(0);
    motor2.setSpeed(0);
    motor3.setSpeed(0);
    motor4.setSpeed(0);
    delay(20);
  }
}

void CarStop()
{
  Serial.println("stop");
  motor1.run(RELEASE);
  motor2.run(RELEASE);
  motor3.run(RELEASE);
  motor4.run(RELEASE);
  delay(200);
}

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);
  irrecv.enableIRIn();
  irrecv.blink13(true);
  motor1.setSpeed(130);
  motor2.setSpeed(130);
  motor3.setSpeed(130);
  motor4.setSpeed(130);
}

void loop()
{
  left_sensor_state = analogRead(left_sensor_pin);
  right_sensor_state = analogRead(right_sensor_pin);
  back_left_sensor_state = analogRead(back_left_sensor_pin);
  back_right_sensor_state = analogRead(back_right_sensor_pin);

  static int wariat_na_lini = 1;  // if = 1 follow the line and go forward, if -1 go backwards

  if (irrecv.decode(&results)) // have we received an IR signal?
  {
    if (results.value == 0xFFFFFFFF) // if the value is equal to 0xFFFFFFFF
    {
      results.value = key_value; // set the value to the key value
    }
    switch (results.value)
    {
      case 0xCBA816E1:
      case 0xC078:
        Serial.println("right button");
        wariat_na_lini = 1;
        break;
      case 0x43D69629:
      case 0xC0F8:
        Serial.println("left button");
        wariat_na_lini = -1;
        break;
      case 0xA6F5461D:
      case 0xC004:
        Serial.println("stop button");
        wariat_na_lini = 0;
        CarStop();
        break;
      default:
        Serial.println("different code");
        break;
    }
    key_value = results.value; // store the value as key_value
    irrecv.resume(); // reset the receiver for the next code
  }

  if (wariat_na_lini > 0) CarForward();
  else if (wariat_na_lini < 0) CarBackward();
}
```

So my question is - why are there only right motors working when the ir receiver is plugged?

This is my motor driver:
[![this is my motor driver][1]][1]

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

body:
Your problem is most likely this line:

```c++
  irrecv.blink13(true);
```

That is intended to flash an LED on pin 13 when you use your IR remote. However pin 13 is also used by the motor shield as part of the serial protocol to communicate with the control chips.

By using that you are confusing the motor shield.

Just remove that line should allow the motors to work again.


message:
Getting Accurate Velocity Readings From IMU

Hi I am currently using a BNO055 for a design project. This sensor outputs a linear acceleration vector corresponding to three (xyz) directions. I am trying to "integrate" the acceleration to get a speed the object it is mounted to is traveling.
I noticed early on that in my speed graph there is large amounts of drift.
I was looking for any guidance someone might have for tuning out the drift some way or filtering options I could use for acceleration data to reduce the drift

body:
The process of integrating acceleration to derive velocity and integrating velocity to derive position are commonly known as [dead reckoning][1].  In this link it is stated:

> Dead reckoning is subject to cumulative errors. Advances in
> navigational aids that give accurate information on position, in
> particular satellite navigation using the Global Positioning System,
> have made simple dead reckoning by humans obsolete for most purposes.

It may help to calibrate each of the 3 accelerometers using Earth's gravity as a constant.  Test if each accelerometer is symmetrical providing the same absolute values when pointed toward the Earth as when pointed away from the Earth. If any are not symmetric calculate an appropriate offset.  Next compare the range of each of the 3 accelerometers.  If they are not the same calculate an appropriate magnitude correction factor for maximum and minimum accelerometer ranges.

To find the offset and range correction values look at page 26 of the [BNO055 specification sheet][2].  There you will find a picture of the BNO055 chip which relates to the direction of the X, Y and Z accelerometers.  Position the chip such that the X accelerometer is pointed downwards toward the earth.  Record the raw value.  Now repeat the measurement with the X accelerometer pointing away from the earth.  The absolute value of these two measurements should be the same.  If not, determine the offset needed to correct X accelerometer measurements and incorporate that value into your program.  Repeat this for the Y and Z vectors.

Now compare the maximum - minimum values for the X, Y and Z accelerometers.  These 3 values should be the same.  If not, find a value to multiply the smallest of the three such that it matches the middle value and incorporate that value into your program. Repeat this for the largest of the three values.

It is desired all 3 accelerometers work the same.  If they do not, using the values derived above should adjust the raw values such as the result appears as 3 nearly identical accelerometers.

That said, most accelerometers are very usable with no correction factors.  And it is expected any correction factors to be small.  However, as experienced, when integrating, small errors can accumulate quickly.

Next consider the application in which dead reckoning is to be used.  There may be clues as to the velocity at a given moment which, if used, can reset the assumed velocity to a known value.  For example, if the accelerometer were attached to a runner's foot, it can be assumed the velocity is zero for each foot to ground impact detected.

  [1]: https://en.wikipedia.org/wiki/Dead_reckoning
  [2]: https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bno055-ds000.pdf


message:
'Serial1' was not declared in this scope for automatic plant watering

```c++
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
int in1 = 2;
int in2 = 3;
LiquidCrystal lcd(14,15,16,17,18,19);
int led = 13;
int flag = 0;
int motorpin = 11;
int sensorpin = 7;

void setup()
{
  lcd.begin(16,2);
  Serial1.begin(9600);
  pinMode(led, OUTPUT);
  pinMode(motor, OUTPUT);
  pinMode(sensor, INPUT_PULLUP);
  lcd.print("Plant Watering");
  lcd.setCursor(4,1);
  delay(2000);
  lcd.clear()
  lcd.print("RCC INSTITUTE");
  lcd.setCursor(0,1);
  lcd.print("Starting....");
  delay(2000);
  gsmInit();
  lcd.clear();
  lcd.print("System Ready");
}

void loop()
{
  lcd.setCursor(0,0);
  lcd.print("Automatic Mode");
  if (digitalRead(sensor) == 1 && flag == 0)
  {
    delay(1000);
    if (digitalRead(sensor) == 1)
    {
      digitalWrite(led, HIGH);
      sendSMS("Low Soil Moisture detected. Motor turned ON");
      lcd.begin(16, 2);
      lcd.setCursor(0, 1);
      lcd.print("Motor ON ");
      digitalWrite(motor, HIGH);
      delay(2000);
      flag=1;
    }
  } else if(digitalRead(sensor) == 0 && flag == 1)
  {
    delay(1000);
    if (digitalRead(sensor) == 0)
    {
      digitalWrite(led, LOW);
      sendSMS("Soil Moisture is Normal. Motor turned OFF");
      digitalWrite(motor, LOW);
      lcd.begin(16, 2);
      lcd.print("Motor OFF");
      lcd.setCursor(0, 1);
      lcd.print("Motor OFF");
      delay(2000);
      flag = 0;
    }
  }
}

void sendSMS(String msg)
{
  lcd.clear();
  lcd.print("Sending SMS");
  Serial1.println("AT+CMGF=1");
  delay(500);
  Serial1.print("AT+CMGS=");
  Serial1.print('"');
  Serial1.print("+918xxxxxxxxx"); // number
  Serial1.print('"');
  Serial1.println();
  delay(500);
  Serial1.println(msg);
  delay(500);
  Serial1.write(26);
  delay(1000);
  lcd.clear();
  lcd.print("SMS Sent");
  delay(1000);
  lcd.begin(16, 2);
}

void gsmInit()
{
  lcd.clear();
  lcd.print("Finding Module..");
  boolean at_flag = 1;
  while (at_flag)
  {
    Serial1.println("AT");
    while (Serial1.available() > 0)
    {
      if (Serial1.find("OK"))
      at_flag = 0;
    }
    delay(1000);
  }
  Serial1.println("ATE0"); //<=== it says 'Serial1' was not declared in this scope
  lcd.clear();
  lcd.print("Finding Network..");
  boolean net_flag = 1;
  while(net_flag)
  {
    Serial1.println("AT+CPIN?");
    while(Serial1.available() > 0)
    {
      if (Serial1.find("READY"))
        net_flag = 0;
      break;
    }
    delay(1000);
  }
  Serial1.println("AT+CNMI=2,2,0,0,0");
  delay(1000);
  Serial1.println("AT+CMGF=1");
  delay(1000);
  Serial1.println("AT+CSMP=17,167,0,0");
  lcd.clear();
  Serial1.flush();
}

body:
The UNO only has one serial port, named `Serial`.  You can create another one using SoftwareSerial (which you have included but not used) and you can, if you choose, name this `Serial1`.

```c++

#include <SoftwareSerial.h>

SoftwareSerial Serial1(4, 5); // RX, TX
```


message:
Not output on serial monitor, sending string on serial.print

I get two 10-bit values from analog pins. These two values in a string, ";" combine with.

for ex:  515; 510

I am sending it to another arduino via Serial.print. I cannot display this string expression on other arduino's serial monitor. But when I press the reset button of Coordinator arduino, there are a few values. Can you help me?

My Coordinator Code:

    #include <SoftwareSerial.h>
    #define xBeeRxPin 10
    #define xBeeTxPin 9
    int deger3;
    int deger4;
    SoftwareSerial xBeeSerial(xBeeRxPin, xBeeTxPin);

    void setup() {
      //Serial.begin(9600);
      xBeeSerial.begin(38400);
      }void loop() {

        deger3 = analogRead(A0);
        deger4 = analogRead(A2);

        String deger5 = " " + (String)deger3 + ";" + (String)deger4 ;

        Serial.println("string ifade: " + deger5);

        xBeeSerial.print(deger5);
      }

My Receiver Code:

    #include <SoftwareSerial.h>
    #define xBeeRxPin 10
    #define xBeeTxPin 9
    SoftwareSerial xBeeSerial(xBeeRxPin, xBeeTxPin);
    String d1;

    void setup() {
      xBeeSerial.begin(38400);
      Serial.begin(38400);
    }
    void loop() {
      if(xBeeSerial.available()){
        d1=xBeeSerial.readString();
        Serial.print(d1);
      }
    }

body:
There is a fundamental problem with your communication strategy, and that is you have nothing to tell the receiver "This is the end of a message".

You are sending a constant stream of

```
 515; 510 515; 510 515; 510 515; 510 515; 510 515; 510 515; 510 515; 510 515; 510 515; 510 515; 510 515; 510 515; 510 515; 510.....
```

and the receiver really doesn't know what to make of that.

This is because you are using the function `.readString()` at the receiver. This will blindly receive characters and store them in the target string up until the point those characters stop arriving. And that happens only after a break of at least 1 second in transmission. That never comes. So never ends. That is, until you reset the sender and it sees that break in transmission.

It's a very crude function and I'd never recommend anyone ever using it for anything.

Instead you need to break your transmission up into separate lines with `.println()` or appending `\n` to the string.  Then you can use `.readStringUntil('\n')` to get each line in turn and display it.

Also, on a side note, you really shouldn't be appending all your data to a string then sending the string, that's completely redundant. Just send each individual part of the data as separate prints. All you're achieving with all that String manipulation is to fragment your heap and cause your code to be unstable.


body:
I obtained the values I wanted and performed the separation. I am sending a list of joystick positions via the serial connection to the arduino in the following format

515;520

Which would be parsed as:

x=515

y=520

***MyCoordinator:***

    #include <SoftwareSerial.h>
    #define xBeeRxPin 10
    #define xBeeTxPin 9
    int deger3;
    int deger4;
    SoftwareSerial xBeeSerial(xBeeRxPin, xBeeTxPin);

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

    }void loop() {
      xBeeSerial.begin(38400);
      deger3 = analogRead(A0);
      deger4 = analogRead(A2);

      String deger5 =  (String)deger3 + ";" + (String)deger4 ;
      Serial.println("string ifade: " + deger5);

      xBeeSerial.println(deger5);

      delay(200);
    }

***MyReceiver:***

    #include <SoftwareSerial.h>
    #define xBeeRxPin 10
    #define xBeeTxPin 9
    SoftwareSerial xBeeSerial(xBeeRxPin, xBeeTxPin);
    String d1,d2,d3;

    void setup() {
      xBeeSerial.begin(38400);
      Serial.begin(38400);
    }
    void loop() {
      if(xBeeSerial.available()>0){
        d1=xBeeSerial.readStringUntil('\n');
        //Serial.print(d1);
        d2 = d1.substring(0,d1.indexOf(59));
        d3 = d1.substring(d1.indexOf(59)+1);
        Serial.println("x ekseni: " + d2);
        Serial.println("y ekseni: " + d3);
      }
    }


message:
Am I at the limit of UART transmission time?

I'm currently using an STM32F103C8 (With an arduino core) to read 4 sensors at 1kHz, then send that data via UART (at 115200 baud) to another device. Each sensor returns a float, I also include an unsigned long representing milliseconds since boot time. This adds up to be a 20 byte package, that I attempt to send at 1kHz. Sensor sampling is carried out via a timer interrupt, as it is crucial the time between samples is constant.

The data transmission itself (If I send it slowly) takes approx. 70 microseconds. When sped up to 1kHz, it takes approx. 2500. I assume this is because I am filling a serial buffer of some sort.

Is this about the limit of the communication method? If it takes longer than 1000 microseconds to send the data, then presumably the interrupt will trigger before the data is sent and it will have to start again?

body:
At 115200 baud you can send 11520 characters per second. At 20 bytes per packet you can send 576 packets per second. That's 1,736µs per packet.

That's assuming zero wait between bytes. That's not going to happen.

Your measurement of 70µs will just be the time taken to place data into the transmit buffer, and has nothing to do with how long the transmission itself takes.

Roll all that together and the value of 2,500µs per packet is not unreasonable.

To transmit faster you will simply have to run at a faster baud rate.  If you're getting 2500µs per packet currently and a packet takes 1736µs (call it 1,750 for simplicity) then there's about a 750µs overhead per packet to do the actual work of sending the data from the buffer. I'll assume this is a fixed value, though with no knowledge of how the STM32F1 UART works it may not be.

If you want <1000µs then that leaves you about 250µs of time to fit the packet into. That means an equivalent of 4,000 packets per second, or 80,000 bytes per second, or a baud rate of 800,000baud.

1 MBaud is more than possible, and is a good standard baud rate number that most things can cope with. So raising your baud rate to 1,000,000 *should* allow the communication to happen fast enough.


body:
I tested a lot of baud rates on Arduino Unos, including cheap Chinese models, and decided to use a default 115200 for my DaqPort system (<https://www.daqarta.com/dw_rraa.htm>).  I had found problems, like the system hanging after a second or so at 150000 baud, and didn't want to have my users run into issues that would be hard to troubleshoot.

So I'm wondering if you can reduce the bytes you need to send.  Do you really need to send floats?  I'm thinking 4 bytes for the data and 4 for the time would give ample resolution for almost anything, and I can't (off the top of my head anyway) think of a sensor type with more than 32-bit resolution. Also, 32 bits of msec is nearly 50 days; if you need more than that it should be pretty easy to unwrap the times after the fact.

Just a thought...


message:
Standalone ATmega328P stops responding when RX is connected

I have followed [this demo][1] and have set up a standalone ATmega328P being programmed from a Raspberry Pi via the SPI lines. I have also added a 16 MHz crystal with 22 pF capacitors, as well as I have enabled and set up I²C between the ATmega and Raspberry Pi.

I have compiled and uploaded a bunch of programs and I can confirm everything works as expected.

As you can imagine, it is quite hard debugging things without a serial connection, so I connected pin 2 of the ATmega to GPIO14 of the Raspberry Pi and pin 3 to GPIO15. At this point, when I try uploading a program, I get this:

    $ avrdude -P /dev/spidev0.0 -c linuxspi -p m328p -U flash:w:build-uno/program.hex

    avrdude: error: AVR device not responding
    avrdude: initialization failed, rc=-1
             Double check connections and try again, or use -F to override
             this check.

    avrdude done.  Thank you.

If I break the pin2 to GPIO14 connection, then my program gets uploaded. And if I restore the connection between the pins and open [Minicom][2] on the Raspberry Pi I see the output of my simple program:

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

    void loop() {
      delay(1000);

      Serial.println("Echo Test");
    }
---

    $ minicom -b 9600 -o -D /dev/ttyS0

    Welcome to minicom 2.7.1

    OPTIONS: I18n
    Compiled on Aug 13 2017, 15:25:34.
    Port /dev/ttyS0, 16:50:17

    Press CTRL-A Z for help on special keys

    Echo Test
    Echo Test
    Echo Test
    Echo Test

But whenever I press a button on the keyboard (inside Minicom), I notice that the ATmega gets reset. If I hold the button down the transmission of "Echo Test" seizes as it is getting reset rapidly.

How can I get serial to function properly?

Addendum:

I'm using a Raspberry Pi 4, and in *raspi-config* I have disabled serial login and left the serial hardware enabled.

  [1]: https://www.youtube.com/watch?v=f-Tx4RvKL0o&t=427s
  [2]: https://en.wikipedia.org/wiki/Minicom

body:
There are two things wrong with the circuit in that demo.

1. There is no decoupling capacitor on the power pins. This is required to keep the power stable during opertaion.
2. More critically: this is being powered from 3.3V, but is being run at 16MHz. That is outside specifications. You should use an 8MHz crystal to operate at 3.3V.


message:
How to make my LCD screen brighter

I'm trying to make my LCD screen brighter, can someone can help?

These are the code and the connections:

```c++
//LCD
#include <LiquidCrystal.h>
int Contrast=75;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//LED
int LdrPin = A0;   // the cell and 10K pulldown are connected to a0
int LdrValue = 0;  // the analog reading from the sensor divider
int LedPin = 10;   // connect Red LED to pin 11 (PWM pin)
int LedBrightness;

//כתום
int LdrPin2 = A0;  // the cell and 10K pulldown are connected to a0
int LdrValue2 = 0; // the analog reading from the sensor divider
int LedPin2 = 9;   // connect Red LED to pin 11 (PWM pin)
int LedBrightness2;

//צהוב
int LdrPin3 = A0;  // the cell and 10K pulldown are connected to a0
int LdrValue3 = 0; // the analog reading from the sensor divider
int LedPin3 = 8;   // connect Red LED to pin 11 (PWM pin)
int LedBrightness3;

//serial monitor
char rx_byte = 0;
//random
long randNumber;

void setup()
{
  //אתחול LCD
  analogWrite(6, Contrast);
  lcd.begin(16, 2);

  //אתחול LED
  pinMode(LdrPin, INPUT);
  pinMode(LedPin, OUTPUT);
  Serial.begin(9600);

  pinMode(LdrPin2, INPUT);
  pinMode(LedPin2, OUTPUT);
  Serial.begin(9600);

  pinMode(LdrPin3, INPUT);
  pinMode(LedPin3, OUTPUT);
  Serial.begin(9600);

  //serial monitor
  Serial.begin(9600);

  //random אתחול
  Serial.begin(9600);
  randomSeed(analogRead(0));
}

void loop()
{
  // lcd.setCursor(2, 0);
  // lcd.print("Good Morning");

  LdrValue = analogRead(LdrPin);
  //Serial.print("LDR reading = ");
  //Serial.println(LdrValue);    // print the raw analog reading
  LedBrightness = map(LdrValue, 679, 6, 255, 0);

  if (Serial.available() > 0) // is a character available?
  {
    rx_byte = Serial.read();       // get the character
  }
  //check if morning and show good morning on thr LCD
  if (LdrValue == 679 && rx_byte == '7')
  {
    lcd.setCursor(2, 0);
    lcd.print("Good Morning!");
    //random 50% order of lights
 randNumber = random(0, 2);
 Serial.print(randNumber);
 if (randNumber == 1)
    {
      //אדום
      for (int i=0; i<8; i++)
   {
        digitalWrite(LedPin, HIGH);
        delay(1000);
        digitalWrite(LedPin, LOW);
        delay(1000);
        //led start working on red
        lcd.setCursor(2, 0);
        lcd.print("working on");
        lcd.setCursor(2, 1);
        lcd.print("red");
      }
      //כתום
      for (int i=0; i<4; i++)
      {
        digitalWrite(LedPin2, HIGH);
        delay(1000);
        digitalWrite(LedPin2, LOW);
        delay(1000);
        //led start working on orange
        lcd.setCursor(2, 0);
        lcd.print("working on");
        lcd.setCursor(2, 1);
        lcd.print("orange");
      }

      //צהוב
      for (int i=0; i<5; i++)
      {
        digitalWrite(LedPin3, HIGH);
        delay(1000);
        digitalWrite(LedPin3, LOW);
        delay(1000);
        //led start working on yellow
        lcd.setCursor(2, 0);
        lcd.print("working on");
        lcd.setCursor(2, 1);
        lcd.print("yellow");
      }
    } else
    {
      //צהוב
      for (int i=0; i<5; i++)
      {
        digitalWrite(LedPin3, HIGH);
        delay(1000);
        digitalWrite(LedPin3, LOW);
        delay(1000);
        //led start working on yellow
        lcd.setCursor(2, 0);
        lcd.print("working on");
        lcd.setCursor(2, 1);
        lcd.print("yellow");
      }

      //כתום
      for (int i=0; i<4; i++)
      {
        digitalWrite(LedPin2, HIGH);
        delay(1000);
        digitalWrite(LedPin2, LOW);
        delay(1000);
        //led start working on orange
        lcd.setCursor(2, 0);
        lcd.print("working on");
        lcd.setCursor(2, 1);
        lcd.print("orange");
      }

      //אדום
      for (int i=0; i<8; i++)
      {
        digitalWrite(LedPin, HIGH);
        delay(1000);
        digitalWrite(LedPin, LOW);
        delay(1000);
        //led start working on red
        lcd.setCursor(2, 0);
        lcd.print("working on");
        lcd.setCursor(2, 1);
        lcd.print("red");
      }
    }
  } else
  {
    lcd.setCursor(2, 0);
    lcd.print("Good night!");
  }
}
```

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

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

body:
For a complete answer, we would need the datasheet of the LCD screen, but in general, LCD screens have a pin for the backlight, or two, one for plus and one for ground.

In the datasheet you can find what voltage the backlight wants, and what the maximum voltage is, and then set it to what you want.

For extra points, you can feed the backlight with PWM and set the brightness from the Arduino; if you do, make sure you don't pull too much current from the Arduino pin; add a FET if necessary.


body: Use a 220 ohm resistor for the backlight. Treat it just as an LED. That's what it is, just a normal LED.


message:
Is there a way to send a String via a Webserver Textbox without the use of the SD card?

Since my [last post][1], I've been trying to do some extra things with my Stranger Things Wall Project.

I connected a LCD Screen (16x2) that will take any text being processed to the wall and show what is being written (So we can read the full message even if we lost the first chars being flashed)

The original example I followed used a Bluetooth App to send the message, however I want to use a [Web Server with Ethernet][2].

My current challenge is if it is possible to make a WebServer to feed text to arduino, without the use of a SD card. I did manage to find [an example][3] that sends a simple command, but in my case, I need to call a function and sends a string.

My knowledge is limited on the areas of HTML and JS, so any help is welcome. If it matters, the Ethernet Shield I am using currently is the W5100.

The schematic is the same as the last post, however, here is the updated code:

    #include <Wire.h> //INCLUSÃO DE BIBLIOTECA
    #include <LiquidCrystal_I2C.h> //INCLUSÃO DE BIBLIOTECA
    #include <SPI.h> //INCLUSÃO DE BIBLIOTECA
    #include <Ethernet.h> //INCLUSÃO DE BIBLIOTECA

    //Pin connected to ST_CP of 74HC595
    #define latchPin 5
    //Pin connected to SH_CP of 74HC595
    #define clockPin 7
    ////Pin connected to DS of 74HC595
    #define dataPin 6
    // size of buffer used to capture HTTP requests
    #define REQ_BUF_SZ   90
    // size of buffer that stores a line of text for the LCD + null terminator
    #define LCD_BUF_SZ   17
    char HTTP_req[REQ_BUF_SZ] = {0}; // buffered HTTP request stored as null terminated string
    char req_index = 0;              // index into HTTP_req buffer
    LiquidCrystal_I2C lcd(0x27,16,2);
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //ATRIBUIÇÃO DE ENDEREÇO MAC AO ETHERNET SHIELD W5100 - ETIQUETINHA
    EthernetServer server(80);
    String text;                                                    //Variável do tipo string que receberá o texto

    void setup() {
      Serial.begin(9600);                                           //Velocidade de comunicação
      for (int i = 2; i < 7; i++) {
        if (i != 4) {
          pinMode(i, OUTPUT);                                   //Declarando o pino como saída
        }
      }
      pinMode(8,OUTPUT);
      pinMode(9,OUTPUT);
      lcd.init();
      lcd.setBacklight(HIGH);
      lcd.setCursor(0,0);
      lcd.print("Iniciando");
      if (Ethernet.begin(mac) == 0) {
        lcd.clear();
        lcd.setCursor(1,0);
        lcd.print("FALHA AO PEGAR");
        lcd.setCursor(7,1);
        lcd.print("IP");
      // no point in carrying on, so do nothing forevermore:
        delay(5000);
        return;
      }
      // print your local IP address:
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("PRONTO");
      lcd.setCursor(0,1);
      lcd.print(Ethernet.localIP());
      server.begin();
      brilho(255);
      inicializationEffect();                                       //Chamada da Função responsável pelo efeito inicial
    }
    void loop() {
       EthernetClient client = server.available();
      if (client) {
        Serial.println("new client");
        // an http request ends with a blank line
        boolean currentLineIsBlank = true;
        while (client.connected()) {
          if (client.available()) {
            char c = client.read();
            Serial.write(c);
            // if you've gotten to the end of the line (received a newline
            // character) and the line is blank, the http request has ended,
            // so you can send a reply
            if (c == '\n' && currentLineIsBlank) {
              // send a standard http response header
              client.println("HTTP/1.1 200 OK");
              client.println("Content-Type: text/html");
              client.println("Connection: close");  // the connection will be closed after completion of the response
              client.println("Refresh: 5");  // refresh the page automatically every 5 sec
              client.println();
              client.println("<!DOCTYPE HTML>");
              client.println("");
              client.println("
Stranger Things

");
              client.println("");
              break;
            }
            if (c == '\n') {
              // you're starting a new line
              currentLineIsBlank = true;
            } else if (c != '\r') {
              // you've gotten a character on the current line
              currentLineIsBlank = false;
            }
          }
        }
        // give the web browser time to receive the data
        delay(1);
        // close the connection:
        client.stop();
        Serial.println("client disconnected");
      }

      //receiveText();                                               //Chamada da função responsável por receber o texto digitado
    }
    //Função que recebe o texto diitado
    void receiveText() {
      while (Serial.available() > 0) {                              //Verifica se existe alguma informação na Serial
        char c = Serial.read();                                     //atribui cada caractere a variável c que é do tipo char
        if (c != '\n') text.concat(c) ;                              //verifica se a variável do tipo char recebeu uma quebra de linha que indica o fim da palavra ou frase e concatena todos os caracteres na String text
        delay(10);                                                  //aguarda 10 milissegundos
      }
      if (text.length() > 0) {                                      //verifica se a string text tem tamanho maior que 0
        text.toUpperCase();                                       //transforma tudo que estiver na string text para maiúsculo
        if (text[0]=='#'){
          waveEffect();
        }else if(text[0]=='!'){
          blink();
        }else {
          executeEffect(text);                                        //chama a função executeEffect passando a string text como parâmetro
        }
      }
      text = "";                                                    //limpa a string text
    }
    //Função responsável por ativar linha que recebe como parâmetro o número da linha
    void lineActivation(int line, int keepalive) {
      if (keepalive == 0) {
        for (int i = 2; i <= 4; i++) {
          if (i == 4) { i = 8; } //porta 4 usada pelo SD do Ethernet
          digitalWrite(i, LOW);
        }
      }
      if (line >= 1 && line <=3){
        if (line == 3) { line = 7; } //porta 4 usada pelo SD do Ethernet
        digitalWrite(line+1, HIGH);                               //coloca a linha 1 em estado lógico alto
      }
    }

    void activateLetter(char letter, int on, int off) {
      int lt;
      brilho(255);
      lt = (((int)letter - 64) % 9);
      if (((int)letter - 64) > 8) {
        lt = lt + 1;
      }
      if (on) {
        callCol(1<<lt-1);
        delay(on);                                                //mantém o pino em nível lógico alto durante o tempo que foi determinado no parâmetro da função
      }
      if (off) {
        callCol(0);
        delay(off);                                               //mantém o pino em nível lógico baixo durante o tempo que foi determinado no parâmetro da função
      }

    }

    void callCol(int col){
      digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, highByte(col));
    shiftOut(dataPin, clockPin, MSBFIRST, lowByte(col));
      digitalWrite(latchPin, HIGH);

    }
    void executeEffect(String text) {
      for (int i = 0; i < text.length(); i++) {
        if (text[i] == ' ') {
          delay(1000);
        } else if ((int)text[i] < 65 or (int)text[i] > 90) {
        } else {
          lineActivation(int(((int)text[i] - 64) / 9) + 1, 0);
          activateLetter(text[i], 1000, 200);
        }
      }
    }

    void inicializationEffect() {
      for (int i = 1; i < 27; i++) {
        lineActivation(int(i / 9) + 1, 0);                          //ativa a linha
        activateLetter(char(64 + i), 100, 10);                   //ativa a letra
      }
    }
    void waveEffect() {
      Serial.println("Wave");
      for (int i = 1; i < 4; i++) {
        lineActivation(i, 1);                          //ativa a linha
      }
      for (int i = 1; i < 10; i++) {
        activateLetter(char(72 + i), 100, 0);
      }

      for (int i = 1; i < 10; i++) {
        activateLetter(char(72 + i), 0, 100);
      }
        lineActivation(0, 0);                          //ativa a linha

    }
    void blink() {
      Serial.println("Blink");
      callCol(511);
      lineActivation(1,1);
      lineActivation(2,1);
      lineActivation(3,1);
      for (int i = 0; i < 256; i++){
        brilho(i);
        delay(1);
      }
      delay(100);
      for (int i = 255; i >= 0; i--){
        brilho(i);
        delay(1);
      }
    }

    void brilho(byte brt) { // 0 to 255
      analogWrite(9, 255-brt);
    }

  [1]: https://arduino.stackexchange.com/questions/79309/cant-make-the-second-74hc595-to-start-counting/79310#79310
  [2]: https://www.arduino.cc/en/Tutorial/LibraryExamples/WebServer
  [3]: https://forum.arduino.cc/index.php?topic=168738.0

body:
Yes, and it's not too hard, but do you do need to do string parsing in C to achieve it.

In your code you read the header of the HTTP request byte by byte and send it to serial, essentially discarding it.

Instead you need to read the header line by line (at least the first line) and parse the URL parameters.

The format of the first line should be something like:
```
GET / HTTP/1.1
```
or:
```
GET /?text=This+will+be+displayed HTTP/1.1
```

You need to parse that to get everything between `=` and the the space if they exist. You can then display it as you wish.

Next you also need to alter the code that is sending the web page content to also include a simple HTML form with the GET method and the destination of `/`, which contains a text field called `text`.


message:
Arduino TFMini Lidar sensors and speaker

I have this code for the TFMini Lidar sensors and Speaker. I Need help figuring why I'm using this calculation in my code and why if I removed it the lidar will not give me any measurement? (see below plz).

And my code now it's only one sensor is working pins (4,5) I don't know why the three of them don't work together.   Thanks in advance.

I took this code from the internet My coding experience is basic .

```c++
rx[i] = TFMiniOne.read();
if (rx[0] != 0x59) {
  i = 0;
} else if (i == 1 && rx[1] != 0x59) {
  i = 0;
} else if (i == 8) {
  for (j = 0; j < 8; j++) {
    checksum += rx[j];
  }
  if (rx[8] == (checksum % 256)) {
    *distance = rx[2] + rx[3] * 256;
    *strength = rx[4] + rx[5] * 256;
  }
  i = 0;
} else {
  i++;
}
```

Here is the complete code:

```c++
#include "Talkie.h"
#include "Vocab_US_Large.h"
#include <SoftwareSerial.h>
#include "TFMini.h"
TFMini tfminiOne;
TFMini tfminiTwo;
TFMini tfminiThree;

Talkie voice;
const int Speaker = 3;

//Declaring variables and constants

SoftwareSerial TFMiniOne (4,5);    //(RX, TX)
SoftwareSerial TFMiniTwo (6,7);
SoftwareSerial TFMiniThree (8,9);

void getTFminiData(int* distance, int* strength) {
  static char i = 0;
  char j = 0;
  int checksum = 0;
  static int rx[9];
  if (TFMiniOne.available()) {
    // Serial.println( "tfmini serial available" );
    rx[i] = TFMiniOne.read();
    if (rx[0] != 0x59) {
      i = 0;
    } else if (i == 1 && rx[1] != 0x59) {
      i = 0;
    } else if (i == 8) {
      for (j = 0; j < 8; j++) {
        checksum += rx[j];
      }
      if (rx[8] == (checksum % 256)) {
        *distance = rx[2] + rx[3] * 256;
        *strength = rx[4] + rx[5] * 256;
      }
      i = 0;
    } else {
      i++;
    }
  }
}

void setup() {
  pinMode(Speaker, OUTPUT);

  //Initializing
  Serial.begin (115200);
  while(!Serial);                     //Wait for USB Serial Port to connect
  Serial.println("Initializing...");
  TFMiniOne.begin (TFMINI_BAUDRATE);

  //Initializing TFMini Sensors
  tfminiOne.begin(&TFMiniOne);
  tfminiTwo.begin(&TFMiniTwo);
}

void loop() {
  int distance = 0;
  int strength = 0;

  getTFminiData(&distance, &strength);
  while (!distance) {
    getTFminiData(&distance, &strength);
    if (distance) {
      Serial.print(distance);
      Serial.print("cm\t");
      Serial.print("strength: ");
      Serial.println(strength);
    }
  }

  delay(100);

  if (distance > 30) {
    digitalWrite(Speaker,HIGH);
    voice.say(sp2_ALERT);
    voice.say(sp2_F);
  } else {
    digitalWrite(Speaker,LOW);
  }

  if (distance > 20) {
    digitalWrite(Speaker,HIGH);
    voice.say(sp2_ALERT);
    voice.say(sp2_L);
  } else {
    digitalWrite(Speaker,LOW);
  }

  if (distance < 15) {
    digitalWrite(Speaker,HIGH);
    voice.say(sp2_ALERT);
    voice.say(sp2_R);
  } else {
    digitalWrite(Speaker,LOW);
  }
  delay(300);

```

body:
I can't answer the first part of your question as I don't understand what you're asking.  However:

> I don't know why the three of them don't work together.

That doesn't work for 2 reasons:

1. Your receiving routine specifically references only one TFMini serial port, and
2. It is impossible to receive from more than one SoftwareSerial port at a time.

If you want to use multiple units you really should choose a microcontroller that has enough hardware UARTs to do the job. The Uno is not a suitable board.

Try the Mega2560 or one of the myriad of 32-bit ARM or MIPS boards.


body:
> I don't know why the three of them don't work together.

I already answered that question in my answer to your [previous question][1].

> why I'm using this calculation in my code and why if I removed it the lidar will not give me any measurement?

That code part is reading the data from the first `SoftwareSerial` interface. If you don't read this data (by removing this code part) you are not reading any data from the TFMini, thus you don't have any measurement. If you want measurements from the lidar sensor, don't remove the code part, that actually reads the measurements.

Besides that I will explain the complete function here in comments to the code. Before that, you should understand what the `static` keyword means here. Normal variables, that get declared inside a function, (aka local variables) will get destroyed, when the code reaches the end of the function. Variables marked with the keyword `static` will continue to exist and hold their value also after the function ended. They act a lot like global variables, though their namespace is local to the function (thus you can declare other variables with that name in other parts of your code).

    void getTFminiData(int* distance, int* strength) {
      static char i = 0; // this counter variable denotes the position of the next to be received byte in the buffer rx.
      char j = 0; // temporary counter variable
      int checksum = 0; // will be used to calculate the checksum, so that it can be compared to the one send with the data
      static int rx[9]; // this is the receive buffer, where the received data will be put

      if (TFMiniOne.available()) { // When data is available on the serial interface, read one byte
        // Serial.println( "tfmini serial available" );
        // read one byte into the current position in the buffer
        rx[i] = TFMiniOne.read();

        // A valid message starts with two bytes of the value 0x59, so we restart, if the current message doesn't have that. (checking the first two bytes with these two if statements)
        if (rx[0] != 0x59) {
          i = 0;
        } else if (i == 1 && rx[1] != 0x59) {
          i = 0;
        } else if (i == 8) { // if we received 9 bytes (positions 0 to 8 in the buffer), the message is complete --> process it

          // Calculating the checksum by adding all bytes together
          for (j = 0; j < 8; j++) {
            checksum += rx[j];
          }

          // Comparing the calculated checksum with the last byte, that was received, (which is the checksum)
          // as the checksum is only one byte, we calculate the modulo with 256, thus only leaving the number range 0-255.
          if (rx[8] == (checksum % 256)) {
            // The checksums are equal, so the data is valid and we can proceed
            // The values for distance and strength have two bytes. Thus we need to put these bytes together into one value.
            *distance = rx[2] + rx[3] * 256;
            *strength = rx[4] + rx[5] * 256;
          }

          // reset the counter, since we have a full message and can now receive the next message
          i = 0;
        } else {
          // increment the counter variable to the next position, if we are currently receiving the bytes of a valid message
          i++;
        }
      }
    }

I hope this makes the code clearer. As already said the my previous answer, it doesn't make much sense, to first use the TFMini library (declaring the corresponding objects) and then doing the communication yourself. I would suggest, that you look closer into the TFMini library. Try the examples, that surely come with the library. Use the libraries functions to communicate with the sensors. That will make it way easier for you, since the library will do the communications for you.

  [1]: https://arduino.stackexchange.com/questions/79254/tfmini-sensors-with-arduino


message:
Help solving "collect2.exe: error: ld returned 1 exit status" error in code

I just got an Elegoo UNO starter kit the other day and have been working my way through the little tutorials on all the parts it came with. I am using VSCode with Platform.io plugin and (after getting it set up) it has been working nicely.

The code I am currently struggling with is a sketch that is supposed to use the IR Remote and Receiver the kit came with, I keep getting the error: `collect2.exe: error: ld returned 1 exit status`

I have done some looking around online but haven't had much luck getting anything to work.

My full code is below:

```
char foo;

#include <Arduino.h>
#include <IRremote.h>
#include <IRremoteInt.h>
#include <IR.h>

IRrecv irrecv(RECEIVER);     // create instance of 'irrecv'
decode_results results;      // create instance of 'decode_results'

void setup() {
  Serial.begin(9600);
  Serial.println("IR Receiver Button Decode");
  irrecv.enableIRIn();
}

void loop()
{
  int tmpValue;
  if (irrecv.decode(&results)) // have we received an IR signal?
  {
    for (int i = 0; i < 22; i++)
    {
      if ((keyValue[i] == results.value) && (i<KEY_NUM))
      {
        Serial.println(keyBuf[i]);
        tmpValue = results.value;
      }
      else if(REPEAT==i)
      {
        results.value = tmpValue;
      }
    }
    irrecv.resume(); // receive the next value
  }

//The implementation effect of the above program is
//the same as that of the following, but it is more concise

//    switch(results.value)
//  {
//  case 0xFFA25D: Serial.println("POWER"); break;
//  case 0xFFE21D: Serial.println("FUNC/STOP"); break;
//  case 0xFF629D: Serial.println("VOL+"); break;
//  case 0xFF22DD: Serial.println("FAST BACK");    break;
//  case 0xFF02FD: Serial.println("PAUSE");    break;
//  case 0xFFC23D: Serial.println("FAST FORWARD");   break;
//  case 0xFFE01F: Serial.println("DOWN");    break;
//  case 0xFFA857: Serial.println("VOL-");    break;
//  case 0xFF906F: Serial.println("UP");    break;
//  case 0xFF9867: Serial.println("EQ");    break;
//  case 0xFFB04F: Serial.println("ST/REPT");    break;
//  case 0xFF6897: Serial.println("0");    break;
//  case 0xFF30CF: Serial.println("1");    break;
//  case 0xFF18E7: Serial.println("2");    break;
//  case 0xFF7A85: Serial.println("3");    break;
//  case 0xFF10EF: Serial.println("4");    break;
//  case 0xFF38C7: Serial.println("5");    break;
//  case 0xFF5AA5: Serial.println("6");    break;
//  case 0xFF42BD: Serial.println("7");    break;
//  case 0xFF4AB5: Serial.println("8");    break;
//  case 0xFF52AD: Serial.println("9");    break;
//  case 0xFFFFFFFF: Serial.println(" REPEAT");break;
//  default:
//    Serial.println(" other button   ");

  }// End Case
```

This is code that was included with the tutorials, but I am not certain it is airtight as I have already had to do some tweaking of the code and header files included with the device.
The error I am getting is the following:

```In file included from src\main.cpp:6:0:
include/IR.h:29:0: warning: "REPEAT" redefined
 #define REPEAT 22
 ^
In file included from src\main.cpp:4:0:
include/IRremote.h:57:0: note: this is the location of the previous definition
 #define REPEAT 0xffffffff
 ^
In file included from src\main.cpp:6:0:
include/IR.h:36:78: warning: initializer-string for array of chars is too long [-fpermissive]
                   "UP","EQ","ST/REPT","0","1","2","3","4","5","6","7","8","9"};
                                                                              ^
Linking .pio\build\uno\firmware.elf
C:\Users\wiley\AppData\Local\Temp\ccDVm6mB.ltrans0.ltrans.o: In function `global constructors keyed to 65535_0_main.cpp.o.1820':
<artificial>:(.text.startup+0x60): undefined reference to `IRrecv::IRrecv(int)'
C:\Users\wiley\AppData\Local\Temp\ccDVm6mB.ltrans0.ltrans.o: In function `main':
<artificial>:(.text.startup+0x160): undefined reference to `IRrecv::enableIRIn()'
<artificial>:(.text.startup+0x16c): undefined reference to `IRrecv::decode(decode_results*)'
<artificial>:(.text.startup+0x1c6): undefined reference to `IRrecv::resume()'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\uno\firmware.elf] Error 1
```

I don't understand the errors it is telling me are in the IR.h file. It says that REPEAT is redefined but it only defined once in the file. In regards to the `undefined reference to IRrecv::` I dont understand, because I have all the encessary files in the 'Include' folder, and when I CTRL click those functions in the editor it takes me to the files and shows me the code... so why can't it find the code when I run it?

IR.h:

    #ifndef _IR_H
    #define _IR_H

    #define RECEIVER 11

    #define KEY_POWER (0xFFA25D)
    #define KEY_FUNC_STOP (0xFFE21D)
    #define KEY_VOL_ADD (0xFF629D)
    #define KEY_FAST_BACK (0xFF22DD)
    #define KEY_PAUSE (0xFF02FD)
    #define KEY_FAST_FORWARD (0xFFC23D)
    #define KEY_DOWN (0xFFE01F)
    #define KEY_VOL_DE (0xFFA857)
    #define KEY_UP (0xFF906F)
    #define KEY_EQ (0xFF9867)
    #define KEY_ST_REPT (0xFFB04F)
    #define KEY_0 (0xFF6897)
    #define KEY_1 (0xFF30CF)
    #define KEY_2 (0xFF18E7)
    #define KEY_3 (0xFF7A85)
    #define KEY_4 (0xFF10EF)
    #define KEY_5 (0xFF38C7)
    #define KEY_6 (0xFF5AA5)
    #define KEY_7 (0xFF42BD)
    #define KEY_8 (0xFF4AB5)
    #define KEY_9 (0xFF52AD)
    #define KEY_REPEAT (0xFFFFFFFF)
    #define KEY_NUM 21
    #define REPEAT 22

    unsigned long keyValue[]={KEY_POWER,KEY_FUNC_STOP,KEY_VOL_ADD,KEY_FAST_BACK,KEY_PAUSE,KEY_FAST_FORWARD,
                    KEY_DOWN,KEY_VOL_DE,KEY_UP,KEY_EQ,KEY_ST_REPT,KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,
                    KEY_6,KEY_7,KEY_8,KEY_9,KEY_REPEAT};

    char keyBuf[][10]={"POWER","FUNC/STOP","VOL+","FAST BACK","PAUSE","FAST FORWARD","DOWN","VOL-",
                      "UP","EQ","ST/REPT","0","1","2","3","4","5","6","7","8","9"};
    #endif

I have searched online a lot, and this seems to be a common issue with this IR.h library, and none of the fixes proposed have got me anywhere. (I get the same outputs when trying to run this sketch within the Arduino IDE with all a libraries installed)

I have been developing with Java and Python for a while now, but I have almost no experience with C or C++ before the Arduino, so maybe this is a simple error I just don't understand. Super frustrating!! Any help or guidance would be appreciated! Thanks

body:
I have figured it out.

The problem was I had not properly set up the project with the proper libraries. I thought I was doing it right manually but I was not. PlatformIO has a really convenient Library manager that helps with set up. You just select a library and it will automatically add it to the project you choose and make sure the correct dependencies are listed in the .ini file. I was trying to manually drop the files I needed into the correct directories, and was not doing the proper adjustments to the .ini file. Thanks for the help @Mat!


message:
Arduino Esp8266 Signal(TIMER0_COMPA_vect) can’t compile

Trying to compile a program containing the statement SIGNAL(TIMER0_COMPA_vect) written for arduino. But I want to use it on an esp8266 board. The code will compile  for Arduino uno. But I get an error “expected constructor, destructor, or type conversion before ‘(‘ token when I try to compile for a Wemos D1 board. Can anyone help me convert the statement to pass the compile test. Thank you

body:
That instruction is for setting up an interrupt handler for the timer. It is very much specific to the AVR.

There's a lot more to do that just adjust that one statememt - you have to completely rewrite the whole of the timer code that you're using to operate with the ESP8266 SDK calls.

Without knowing what your code intends to achieve it's impossible to help you further, but [this library](https://github.com/khoih-prog/ESP8266TimerInterrupt) may be of help to you.


message:
Arduino waits until button release to activate

I'm fairly new to arduino, and on my own I'm trying to move a servo to the left and right using 2 buttons.  I've got it working for the most part, however when I hold the button down nothing happens, and when I finally release the servo moves a certain amount based on how long I was holding the button down.  I would like the servo to move when the button is being held down though.  The servo also occasionally moves oddly and sporadically.  I'm thinking its most likely a logic error in the code, but I can't figure it out.  Could someone please tell me what they think I've done wrong?  Thank you.

code:

    #include <Servo.h>
    Servo servo;

    #define right 9
    #define left 8

    int angle = 90;
    int angStep = 5;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(right, INPUT_PULLUP);
      pinMode(left, INPUT_PULLUP);
      servo.attach(2);
      servo.write(angle);
      Serial.print("Begin");
      Serial.print('\n');
      Serial.print(angle);
      Serial.print(angle);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      if (digitalRead(left) == HIGH && angle < 180){
        angle += angStep;
        Serial.print(angle);
        Serial.print('\n');
        servo.write(angle);
        delay(50);
      }

      if (digitalRead(right) == HIGH && angle > 0){
        angle -= angStep;
        Serial.print(angle);
        Serial.print('\n');
        servo.write(angle);
        delay(50);
      }
    }

body: I think it's because you are using a pullup resistor, so it's constantly HIGH instead of constantly LOW. Try changing HIGH and LOW to the opposite.


message:
Serial.print skips or hangs inside a "if" statement. Trying to call a function VIA serial uart

I have two microcontrollers talking to each other using serial UART pins.

Now for some reason which I can not figure out why... doing a `Serial.print()` does not work in an "if" statement. And also assigning/declaring/initializing variables and values inside the "if" statement does not work... this is really weird. I can turn on the GPIO pins in the "if" statement but other than that nothing else works.

Microcontrollers are: Arduino Nano and WeMos D1 Mini.

Just want to note that both of the microcontrollers are talking to each other fine and arduino can determine the serial input but it can not "Serial.print" in the "if" statement of "strcmp", it is being skipped.

EDIT: I just woke up this morning, and magically "Serial.print" is working properly inside the "if" statement of "strcmp"... I guess the microcontroller needed some rest, I was testing it for 13+ hours...

Please view the code below:

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

        void loop()
        {
          char a[5];
          delay(100);
          int i = 0;

          if (Serial.available() > 0)
          {
            while(Serial.available() > 0)
            {
                a[i]=Serial.read();
                i++;
            }

            a[i] = '\0';  //last character inserted with a "null char".
          }

         if(strcmp(a,"RGB_1") == 0)   //<----- "if" statement, comparing the string array buffer
         {
            int m = 1; //<---------------- declaring and initializing a variable
            //Serial.print(m); //<-------- Serial monitor will hang and skip the GPIO pins below to trigger.
            digitalWrite(12, HIGH);
            delay(1000);
            Serial.print(m); //<---------- "if" statement allows the GPIO pins to trigger but skips this serial print.
         }
       }

body:
High likely you are exceeding your character array, see:

    char a[5];

Which can hold 5 characters. However, you write:

    if(strcmp(a,"RGB_1") == 0)

Which assumes you receive "RGB_1" which is 6 characters, because a string ends with a 0.

What also might happen is that you indeed receive only 5 characters without the ending newline, which means strcmp keeps searching until it finds a string end which may not happen.

So you can increase the array size a few just for testing purposes, and print `i` as jsotola proposes. Beyond that, also print each character you put into the array so you know how/if to handle a new line.

If you don't receive a string end, then use instead of the `strcmp` function, then use `strncmp`, which can search for exactly 5 characters, not checking until the end of the string.


message:
My DHT22 module doesn`t work at all

I had bought [this][1] DHT22 module on AliExpress. The module looks fine, but it does not work at all. I had tried lots of sketches, I tried to change the pin, I tried to change the cables, but I always have the same result:
`Failed to read from DHT22 sensor!`.

That's what I get if I use the standard sketch `DHTtester.ino`:

[![problema][2]][2]

That's what I get if I use the standard sketch `DHT_Unified_Sensor.ino`:

[![problemo][3]][3]

Can you help me? Or is the module corrupted?

  [1]: https://aliexpress.ru/item/4001253056515.html?cv=815660&af=701906&utm_campaign=701906&aff_platform=link-c-tool&utm_medium=cpa&sk=mr6wR6CC&aff_trace_key=be28d4c9436349ea98b718b03464cb0a-1605781043989-07167-mr6wR6CC&dp=f639faf6a18915099c95ce1f27cdd06a&terminal_id=049661e6cfa5453b8ac1fb4fa188d0b9&utm_source=admitad&utm_content=815660https://aliexpress.ru/item/4001253056515.html?cv=815660&af=701906&utm_campaign=701906&aff_platform=link-c-tool&utm_medium=cpa&sk=mr6wR6CC&aff_trace_key=be28d4c9436349ea98b718b03464cb0a-1605781043989-07167-mr6wR6CC&dp=f639faf6a18915099c95ce1f27cdd06a&terminal_id=049661e6cfa5453b8ac1fb4fa188d0b9&utm_source=admitad&utm_content=815660
  [2]: https://i.stack.imgur.com/ocpyv.png
  [3]: https://i.stack.imgur.com/TOvv5.png

body:
The product page you linked to has modules of different types.

Make sure you have uncommented the matching type in the this section of the example:

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

Also makers of these boards sometimes label them incorrectly or describe them incorrectly when selling them.  If you're unsure what you have, try them all.


message:
How to include a file from another (parent) directory

This is my structure

    program/
      src/
        Makefile
        main.ino
        test.h
        ...
      lib/
        i2c.h

In `main.ino` I include `test.h` and in `test.h` I'm trying to include `i2c.h` but it is just not working, I keep getting:

    make: *** No rule to make target 'i2c.h', needed by 'build-uno/main.ino.o'.  Stop.

I tried including like this

    // test.h
    #include "../lib/i2c.h"

I also tried making a symlink to my lib folder in arduino libraries and adding it as a library in Makefile

`sudo ln -s /home/pi/program/lib /usr/share/arduino/libraries/GAVR`

    # Makefile
    ARDUINO_DIR = /usr/share/arduino
    BOARD_TAG = uno
    ARDUINO_PORT = /dev/ttyAMA0
    ARDUINO_LIBS = GAVR
    include /usr/share/arduino/Arduino.mk

I also tried making a symlink to lib inside the src directory

`ln -s /home/pi/program/lib /home/pi/program/src/lib`

None of the above had any effect, the error message stays the same.

How can I include a file from another directory in my program?

body:
This is definitely on the hacky side and not a proper solution to the problem, but it works nevertheless so I'm sharing it.

After making a symlink in the `/usr/share/arduino/libraries` directory you must make sure that there is a header file with the exact name of the directory, apparently that's how arduino is set up to include them.

In my case my symlink was named `GAVR`, so I had to create a `GAVR.h` file inside my `lib` directory, which would then go ahead and include my `i2c.h` file and possibly any other file that I'd need.

<strike>Also in `test.h` or anywhere I need to use `i2c.h` I must include `<GAVR.h>` instead.</strike>
Turns out Also 1 is false, you just need to include `<GAVR.h>` once in the `.ino` file and its members will be available everywhere, just like any other library.

Also 2, now that `ARDUINO_LIBS` is not empty in the `Makefile` you will need to manually declare *all* libraries that your code is using.


message:
Does the compiled binary of a sketch include uncalled functions from a library?

I am writing a GUI using a TFT display and the Adafruit GFX library and its default font on Arduino Nano.
I want to be memory efficient and I assumed that the 'optimise for size' default setting of the compiler would not compile and include all functions from all included libraries if those functions are never called in the sketch.

However I was reading this [memory management guide][1] which advises (on pager 20) to remove 'unused libraries' and 'unused functions' from your sketch to save memory.
So I have 2 related questions:

1. Does the Arduino IDE compiler include all the compiled binary from these library functions even if they are never called in the source sketch (I know that any global variables in a library will take space even if unused but I am specifically asking about unused functions)?

2. If that is the case would making my own modified, trimmed down, version of the standard libraries save space?

Thanks.

  [1]: https://cdn-learn.adafruit.com/downloads/pdf/memories-of-an-arduino.pdf

body:
In general only the functions actually used by your code are included in the final linkage of the binary.

However it's not always possible for the compiler to know what is used and what isn't.

In the case of simple functions and classes there's no problem - the linker is intelligent enough to work it out and only link in the functions that are actually used.

However when it comes to more complex systems with polymorphism or when working with function pointers there are times when the compiler won't really know what is needed and what isn't so sometimes some code gets included that isn't actually wanted.

As the compiler advances those times are getting fewer and farther between, so unless you really have a dire need to reduce your code size there's really nothing much to gain. If you do have that need then you would gain more by reducing the complexity of the code in general and collapsing any polymorphism rather than removing unused functions.

BTW: the "optimize for size" has nothing to do with what code is included / excluded. Instead it controls such things as which function are selected for `inline`, and what loops are *unrolled* or not, amongst other things.


message:
What are a few good ways to connect multiple I2C busses?

I have an issue with a project. I have a backplane with an Atmega328P based microcontroller controlling an I2C bus with multiple peripheral devices. One such peripheral is a removable card with another Atmega328P based microcontroller as the peripheral. I have a TCA4311ADR I2C hotswap buffer on the backplane connected to the port that connects to the card. The card is supposed to be a peripheral device that sends processed data from a sensor to the backplane.

Here’s my issue: one of the sensors I intend to use on the card is an I2C breakout board. To control it, the microcontroller on the card needs to act as a controller, but it also needs to be a peripheral to communicate with the backplane controller. Every time I try to make this work and the card tries to communicate with the sensor, it tries to start a new I2C bus and everything starts glitching.

I’ve tried a few options. Software used to turn normal digital pins into I2C pins didn’t work since the libraries don’t seem compatible. I can’t seem to get the card peripheral to wait until the controller starts the bus before trying to control the sensor to avoid a conflict.

I had an idea to use an I2C multiplexer like the TCA9543A to create two busses but I don’t know if that would work. I also don’t wanna just use SPI or Serial to connect the microcontrollers cause I’d have to undo months of work on coding and custom PCBs. Also using Serial would complicate the connection to the computer and using SPI wouldn’t work if I use an SPI sensor breakout later.

Is there any other way to make this system work?

body:
In an ideal world you would have your other sensor on a separate I2C bus. It *can* be done with software, but chances are you will have to re-write the library that supports it to use bit-banged I2C.

Yes, you could use an I2C MUX to share the single hardware I2C channel, however that will both be awkward and the results will be sub-optimal anyway.

Most I2C MUX chips, including the TCA9543A, are controlled themselves by I2C, so you can't really use them in your environment, since you really need to switch it to isolate your main bus from the MCU *before* you switch it from slave to master, which you can't do until *after* you have switched it from slave to master. If you switch to master before isolating the bus you risk a collision with the main master on the bus and everything going horribly wrong.

These MUX chips are really designed for allowing one master to talk to multiple slaves that share the same addresses.

And on top of that when you've isolated the bus the main master will no longer be able to communicate with that slave board, which will either cause the whole bus to lock up or other strange and unwanted things to happen.

So have another go at using software I2C to communicate with your sensor. Most I2C communication to sensors is pretty straightforward and follows the same rough format, so it really shouldn't be too hard to implement.

Either that or consider replacing the ATMega328P with a more capable microcontroller that has multiple I2C busses.


message:
Uno Wifi Rev2 Programming via Uno R3 ArduinoISP

I'm attempting to program Atmega4809 (Uno Wifi Rev2) via the ICSP pins on the board by connecting in this manner:[![enter image description here][1]][1]

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

The difference is that I have a Uno Wifi Rev2 on the right instead of a Uno R3. I've uploaded the ArduinoISP sketch onto the Uno R3 on the left. Here is the `avrdude` command that I am using:

```
$ avrdude -v -patmega4809 -cavrisp -P /dev/ttyACM1 -b19200 -U program.elf

...

avrdude: AVR device initialized and ready to accept instructions

Reading |                                                    | 0% 0.00savr_read(): error reading address 0x0000
    read operation not supported for memory "signature"
avrdude: error reading signature data for part "ATmega4809", rc=-2
avrdude: error reading signature data, rc=-2
```
Full log: https://pastebin.com/LUfhsYeD

I am wondering if I am missing some difference between the UnoR3 and Uno Wifi Rev2... there doesn't seem to be much documentation about external programming of the Uno Wifi Rev2's Atmega 4809.

If it helps, my usecase for trying to program my Uno Wifi Rev2 externally is a need to reprogram the 32u4 as a HID. Once I program the 32u4, I won't be able to program the 4809 via USB (afaik).

If anyone knows what I'm doing wrong or the proper way to program the Uno Wifi Rev2 externally, your help would be greatly appreciated.

body:
The new generation of AVR chips created by Microchip no longer use the same ICSP protocol as the old ones. Instead they use a new protocol called `updi`.

You need to use a different sketch and wiring to turn your Arduino into a suitable programmer.  More information can be found [here](https://github.com/SpenceKonde/megaTinyCore/blob/master/MakeUPDIProgrammer.md) about how to do that.


message:
How do i make my DC motors run simultaneously?

Im coding an adafruit motor shield for  3 DC motors to go forward & backwards, and so my concern is why only my motor3 is running the whole time and motors 1 & 2 are switching off meaning 1 goes than 2 goes and on and on? My code is below if you see where my mistake is in the code can you just tell me what it is and what to do to make them run simultaneously?

```c++
#include <AFMotor.h>
AF_DCMotor motor1(1);
AF_DCMotor motor2(2);
AF_DCMotor motor(3);

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Motor test!");
  // turn on motor
  motor1.setSpeed(300);
  motor2.setSpeed(200);
  motor.setSpeed(500);
  motor.run(RELEASE);
}

void loop() {
  uint8_t i;

  //third motor
  Serial.print("tick");
  motor.run(FORWARD);
  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  //second motor
  Serial.print("tick");
  motor2.run(FORWARD);
  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }
  Serial.print("tack");
  motor2.run(BACKWARD);
  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  Serial.print("tick");
  motor1.run(FORWARD);
  for (i=0; i<255; i++) {
    motor1.setSpeed(i);
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor1.setSpeed(i);
    delay(10);
  }
  Serial.print("tack");
  motor1.run(BACKWARD);
  for (i=0; i<255; i++) {
    motor1.setSpeed(i);
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor1.setSpeed(i);
    delay(10);
  }
}
```

body:
The simplest approach to include a delay in your sketch is to call the [Arduino delay() function][1].  Pass this function a delay value in milliseconds.  For example, a 1 second delay is 1000 milliseconds.

As simple as this method is, it is not recommended if your sketch is required to accomplish tasks during the delay.  This is a common requirement and frustrates many new programmers.

In order to accomplish tasks while waiting for an arbitrary period of time, do not use the Arduino delay() function.  Instead use the [Arudino millis() function][2].  The millis() function will return the number of milliseconds passed since the Arduino board began running the current program.  Record this number, execute the desired action then enter an infinite loop until millis() return a number which indicates the desired number of seconds have passed.  While in the infinite loop the program can execute other tasks as long as they take small amounts of time relative to the desired delay.  Such as testing for a switch closure and turning on an LED.

Essentially, this new program is now a simple [finite state machine][3].

  [1]: https://www.arduino.cc/reference/en/language/functions/time/delay/
  [2]: https://www.arduino.cc/reference/en/language/functions/time/millis/
  [3]: https://en.wikipedia.org/wiki/Finite-state_machine


body:
What you're searching for is called "non-blocking programming", a technique in which you frequently test or evaluate whether something needs to be done, and either do it or not, but *move on immediately*. For one motor, you could block successfully (do nothing else while you wait for something to happen): start/wait/stop/reverse/wait/stop/... etc.

But for two more more motors that need to run independently, your code must not block but decide *quickly* whether to do a particular thing now or not (start or stop a motor, f/ex), and *move on to the next decision*.

[This article describes how to do that in more detail][1]
 (full disclosure: it's one of mine).

  [1]: https://arduino.stackexchange.com/questions/60759/how-to-rotate-two-or-more-steppers-simultaneously-by-giving-array-of-angles/66380#66380