# Question
Title: How to write arduino code in a c/c++ script
I'm pretty new to arduino. But I have some knowledge about programming in c/c++. I know that arduino is written in c. But it can't be used as normal c/c++ code. for example , instead of including some libraries and write the code like this..

```
#include "arduino.h"

int main(){

    pinMode(13, OUTPUT);

    while(1){
    digitalWrite(13, HIGH);
    .....
    }
}

```

We have to write it using functions defined in arduino.

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

void loop(){
    digitalWrite(13, HIGH);
    .....
}

```

But I have some other libraries and programmes and stuff written in c and c++ and I need to use some arduino code in it and compile. So my question is, is there a way to write arduino in pure c/c++ as in first code snippet.

\*I may not need arduino for this. My main target is to use servos, sensors in programms written in c/c++. But I would like to know what is the best way.

# Answer
> 2 votes
Arduino IDE uses C++ not C.

You don't **have** to use `setup` and `loop`. This is a valid Arduino sketch:

```
#include <Arduino.h>

int main ()
  {
  init ();  // initialize timers
  Serial.begin (115200);
  Serial.println ("Hello, world");
  Serial.flush (); // let serial printing finish
  }  // end of main

```

> But I would like to know what is the best way.

The way that works best for you. The IDE gives you some convenience functions. You don't have to use them. You can look at the datasheet and directly address the hardware registers.

See here for a few more details.

---
Tags: arduino-uno, c++, c, core-libraries
---


title: Balancing pendulum using PID

text:
# Question
Title: Balancing pendulum using PID
Dear all, referring to the video at here on how to make a PID balancing pendulum as shown in the picture and the author also provided the arduino code in the video description. May I ask whether this arduino code can be used on my MPU6050 gyroscope without any modifications because the author in the video does not provide the model of the gyroscope used. I have also searched countless of arduino code on web on **balancing pendulum using propeller PID with a DC brushless motor (not 3 phase) and MPU6050 gyrocope**, but couldn't find any and I hope someone could show me some examples code.

Thank you and have a nice day!!

```
// Chuong trinh dieu khien cân bang thanh ngang Nguyen Duc Sang 24/05/2018
//---------------------------------------------------------------

//875=0
//530=90 do
#define SENSOR A1
#define CONTROL 6
#define dongco 7

   void setup() {
       Serial.begin(9600);
       pinMode(SENSOR,INPUT);
       pinMode(CONTROL,OUTPUT);
       pinMode(dongco,OUTPUT);
   }
   double error = 0;
   double realAngle;
   double lastrealAngle;
   double
     kP = 1,
     kI = 0.005,
     kD = 0;
   double
     P = 0,
     I = 0,
     D = 0;
   double PID;
   double setPoint = 90;
   int controlPwm = 85;
   long lastProcess = 0;
  void loop(){
     realAngle = map(analogRead(SENSOR), 1023, 0, -39.73, 229.47);
     //Serial.println(analogRead(SENSOR));
     //Serial.println('gia tri goc realAngle la');
     Serial.println(realAngle);
     Serial.println(setPoint);
    //PID
    error = setPoint - realAngle;
    //thoi gian lay mau
    float deltaTime = (millis() - lastProcess)/100.0;
    lastProcess = millis();
    // P
    P = error * kP;
    // I
    I += (error * kI) * deltaTime;
    // D
    D = (lastrealAngle-realAngle) * kD * deltaTime;
    lastrealAngle = realAngle;
   // Sub pid
  PID = P + I + D;
  if (PID>255){
   PID=255;}

  controlPwm = (PID + 80);

    analogWrite(CONTROL,controlPwm );

  }

```

# Answer
The shown code does not use the MPU6050. Instead it uses a sensor with an analog output signal. From the image and the video I suspect, that this sensor is a potentiometer attached to the axle of the arm. So the analog value basically gives you a measure of the angle.

> have also searched countless of arduino code on web on balancing pendulum using propeller PID with a DC brushless motor (not 3 phase) and MPU6050 gyrocope, but couldn't find any

That's not really surprising to me, since that is a very specific search request. That assumes that someone did exactly what you want to do and also described it with the same words. Finding a ready-to-use code that way is highly unlikely and I don't have such a code either.

**What to do now?** You will have to develop the code yourself. First you should divide up your project in individual parts, like: Getting readings from the MPU6050, calculating a stable angle value from the readings (by combining gyro and accelerometer values), driving the DC brushless motor and controlling its speed, implementing a PID feedback loop.

When you are able to implement each individual part by itself you can put them all together to make your project. Each individual part can be researched way easier, because there are many people, who have done these things in their own projects. Also try searching for Arduino libraries for these parts. For example: There are libraries for using the MPU6050, which will handle all the communication to the sensor for you. A good way to find libraries is search for "Arduino library MPU6050" (replace "MPU6050" by whatever single thing you wanna implement, like PID or similar). And such libraries are often hosted at Github, so it is often also good to search for something like "github arduino MPU6050". Try keeping your search request short. Look at the results and assess, if the found libraries are fitting for your situation.

And as help and inspiration you can search for similar projects. A quick search for "Arduino mpu6050 balancing robot" did show promising results and a balancing robot is very similar to your project.
> 2 votes

---
Tags: arduino-uno, arduino-mega, arduino-ide, arduino-nano
---


# Question
Title: How can I send Arduino sensors data to java application?
my final year project is to do an Arduino watch that has heart rate and body temperature sensors and also a location tracking module. I need to send all the watch data to my java app but I don't how do I need to send it to a database first and then use it? and how can i do that. I'm using arduino uno and i want to send the data to a database on a server.

I'm using android studio and coding with java

please help :(

# Answer
> 1 votes
To send the data from the Arduino, you just need to do this:

```
Serial.println(the_data);

```

But then you have to manage some communication link between the Arduino and whatever is going to collect the data. Typical choices are the USB link or a Bluetooth module. Then, whatever you do with this data (send to an Android phone, a Java app, a server, a database, whatever...) is up to you, and is *not an Arduino question*.

---
Tags: arduino-uno, sensors, java
---


title: I2C HMC5983 communication issue

text:
# Question
Title: I2C HMC5983 communication issue
I have a really weird problem, when I run the exmple wire (I2C) scanner from Arduino, I get:

**I2C Scanner** **Scanning...** **I2C device found at address 0x1E !** **done**

However when I try directly to the 0x1E I get the following error code 2:

**received NACK on transmit of address.**

Below is my code that i did only modify the example code:

```
#include <Wire.h>

void setup() {
  Wire.begin();

  Serial.begin(9600);
  while (!Serial); // Leonardo: wait for Serial Monitor
  Serial.println("\nI2C Scanner");
}

void loop() {

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

  byte address = 0x1E;

  Wire.beginTransmission(address);
  byte error = Wire.endTransmission();

  if (error == 0) {
    Serial.print("I2C device found at address 0x1E");
  } else if (error == 1) {
      Serial.print("data too long to fit in transmit buffer.");
  }
  else if (error == 2) {
      Serial.print("received NACK on transmit of address.");
  }
  else if (error == 3) {
      Serial.print("received NACK on transmit of data.");
  }
  else if (error == 4) {
      Serial.print("Unknown error at address 0x");
  }

  delay(5000); // Wait 5 seconds for next scan
}

```

# Answer
> 0 votes
There are certain situations where the device can send a nack after a valid address is sent - search "received NACK on transmit of address". Nothing I read applies specifically to your situation.

I see nothing in the HMC5983 datasheet (https://www.farnell.com/datasheets/1509871.pdf?\_ga=2.219060057.1318745487.1555987311-293789508.1555987311) that could account for what you are seeing.

I don't have an HMC5983 on a GY282 module (you mentioned the module in a different forum) as you do, but I have it's predecessor, HMC5883 which I think is largely comparable, but slower.

I tested your code and I DID NOT get the NACK error - it simply reported finding the the device.

Then, I tested the leanest HMC5883 code I could find and I saw systematic output, which changed as I moved the device.

Then I tested similar code for the HMC5983 (see https://wiki.eprolabs.com/index.php?title=GY-282\_HMC5983\_Module#Hardware\_Connections). That code worked on my slower HMC5883 board (e.g., systematic output).

I suggest the following - double check the solder blobs on the board to make sure I2C/SPI is jumpered properly - also the 3v3 CS blobs - a picture would be helpful.

I would also suggest that you try to run the HMC5983 code that I linked and see what you get.

Hope it helps.

---
Tags: arduino-uno, arduino-nano, i2c
---


# Question
Title: Provide custom AVR dude commands through the Arduino IDE
Besides the standard upload button that burns the code using FTDI, I want to then be able to provide custom AVRDude commands for burning fuses, when the external programmer is used.

Is this possible to do from the IDE? Maybe if I can edit some configuration files?

The idea is to have the IDE supply the upload command when the standard upload option is selected, but when `external programmer` is selected, i want to have custom behavior.

The custom behavior that I want is to preserve the EEPROM and set the lock bit.

These two actions can be performed with the following AVRDude commands:

```
avrdude -c usbtiny -p m328p -U hfuse:w:0xd2:m
avrdude -c usbtiny -p m328p -U lock:w:0x00:m

```

The external programmer i use is Sparkfun's "Pocket AVR Programmer" which is an SPI programmer.

So can I have custom behavior (supported by AVRDude) when I select program using external programmer?

EDIT: I opened file `boards.txt` and i found these specifications of interest:

```
pro.name=Arduino Pro or Pro Mini

pro.upload.tool=avrdude
pro.upload.protocol=arduino

pro.bootloader.tool=avrdude
pro.bootloader.unlock_bits=0x3F
pro.bootloader.lock_bits=0x0F

pro.build.board=AVR_PRO
pro.build.core=arduino
pro.build.variant=eightanaloginputs

```

and

```
## Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328P
## ---------------------------------------------------
pro.menu.cpu.8MHzatmega328=ATmega328P (3.3V, 8 MHz)

pro.menu.cpu.8MHzatmega328.upload.maximum_size=30720
pro.menu.cpu.8MHzatmega328.upload.maximum_data_size=2048
pro.menu.cpu.8MHzatmega328.upload.speed=57600

pro.menu.cpu.8MHzatmega328.bootloader.low_fuses=0xFF
pro.menu.cpu.8MHzatmega328.bootloader.high_fuses=0xDA
pro.menu.cpu.8MHzatmega328.bootloader.extended_fuses=0xFD
pro.menu.cpu.8MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex

pro.menu.cpu.8MHzatmega328.build.mcu=atmega328p
pro.menu.cpu.8MHzatmega328.build.f_cpu=8000000L

```

I am using Arduino Pro Mini. In the second specification, there is the option for setting the fuse bits I want. However, there is no option for the lock bits. The option for the lock bits are in the first specification - but there is no option for the fuses.

My new questions are these:

1. Should I specify the lock bits in the first specs and the fuses in the second? Will this work? I have to ask before trying anything stupid. Will the second specs "inherit" from the first specs?
2. Will the parameters I insert here only work for the `Upload Using Programmer` option? I want the regular upload (via bootloader) to work normally.
3. What happens if I ditch the Arduino platform and use a standalone AVR? If I use the same AVR that the Pro Mini platform had. Will the same settings work?

# Answer
> 2 votes
You can add the fuse parameters to the "Upload using programmer" command pattern `tools.avrdude.program.pattern` in platform.txt. Copy them from the `tools.avrdude.erase.pattern`. (The fuse values are from boards.txt)

the modified upload command pattern:

> tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} {program.verify} -p{build.mcu} -c{protocol} {program.extra\_params} "-Uflash:w:{build.path}/{build.project\_name}.hex:i" -Ulock:w:{bootloader.lock\_bits}:m

---
Tags: arduino-ide, avrdude, ide
---


# Question
Title: How to read and parse UART data from human presence radar sensor
I'm working on a project, and I purchased a 24 GHz "Human existence/presence" mm Wave sensor from micradar, the R24DVD1. The output of the module is serial data which varies in length and is of the structure shown below;

The Data element of the stream could get as large as 5bytes and as show each package ends with a 0x54 0x43. My intention is to have my Arduino Uno read the data for further processing. Since I use the Arduino Uno which has only one physical serial port, I felt using it to read the sensor data could prove problematic since the pc is equally connected to that serial line via USB. So I decided to use the SoftwareSerial to read the data from the senor then forward it to the pc and I wrote the following code for that;

```
#include <SoftwareSerial.h>

const int txpin = 3;
int const rxpin = 2;
SoftwareSerial mySerial(rxpin,txpin);

const unsigned int PACK_SIZE = 14;
int inByte1;
int inByte2;
unsigned int recvdByte = 0;

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

void loop() {
// put your main code here, to run repeatedly:
if (mySerial.available() > 0){
int pack[PACK_SIZE];

inByte1 = mySerial.read();
inByte2 = mySerial.read();

if(inByte1 != 84 && inByte2 != 67){
  pack[recvdByte] = inByte1;
  pack[recvdByte+1] = inByte2;
  recvdByte += 2;
 }
else{
  pack[recvdByte] = inByte1;
  pack[recvdByte+1] = inByte2;
  recvdByte = 0;
 }
for(int i = 0; i < PACK_SIZE; i++)
{
  Serial.print(pack[i],HEX);
}
Serial.println();

 }
}

```

I would like to know if my thought process in reading and parsing the data is correct because the output is quite inconsistent to what I expect

# Answer
First of all, I would advise you against using `SoftwareSerial`, especially at this high baud rates: it is a recipe for problems. Since you seem to be using the link to the computer only for writing, and the link to the sensor only for reading, you can use the hardware serial port for both. Connect the sensor's TX to the Arduino RX, and you will be able to read the sensor data with `Serial.read()`. Do **not** connect the sensor's RX, and you will be able to `Serial.print()` to the serial monitor without disturbing the sensor.

Next, you must be aware that serial data is received one byte at a time. If you waited until you had a full packet in the serial buffer, then you could read and process the whole packet at once. This is, however, difficult, because you cannot know the length of the packet before starting to read it.

I would recommend that instead you process one incoming byte at a time, and you do the necessary sanity checks in the process. Here is how I would do it (warning: untested code):

```
const unsigned int MAX_PACKET_SIZE = 14;
const unsigned char char start_signature[] = {0x53, 0x59};
const unsigned char char end_signature[] = {0x54, 0x43};

unsigned char packet[MAX_PACKET_SIZE];
int recvdByte = 0;  // number of bytes received and buffered so far
int dataLength = 0;  // length of the data field

void processPacket();  // defined elsewhere

// Handle a single input byte.
void processInputByte(unsigned char inByte) {
    if (recvdByte < 2) {  // check the start signature
        if (inByte != start_signature[recvdByte]) {  // wrong signature?
            recvdByte = 0;  // discard the packet
            return;
        }
    } else if (recvdByte == 4) {  // grab the data length
        dataLength = inByte;
        if (dataLength > MAX_PACKET_SIZE - 9) {  // overlong packet?
            recvdByte = 0;  // discard the packet
            dataLength = 0;
            return;
        }
    } else if (recvdByte == 5) {  // check the second data length
        if (dataLength != inByte) {  // doesn't match?
            recvdByte = 0;  // discard the packet
            dataLength = 0;
            return;
        }
    } else if (recvdByte == 6 + dataLength) {  // check sum
        // TODO: Look at the datasheet to see how to control that
        // the checksum is correct. Discard the packet if it is not.
    } else if (recvdByte >= 7 + dataLength) {  // check end signature
        if (inByte != end_signature[recvdByte - (7 + dataLength)]) {
            recvdByte = 0;  // discard the packet
            dataLength = 0;
            return;
        }
    }

    // All correct so far, we can buffer the incoming byte.
    packet[recvdByte++] = inByte;

    // If we have a complete packet now, handle it.
    if (recvdByte == 9 + dataLength) {
        processPacket();
        recvdByte = 0;  // reset for the next packet
        dataLength = 0;
    }
}

```

You may want to sprinkle a few `Serial.println()` here and there for testing and debugging. These could be removed once everything works as expected.

Then, in the main loop, you just have to:

```
void loop() {
    if (Serial.available() > 0) {
        processInputByte(Serial.read());
    }
}

```
> 1 votes

---
Tags: arduino-uno, sensors, softwareserial, uart
---


# Question
Title: Confusion about Oscope reading of Arduino Software Serial
I am trying to troubleshoot a Software Uart Connection from my Arduino Nano, and I do not understand this output. The setup is simple, I have a Software Serial connection on pins 2 and 3. I send 170, which I expect to be 10101010 of course with a low start bit and high stop bit.

I hook up to the TX line with my Oscope and check the waveform, but its not as I expect.... I only see 101010

```
#include <Arduino.h>
#include <SoftwareSerial.h>

#define SW_RX 2
#define SW_TX 3
#define SW_BAUD 9600

SoftwareSerial Serial2(SW_RX,SW_TX);

void setup(){
  Serial2.begin(SW_BAUD);
  delay(1000);
}

void loop(){
  Serial2.write(170);
  delay(100);
}

```

Can someone help me to understand this output?

# Answer
It is working exactly as expected. The scope trace shows 10010101011:

* 1: idle state of the serial port
* 0: start bit
* 0: first data bit
* 1010101: other data bits
* 1: stop bit.

Keep in mind that the data bits are sent least-significant first.
> 3 votes

---
Tags: serial, arduino-nano, uart
---


# Question
Title: Problem to store values from Arduino MKR 1010 to mysql?
I have problem to store values to MySQL table from Arduino MKR 1010 Wifi. I get the following message.

```
trying
got: 0 retrying
trying
got: 0 retrying
ERROR!

```

I have also tried to turn off firewall without success. Is my code wrong? Can someone help me with this issue?

```
#include <Ethernet.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
#include <MySQL_Encrypt_Sha1.h>
#include <MySQL_Packet.h>
#include <DHT.h>
#include <DHT_U.h>
#include <dht.h>
#include <WiFiNINA.h>
#include <wifiinfo.h>

byte mac_addr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

#define DHT22_PIN 7
#define DHTTYPE 22
DHT deviceMonitor(DHT22_PIN,DHTTYPE) ;

IPAddress server_addr(192,168,86,39);  // IP of the MySQL *server* here
char user[] = "root";              // MySQL user login username
char password2[] = "test1234";        // MySQL user login password

char ssid[] = SECRET_SSID;        // your network SSID (name)
char password[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS;     // the Wifi radio's status

float hum;
float temp;
float humError;
float tempError;
int checkTemp;

char INSERT_DATA[] = "INSERT INTO weather (temp, hum) VALUES ('%s','%d')";
char query[128];
char temperature[10];

EthernetClient client;
MySQL_Connection conn((Client *)&client);

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial); // wait for serial port to connect
  Ethernet.begin(mac_addr);

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to network: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, password);

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.println("You're connected to the network");

  Serial.println("----------------------------------------");
  printData();
  Serial.println("----------------------------------------");

  if (conn.connect(server_addr, 3306, user, password))
  {
    delay(1000);
  }
  else
  {
     Serial.println("Mysql connection failed.");
  }
    }

void loop()
{
  delay(5000);
  if (conn.connect(server_addr, 3306, user, password2)) {

    MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
    checkTemp = deviceMonitor.read(DHT22_PIN);
    hum = deviceMonitor.readHumidity();
    temp = deviceMonitor.readTemperature();
    Serial.println((String)"Temperature: " + temp + " Celsius");
    Serial.println((String)"Humidity: " + hum +"%");
    Serial.println();
    sprintf(query, INSERT_DATA, temp, hum);
    cur_mem->execute(query);
    delete cur_mem;
    Serial.println("Data recorded.");
    delay(10000);
 }
 else
 {
   Serial.println("ERROR!");
 }
}

void printData()
{
  Serial.println("Board Information:");
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  Serial.println();
  Serial.println("Network Information:");
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

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

  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

```

# Answer
I granted full right to user root in MySQL and now got this error instead.

```
ERROR: Timeout waiting for client.
Error: -1 = Mysql connection failed.

```

Can someone help me with this problem?
> 0 votes

---
Tags: arduino-mkr
---


# Question
Title: The code to turn off the RGB LED by pressing the 4,5,6 switches in sequence doesn't work
I'm making photoresister alarm. When distance under 5cm over notes\[\] 5 times, piezo speaker off. And I want to turn off the led rgb by pressing the 4, 5, 6 switches in sequence. The code to turn off the led rgb by pressing the 4, 5, 6 switches in sequence does not work. What's wrong? Here is a code below.

```
int pins[]={4,5,6};
int melody[]={262,294,330};
int notes[]={392,392,440,440,392,392,330};
int b=0,r=0,g=0;

void setup() {
  // put your setup code here, to run once:
 randomSeed(analogRead(A0));
 for(int i=0;i<3;i++){
   pinMode(pins[i],INPUT);
 }
}
int c=0;
int value1=digitalRead(4);
int value2=digitalRead(5);
int value3=digitalRead(6);

void loop() {
  // put your main code here, to run repeatedly:
  int vin=analogRead(A0);
  if (c>5){
    //  b=0,r=0,g=0;
    noTone(8);
    //analogWrite(11,b);
    //analogWrite(10,r);
    //analogWrite(9,g);
   // return;
  }
  if(digitalRead(0)==HIGH){
    if(digitalRead(1)==HIGH){
      if(digitalRead(2)==HIGH){
       b=0,r=0,g=0;
       noTone(8);
       analogWrite(11,b);
       analogWrite(10,r);
       analogWrite(9,g);
       return;
      }
    }
  }
  if(vin>800){
    for(int i=0; i<7 ;i++){
      tone(8,notes[i],100);
      delay(200);
      noTone(8);
      analogWrite(11,random(256));
      analogWrite(10,random(256));
      analogWrite(9,random(256));
      delay(200);
    }
  }
  long duration = pulseIn(3,HIGH);
  long distance=duration/58.2;
  if(duration == 0){
    return;
  }
  if (distance<5){
    c++;
  }

}

```

The code to turn off the RGB LED by pressing the 4, 5, 6 switches in sequence, RGB LED is off. And when distance under 5cm over notes\[\] 5 times, piezo speaker off.

# Answer
This might not be correct because I'm new in arduino projects but i think the problem comes from here On your setup

```
for (int i=0;i<3;i++)
pinMode(i,OUTPUT);

```

SHOULD BE

```
for (int i=4;i<=6;i++)
pinMode(i,OUTPUT);

```

on your loop

```
if(digitalRead(0)==HIGH){
    if(digitalRead(1)==HIGH){
      if(digitalRead(2)==HIGH){
       b=0,r=0,g=0;
       noTone(8);
       analogWrite(11,b);
       analogWrite(10,r);
       analogWrite(9,g);
       return;
      }

```

I think you need to change the pin to

```
if digitalRead(4).....
if digitalRead(5)......
if digitalRead(6)....

```

Just change it that way maybe it may work. Remember to remove the // on the b=0,r=0,g=0 And also remove the double slash // from the analogWrite And I see you declaring value 1,2,3 and not using them.

hint...

```
int value1;
int value2;
int value3;
int delaytime=500; //half a second

value1=digitalRead(4); /* you are supposed to press the button on pin 4 by now */
if (value1==HIGH) {
  delay(delaytime);
  value2=digitalRead(5); /* you are supposed to press the button on pin 5 by now */

  if (value2==HIGH) {
    delay(delaytime);
    value3=digitalRead(6); /* button on pin 6 is supposed to be pressed by now */
    if (digitalRead(6)==HIGH) {
       b=0,r=0,g=0;
       noTone(8);
       analogWrite(11,b);
       analogWrite(10,r);
       analogWrite(9,g);
       return;
      }
  }
}

```

I added the delay because that might be the greatest problem you have. Arduino is fast at processing, so in order for it to work when you press the three button you will need to press the three all at once before it can give you the output. But if you want to press them one by one, you need to add the delay and make sure you press the three button before the delay time elapse.
> 2 votes

---
Tags: arduino-uno
---


title: Cannot read LED state

text:
# Question
Title: Cannot read LED state
I am running into a problem on a very basic functionality.

I want to read the state of an LED. I have confirmed that under the specified circumstances, the LED receives 1.9V.

I try to read its state with this code:

```
#define LED_1  5

void setup()
{
pinMode(LED_1, INPUT);
}

void loop()
{
 int led_state = 0;
 if ( digitalRead(LED_1) ) led_state = 1;
 Serial.println("LED State is: ");
 Serial.println(led_state);
}

```

However, most of the time, the `led_state` is `0`. Sometimes, it goes to `1`, but then quickly goes back to `0`.

Is it because the voltage is low?

EDIT: I am hooking power directly to one pin of the LED, and the other pin goes to GND (from the same DC power supply). Also, the power pin from the LED enters inside Arduino Digital Pin 5.

# Answer
For the CMOS logic the treshold is usually 1/2 Vcc, therefore you might get lucky with arduino 3.3V Arduinos, but it's still in undefined area. That usual threshold can also change with operating temperature (like 5V WS2812 stopped working in the winter if you were using 3V3 mcu as a driver)

So what are the possible solutions?

1. route it to the Ax pin and use analogRead + condition (basically software comparator)
2. if the previous is too slow, you can use AC module on the mega328p (Analog Comparator), but you'll most likely have to dig into the datasheet and use specific pin or pins (compare it against internal 1V1 reference or external one set by potentiometer)
3. external OpAmp/Comparator (this one can be used with the original pin, note comparator needs pullup, opamp doesn't)
4. NPN transistor (1k or bigger between base and Anode of the LED, internal pullup or external one between Vcc and Collector, Emmiter to the ground)
> 2 votes

# Answer
A digital input on the Arduino Uno is guaranteed to read `LOW` if the input voltage is less than 1.5 V. It is guaranteed to read `HIGH` if that voltage is above 3.0 V. For any voltage in between, you have no guarantees.

That being said, the datasheet of the microcontroller shows some “typical” characteristics. According to those, the input should switch to `HIGH` when the input voltage goes above 2.6 V, and switch to `LOW` when it goes below 2.1 V. There is an hysteretic range in between.

Note, however, that there is no guarantee that your input will behave like in the typical characteristics. The only guarantees are for voltages below 1.5 V and above 3.0 V.
> 3 votes

# Answer
On my understanding, this is what you made

But i think you should do it this way

Here is the code

```

int value;
float input;
int delaytime=500;

void setup() {
pinMode(value,INPUT);
Serial.begin(9600); //serial bud rate
}

void loop() {

value=analogRead(A2);
input=(value*5.0)/1022.0;
Serial.println(value);
Serial.println("LED state is: ");
Serial.println(input);
delay(delaytime);

}

```
> 0 votes

---
Tags: led, digital, digital-in
---


# Question
Title: Library not found when using the arduino-cli command (although working with the Arduino IDE)
I have a sketch which I can upload without problem with the Arduino IDE. I installed the arduino-cli Version: 0.28.0 Commit: 06fb1909 Date: 2022-10-18T15:53:04Z. I want to compile and upload a code on an arduino uno and use the command line

```
arduino-cli compile --fqbn arduino:avr:uno mysketch.ino

```

but get the following error:

```
/path/to/mysketch.ino:44:10: fatal error: LiquidCrystal.h: No such file or directory
 #include <LiquidCrystal.h>
          ^~~~~~~~~~~~~~~~~
compilation terminated.

Used platform Version Path
arduino:avr   1.8.5   /Users/user/Library/Arduino15/packages/arduino/hardware/avr/1.8.5

Error during build: exit status 1

```

how could I proceed to debug?

# Answer
The LiquidCrystal library is bundles with Arduino IDE 1 so it is not installed in your sketchbook folder's `libraries` folder so CLI can't find it.

Install the library with Arduino CLI or simply copy it from Arduino IDE 1 installation folder into `libraries` folder of your sketchbook.
> 2 votes

---
Tags: library, compile, compilation-errors, arduino-cli
---


title: How to unload a sketch

text:
# Question
Title: How to unload a sketch
I've loaded a sketch onto Arduino using the Ardunio IDE and it works but when I press the reset button I realize it doesn't remove the program. Is there a way to unload the program? Why? Because when I take it apart to put it away I don't know if having that program turning pins on or off and having nothing connected to it would break anything.

# Answer
> 3 votes
Frist: The Arduino cannot break when nothing is connected to it, doesn't matter what the code does.

If you want to remove the current code from the Arduino, you have to overwrite it with an empty sketch (one with only `setup()` and `loop()`, both empty). So upload an empty sketch.

The reset button is not meant for erasing the code. It is meant to return the Arduino in a definited starting state (not erasing program space or EEPROM) and executing the program on the Arduino (including the bootloader) from its start.

# Answer
> 3 votes
You can't remove a program by resetting the Arduino. If you want to be sure that it can't activate any pins in your next experiment, then just before you finish with it, upload a new program that does nothing, such as the Basics | Bare Minimum example program. It will effectively replace the previous program.

At power-up, all of your pins\[\*\] get configured as inputs during power-up. With the Bare Minimum program, nothing will change those pins, until you start writing & uploading new code that modifies them.

\[\*\] Note that the bootloader will re-configure pin-1, the serial transmitter pin, as an output.

---
Tags: arduino-ide, sketch
---


# Question
Title: How to write a program to do 2 different loop | Task?
I wanna write a program for rc-plane navigation

The plane must navigate to 2 waypoints waypoint\_1 & waypoint\_2 When it reaches to waypoint\_1 (with miss-distance =\< 5) then navigate to waypoint\_2

But i have a problem.

First look at this :

```
void loop(){

    if (distance-to-waypoint_1 > 5 meters) {
        Navigate to waypoint_1
    if distace-to-waypoint_1 < 5 meters :
        Navigate-to-waypoint_2

```

If i use a code like this, plane will navigate to waypoint\_1 and when it reaches somewhere that has less than 5 meters distance to waypoint\_1, then will navigate to waypoint\_2, but if plane fly away and the distance between it's location and waypoint\_1 goes greater than 5 meters, plane return to previous navigation and will navigate to waypoint\_1 again and ignore navigation to waypoint\_2

So, i need a form of programme to first do a loop for navigation to navigate the plane to waypoint\_1 and when it reaches the waypoint\_1 , do another loop to navigate the plane to waypoint\_2

Thanks

# Answer
I think you should use a different logic by using a variable to hold the current target waypoint and separate the code to reach a waypoint and to change it.

Something like this (in pseudocode):

```
declare variable target_waypoint and set it to waypoint1
loop
    Fly towards target waypoint
    if distance to target waypoint lower than 5
        change target_waypoint to waypoint 2

```

You can easily extent that for more waypoints by using an array of waypoints and a variable holding the index of the next waypoint:

```
declare waypoints as array
declare index variable, initialize with zero
set target_waypoint to waypoints[index]
loop
    Fly towards target waypoint
    if distance to target waypoint lower than 5
        increment index
        if index greater than max index
            Either set to zero to loop through all waypoints again
            or do whatever you want to do after the waypoints
        set target_waypoint to waypoints[index]

```

The code that moves you to the waypoint doesn't care about what waypoint is next. It's only doing this one job. And when you reached a waypoint you simply move the target of that code to a different position.

Much like you yourself would walk between different waypoints. Setting first waypoint as target, walking towards it until you reached it, setting the next waypoint as target and doing the walking again.
> 2 votes

---
Tags: programming, sketch, loop
---


# Question
Title: ADXL345 to detect sudden and large changes in acceleration
I am working on school project to develop, basically, a shock sensor when the object containing the ADXL345 is thrown to the ground.

I have used the Adafruit ADXL345 sensortest from the library but I am not sure how to code it such that the reading will only appear when there is a sudden and large change in in acceleration in either the x/y/z direction.

Any tips on how to do so?

# Answer
> 0 votes
Build an enclosure for the Arduino and the sensor in such a way that you can keep connected the USB cable that links the Arduino to the computer. Then run the sensortest sketch provided as an example with the library, and look at (or better yet, record) the acceleration data.

Now turn the enclosure around, shake it, hit it, drop it to the ground... all while monitoring the sensor's output. I recommend that you plot the acceleration curves: it should make things clearer. What do you see? Can you tell the difference between the enclosure being dropped to the floor and other forms of shaking just by looking at the output data? How do you tell the difference? Is it the magnitude of the acceleration or is it the rate of change? If you think the rate of change is more relevant, then modify the sketch in order to also print this rate of change. In either case, can you find a threshold of magnitude (or rate of change) of acceleration that could be used to discriminate between a drop and other forms of movement? If so, write it down.

I am asking all the questions above to show you the path to solving your problem. The purpose is not only to have you do all the work: *I do not have the answers* to those questions, and you will really have to do all this work yourself.

You should be able to come up with a criterion of the form: the object has been dropped if such function of the measured acceleration is higher than such threshold. The function would likely be either the Euclidean norm of the acceleration or the Euclidean norm of its time derivative (I cannot tell which is better). Now code the function in your sketch, then you can write something like:

```
if (computed_criterion >= drop_threshold) {
    signal_that_the_object_has_been_dropped();
}

```

---
Tags: adafruit
---


# Question
Title: Continous Rotation Servo not changing directions
I have coded a robot to be controlled by a ps3 Controller. I am using continous rotation servos but unfortunately I can not figure out how to get them to change direction. My input for my if statements is correct, but for some reason even if the input from the PS3 controller shows to do the reverse direction, the continuous rotation servo still rotates forward.

Here is my Code:

```
  #include <PS3BT.h>
  #include <usbhub.h>

  // Satisfy the IDE, which needs to see the include statment in the ino too.
  #ifdef dobogusinclude
  #include <spi4teensy3.h>
  #endif
  #include <SPI.h>

  #include <Servo.h>

  USB Usb;
  //USBHub Hub1(&Usb); // Some dongles have a hub inside

  BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
  /* You can create the instance of the class in two ways */
  PS3BT PS3(&Btd); // This will just create the instance
  //PS3BT PS3(&Btd, 0x00, 0x15, 0x83, 0x3D, 0x0A, 0x57); // This will also store the bluetooth address - this can be obtained from the dongle when running the sketch

  bool printTemperature, printAngle;

  // identifying servos
  Servo LeftServo;
  Servo RightServo;

  void setup() {
    Serial.begin(115200);
    #if !defined(__MIPSEL__)
    while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
  #endif
    if (Usb.Init() == -1) {
      Serial.print(F("\r\nOSC did not start"));
      while (1); //halt
     }
    Serial.print(F("\r\nPS3 Bluetooth Library Started"));

  // Attaching Pins to Servos
    LeftServo.attach(2);
    RightServo.attach(3);

  }
  void loop() {
    Usb.Task();

    if (PS3.PS3Connected || PS3.PS3NavigationConnected) {
    if (PS3.getAnalogHat(LeftHatY) < 117){
Serial.print(F("\tLeftHatY: "));
Serial.print(PS3.getAnalogHat(LeftHatY));
  LeftServo.attach(2);
LeftServo.write(180);

}
else if (PS3.getAnalogHat(LeftHatY) > 140) {
     Serial.print(F("\tLeftHatY: "));
Serial.print(PS3.getAnalogHat(LeftHatY));
    LeftServo.attach(2);
  LeftServo.write(0);
  }
else {
LeftServo.detach();
   }
   }
    }

```

# Answer
im new in Arduino projects but i think this might work, try changing some things in your else sttement, you should try and change this

```
LeftServo.attach(2);
  LeftServo.write(0);

```

Try changing it to this

```
LeftServo.attach(2);
  LeftServo.write(180*(-1));
// or, LeftServo.write(-180);
/* if you use (180*(-1), the servo might go the opposite direction continuously until
(PS3.getAnalogHat(LeftHatY) is less than 117 */

```
> 0 votes

---
Tags: arduino-uno, arduino-ide, continuous-servo
---


# Question
Title: 600VDC measurement with Arduino (voltage divider)
I need to detect quick (~200ms) voltage drop, so I am thinking of making an oscilloscope with Arduino. Problem is - can I reliably read 600V DC voltage and what resistor values should I choose for voltage divider? Can I apply same rules as for lower voltage (150k and 1k ohm)?

# Answer
I think first of all you need a circuit to bring down the voltage to about 5volt otherwise 600volts will blow up your Arduino.

Here is the code

```
int vin=A2;
int inputstate;
float inputvalue;

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

void loop()
{
inputstate=analogRead(vin);
inputvalue=(inputstate*5.5)/(11.7)/0.8;
Serial.println(inputvalue);
}

```

It might works but it is hard for me to get the actual calculation but you need to change this for your liking make this calculation,,

***inputstate(which is your analogread pin maximum readings (1023)) × 5.0(you need to cange this on your calculation) / 11.7( or any number it can divide to give you 600.0)*** So your calculation will be

***1023 × 5.0 (or whatever number) / 11.0(or whatever number to get 600.0)***

Once you have gotten your right calculation You input the numbers you calculated with in place of 5.0 and 11.0

You can remove 0.8 i added it base on my calculation to get 600.0.
> 0 votes

---
Tags: analogread, voltage-divider
---


# Question
Title: How to control PWM and digital pins at the same time over ethernet in arduino
I am using Controllino Maxi. It has an Arduino Uno inside it. I am trying to control the PWM pin `D0` and digital pin `R0` via `python` code. Below is the code I have upload on arduino:

`Arduino Code`:

```
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SPI.h>
#include <Controllino.h>

byte mac[] ={};
IPAddress ip(192, 168, 0, 200);
unsigned int localPort = 5000;
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
String datReq;
int packetSize;
EthernetUDP Udp;

void setup()
{
  Ethernet.begin( mac, ip);
  Udp.begin(localPort); //Initialize Udp
  pinMode(CONTROLLINO_D0, OUTPUT);
  pinMode(CONTROLLINO_R0, OUTPUT);

}

void loop() {
  packetSize =Udp.parsePacket(); //Reads the packet size
  if(packetSize>0)
  {
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); //Read the data request
    String datReq(packetBuffer);
    if (datReq == "R0")
    {
      digitalWrite(CONTROLLINO_R0, HIGH);
      delay(2000);
      digitalWrite(CONTROLLINO_R0, LOW);
    }
    else
    {
      analogWrite(CONTROLLINO_D0, datReq.toInt());
      delay(2000);
      analogWrite(CONTROLLINO_D0, 0);
    }
  }
 }

```

In above code, if I receive `R0` over ethernet, then I am turning on/off `R0` pin, else whatever PWM I am receiving, I am setting it using `analogWrite`. Below is my `python` code:

```
from socket import *
import time

address = ('192.168.0.200', 5000)  # define server IP and port ((0x12, 0x02, 0x00, 0x00, 0xEA, 0x03))
client_socket = socket(AF_INET, SOCK_DGRAM)  # Set up the Socket
client_socket.settimeout(1)

data = "R0".encode("utf-8")
client_socket.sendto(data, address)
time.sleep(5)

data = ("{}".format(200)).encode("utf-8")
client_socket.sendto(data, address)
time.sleep(5)

data = ("{}".format("R0")).encode("utf-8")
client_socket.sendto(data, address)

```

In above code, I am first sending `R0` to turn on/off `R0` and then sending `200` for PWM and then again sending `R0` to turn on/off `R0`. When tested I can see `R0` getting high and low, then I can see `200` on PWM but then again `R0` should be high/low but it stays low. If I re run the python code, `R0` doesnt work and only PWM works. If I power off the board and power it again, then `R0` works only for first time and it didnt work in second time.

I am a bit confused at this stage. Is there any bug in my arduino code as I am not very experienced in it. Is there any way to debug it? Please help. THanks

# Answer
You Arduino sketch is storing the received UDP packet in a `char` array named `packetBuffer`, then converting this array to a `String` object like this:

```
String datReq(packetBuffer);

```

The problem is that this `String` constructor expects a NUL-terminated array, and you have no guarantee that this array is NUL-terminated.

Well, actually you have this guarantee, but only at the beginning: as the program starts, the array will be filled with zeros by the C initialization routine. This is why the first request is correctly processed. The second request sends a packet larger than the first one, so the array is still NUL-terminated. On the third request, however, the received bytes are immediately followed by the leftovers of the previous request. In this case it is the digit `'0'`.

The simple solution is to ensure that the buffer is always properly terminated. Start by making it wider by one byte:

```
char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; // +1 for the '\0'

```

Then, whenever you receive a packet, add the terminating NUL character:

```
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); //Read the data request
packetBuffer[packetSize] = '\0'; // properly terminate the buffer

```
> 2 votes

---
Tags: arduino-uno, pwm, ethernet, analogwrite, digitalwrite
---


# Question
Title: How to architect streaming data from multiple plant monitors to single Arduino?
## Premise:

I'm trying to determine a good way to architect getting data from 4 plant monitors to a single Arduino. For context, that Arduino will have a Wifi connection that will transmit the data from the plant monitors to a web server internally.

## Setup

Where I'm struggling to make a decision is how to go about hooking the sensors up. Here's my plant setup:

## Materials

Tools I have at hand:

* Many Arudino Micros
* Arduino Unos
* Arduino Mega
* Raspberry Pi 4 B
* 4x Monk Makes Plant Monitors
* Wiring stuff and power supplies, basic electronics prototyping collection.

## Solutions?

I would like to place 4 monitors into different plants (doesn't matter which ones at the moment, if it does, I can specify). What I've considered:

1. All 4 plant monitors directly wired to the Arduino Mega. This requires a 1k resistor in line of the data pin, which I'm not sure I have a good solution for that without a breadboard. Also, I wasn't sure if the length of data line would be a problem.
2. Each Plant Monitor is hooked up to an Arduino micro and then use the USB of the micro to the RPI.
3. Like #2 but use I2C to send data to Arduino Mega. I would need to supply power to these minis then.
4. There are some options without using Arduinos, but since is the Arduino SE, I'm happy to keep it with this.

I'm open to other options as well, as well as possibly needing to purchase/make another part to optimize the solution some.

# Answer
> 2 votes
The distances between the plants on the shelf are in general too long for TTL level communication and soon you may want to connect more sensors at plants elsewhere in the room or even in other rooms.

In my opinion the solution proposed by dandavis, using esp-01 with WiFi or esp-now is the most simple and universal solution. I see no problems with the implementation. The esp-01 is small and will play nice with the 3.3 V sensor. Maybe it can be even made battery powered and then there are no cables between plants.

If wired solution was required, I would recommend to use RS485 bus. With RS485 modules with AutoDirection control the sensors could be directly connected to the RS485 module without a MCU at every sensor.

---
Tags: arduino-mega, sensors, arduino-micro, raspberrypi
---


# Question
Title: What should happen when sending analogWrite signal to a non-PWM pin?
I'm a very new to Arduino and any electrical engineering, I'm learning through some Youtube tutorials.

Based on my understanding though, sending analog signals to a non-PWM pin would just check for a threshold and send either LOW or HIGH, as opposed to being able to send variable voltages to a PWM pin.

**BUT** ... that's not what I'm seeing in practice...

Using Arduino UNO, I made a little project, for changing a blue LED's brightness. At first I did it through a PWM pin (pin 9) and it worked flawlessly. But then I tried seeing what would happen in a non-PWM pin (pin 8), you know cause you learn by trying and experimenting. So I switched to a non-PWM pin and ... it works the same exact way ...

I can change the brightness of the LED **5 different levels** ... using analogWrite ... to a non-PWM pin ...

Thanks in advance

# Answer
> 2 votes
> Based on my understanding though, sending analog signals to a non-PWM pin would just check for a threshold and send either LOW or HIGH, as opposed to being able to send variable voltages to a PWM pin.

On the Uno you do not send analog signals anywhere. The PWM pins are merely digital outputs which turn on and off rapidly at a frequency and duty cycle that you specify.

You can, therefore, do the same thing to non-PWM pins by sending HIGH/LOW at a variable rate.

To comment more on why your code appears to be "working" we would need to see it.

---

> What is the point of PWM pins if its also possible to send variable high/low signals to non-PWM pins?

Well, the PWM pins output high/low signals asynchronously. That is, without code having to do it. So, if you set up a timer (which is connected to the PWM pins) to output 100kHz then it will do that, regardless of what the code is doing at the time. You might be calculating prime numbers, but the hardware timers will mindlessly toggle that PWM pin on and off at the specified frequency.

If you try to make your own PWM in code, then the code has to do that **and nothing else** if it is going to output a consistent signal.

---
Tags: pwm, analogwrite
---


# Question
Title: Bitwise Operator in Arduino Code Question
What is the below Arduino code doing?

I am not familiar with the '+' with regard to bitwise operations. Just getting familiar with this stuff.

```
return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);

```

# Answer
`+` is the addition operator. It is used to add numbers. For example, `2+3` yields 5.

For analyzing your expression, let's call “a”, “b”, “c” and “d” the bits of `one`, `two`, `three` and `four` respectively, like this:

```
one    = aaaaaaaa
two    = bbbbbbbb
three  = cccccccc
four   = dddddddd

```

These numbers may have more than 8 bits, but in that case the extra bits will be discarded by the `&` operations. Now, let's compute the terms of the sum, and then the whole sum:

```
(one   << 24) & 0xFFFFFFFF = aaaaaaaa000000000000000000000000
(two   << 16) & 0x00FFFFFF = 00000000bbbbbbbb0000000000000000
(three <<  8) & 0x0000FFFF = 0000000000000000cccccccc00000000
(four  <<  0) & 0x000000FF = 000000000000000000000000dddddddd
─────────────────────────────────────────────────────────────
sum                        = aaaaaaaabbbbbbbbccccccccdddddddd

```

As you see, only one bit in each column of this addition can be non-zero, and that column's sum can only be 0 or 1. This means that there will be no carries, and the columns will add independently of one another. The sum is then made of the bits of `one`, `two`, `three` and `four` concatenated.

The exact same result could be computed by using the bitwise OR operator (`|`) instead of `+`. In fact, I would prefer using `|`: to my eyes it makes the programmer's intent clearer.
> 2 votes

# Answer
You are better off using `|` for bitwise operations. Whilst `+` will work under certain circumstances, `|` is better. For example:

```
a = 1 + 1 + 1 + 1;  // a will be 4
a = 1 | 1 | 1 | 1;  // a will be 1

```

For code where you are just trying to set a single bit, using `|` is much preferable, as if the bit is already set and you use `+` then you will clear the bit and set the next one along.
> 1 votes

---
Tags: eeprom, bit
---


# Question
Title: char * variable - Handle correctly to avoid overflow
I'm trying to understand if a `char *` variable can be updated down the code (since it only stores a pointer) or over-flow can occur.

For example:

`char *A="/file.txt";`

`char *B;`

```
void print_filename(char *filename="/defname.txt"){
Serial.println(filename);

```

Is is the right way to use `char*` variable, so down the road I assing new values :

`A="/anyOtherfile.txt";`

`B="This_is_not_empty";`

`print_filename("/logfile.txt");`

# Answer
No overflow can occur when using `char` pointers like you did in your question.

You use a number of different string literals (the strings enclosed by double quotes). These automatically get placed in RAM by the compiler, but they are not meant to be writable. When you do

```
char *A="/file.txt";

```

the compiler will place the literal in RAM (not in stack, but in the read-only section, even if the literal is used inside of a function (Thanks to Edgar Bonet for the comment)) and then set the pointer `A` to the address of that literal. Writing to that address is undefined in the C++ standard and should not be done.

When you then do something like this

```
A = "some other literal";

```

then you are not changing the literal. Instead you are just changing the pointer to a different literal placed in RAM. So no overflow can occur, since the compiler just takes all string literals, places them in RAM (immutable) and only handles their memory addresses. So there is no writable buffer in the first place.

With

```
void print_filename(char *filename="/defname.txt"){
Serial.println(filename);

```

you are setting the default value of the `filename` pointer to the address of that specific literal. Setting the parameter to an address of another literal or an existing `char` array will just change the pointer. If you at another pointer again set `filename`to that exact literal, the literal still lies in RAM and the compiler will usage again its address (so multiple uses of the same literal will not result in higher memory use).

If you - at some point - want to write data to that pointer, you first need to set it to a `char` array, either the address of a static array or creating a new dynamically allocated array with the `new` keyword:

```
char my_static_array[10];
A = my_static_array;
// now you can write to the array my_static_array by using A
A = new char[15];
// now you can write to a newly created array by using A

```

Though for the dynamic allocation you need to keep in mind, that especially AVR based Arduinos (like the Uno/Nano/Mini) don't have much memory and often dynamically declaring and deleting memory can lead to memory fragmentation (essentially the delete operations free memory, but these holes with free memory are often too small for the next allocations, so they don't get used and your memory gets like swiss cheese). That is also the reason why using the Arduino `String` class in the wrong way is really bad.
> 3 votes

---
Tags: char
---


title: for loop crashes program

text:
# Question
Title: for loop crashes program
Just started out with tinyduino(tinycircuits) and I am trying to develop a hangman game. I have this chunk of code that randomly picks a word from my array. I've omitted some code for readability.

```
char* words[] = {"Fortran", "Cobol", "Python", "Java", "Javascript", "Kotlin", "Swift", "Golang", "Typescript"};
long word1;
char* generatedWord1;
int k;
int i;
int wordLength;

void setup(void) {
  randomSeed(analogRead(5));
  hangman();

void hangman(){
  word1 = random(sizeof(words)/sizeof(char*));
  k = 1;

  if (k == 1) {
    display.setCursor(10, 50);
    generatedWord1 = words[word1];

    for (i = 0; generatedWord1[i]; i++) {
      generatedWord1[i] = "_";
    }
}

```

When I upload this to my board, it would not display the underscores based on the randomly chosen word's length. Re-uploading it does not work and usually requires me to reboot the tinyduino after that. Hence, I concluded my code crashes it. But, when I replace the `generatedWord1[i] = "_";` in the `for loop` with `display.print("_");` the program carries on and it prints the correct amount of underscores.

However, this does not fit my purpose of replacing the letters with underscores, as `display.print("_");` just prints underscores based on the random word's length instead. I need it to be in a manner where I can still compare a user input against the random word and replace the underscore if the letter input matches any letters in the word.

What and how do I modify my code to work as such?

Note: For the context of this whole sketch, I am trying to use get an input from a user through bluetooth and compare whether or not the input matches any of the letters from the random word and then replace the underscore with the input letter. Completing the word means winning the game as per hangman.

**EDIT**: I've added the whole sketch below for reference just in case I missed out something important for my question.

```
#include <SPI.h>
#include <STBLE.h>
#include <Wire.h>
#include <SPI.h>
#include <TinyScreen.h>
#include <string.h>

//Debug output adds extra flash and memory requirements!
#ifndef BLE_DEBUG
#define BLE_DEBUG true
#endif

#if defined (ARDUINO_ARCH_AVR)
#define SerialMonitorInterface Serial
#elif defined(ARDUINO_ARCH_SAMD)
#define SerialMonitorInterface SerialUSB
#endif

uint8_t ble_rx_buffer[21];
uint8_t ble_rx_buffer_len = 0;
uint8_t ble_connection_state = false;
#define PIPE_UART_OVER_BTLE_UART_TX_TX 0

TinyScreen display = TinyScreen(TinyScreenDefault);

// declarations
const char* words[] = {"Fortran", "Cobol", "Python", "Java", "Javascript", "Kotlin", "Swift", "Golang", "Typescript"};
long word1;
const char* generatedWord1;
int k;
int i;
int length;

void setup(void) {
  Serial.begin(9600);
  randomSeed(analogRead(5));
  BLEsetup();

  Wire.begin();
  display.begin();
  display.setBrightness(10);
  hangman();
}

void hangman(){
  display.clearScreen();
  display.setFont(thinPixel7_10ptFontInfo);
  display.setCursor(10,20);

  display.print("Ready to hang?");
  delay(2000);

  display.setCursor(5,20);
  display.print("generating word...");
  delay(1000);

  display.clearScreen();

  // word1 is my index, so printing out word1 will give you a random index from the array
  word1 = random(sizeof(words)/sizeof(char*));
  k = 1;

  if (k == 1) {

    display.setCursor(10, 50);
    generatedWord1 = words[word1];

    length = strlen(generatedWord1);
    char user_input[length+1] = "";

    for (i=0; i < length; i++) {
      user_input[i] = "";
      user_input[length] = 0;
    }

    display.setCursor(30, 30);
    display.print("|");

    display.setCursor(30, 20);
    display.print("|");

    display.setCursor(30, 10);
    display.print("|");

    display.setCursor(30, 0);
    display.print("____");

    // remember to move this away from the if statement
    // If user guesses wrong letter (1)
    display.setCursor(50, 10);
    display.print("|");

    // If user guesses wrong letter (2)
    display.setCursor(49, 15);
    display.print("o");

    // If user guesses wrong letter (3)
    display.setCursor(50, 25);
    display.print("|");

    // If user guesses wrong letter (4)
    display.setCursor(43, 21);
    display.print("-");

    // If user guesses wrong letter (5)
    display.setCursor(54, 21);
    display.print("-");

    // IF user guesses wrong letter (6)
    display.setCursor(43, 30);
    display.print("/");

    // If user guesses wrong letter (7)
    display.setCursor(52, 30);
    display.print("\\");
  }

}

void displayScreen(char phone_input[21]) {

  display.clearScreen();

  int width=display.getPrintWidth(phone_input);
  display.setFont(thinPixel7_10ptFontInfo);
  display.setCursor(48-(width/2),32);
  display.fontColor(TS_8b_White,TS_8b_Black);
  display.print(phone_input);
}

void loop() {
  aci_loop();//Process any ACI commands or events from the NRF8001- main BLE handler, must run often. Keep main loop short.
  if (ble_rx_buffer_len) {//Check if data is available
    delay(10);
    displayScreen((char*)ble_rx_buffer);
    ble_rx_buffer_len = 0;//clear afer reading
  }

}

```

# Answer
Funny, I just wrote an answer about the problem, that you have here, about 45min ago. And the problem is, that you are trying to modify a string literal. That is undefined behavior in C++.

When you declare your words array with

```
char* words[] = {"Fortran", "Cobol", "Python", "Java", "Javascript", "Kotlin", "Swift", "Golang", "Typescript"};

```

you are actually defining an array of pointers. The compiler will place these strings in the RAM and place their memory addresses in the array. Then you are declaring another `char` pointer and set it to one of the words:

```
char* generatedWord1;
generatedWord1 = words[word1];

```

So now `generatedWord1` will also point to one of the string literals. And then you are trying to write to this string literal:

```
generatedWord1[i] = "_";

```

But - as already mentioned - string literals are not meant to be changed. Trying so is undefined behavior and yes, it can lead crashes.

**What to do now?** You can define an array of `char` (not `char` pointers) as a buffer and fill it with the number of underscores that equals the length of the string literal. When defining the array you can choose the length of the string literal (plus 1 to accommodate the null character) as size, though - depending on your program flow, that you didn't show - it might be better to just declare a buffer with a fixed size bigger than the longest of your words.

You can get the length of the string literal with the `strlen()` function:

```
int length = strlen(generatedWord1);

```

Defining the `char` buffer:

```
char user_input[length+1] = "";

```

Filling it with underscores

```
for(int i=0;i<length;i++){
    user_input[i] = '_';
}
user_input[length] = 0; // terminating null character

```

> I still can't get the desired output I would like. Also it keeps throwing me an error of invalid conversion from 'const char\*' to 'char'.

The following part is wrong:

```
for (i=0; i < length; i++) {
    user_input[i] = "";
    user_input[length] = 0;
}

```

First: You misunderstood what is in the loop and what not. I changed my snipped above to use curly braces. Terminating the string with the null character can be done outside of the loop.

Second: You wanted to fill the buffer with underscores. If you look at my code snippet I assigned an underscore here.

The warning that you are getting from the compiler also lies in this line. You have used double quotes. Those mark a string literal. But here we are assigning a single character, so you need to use single quotes, which mark single characters.

The message `invalid conversion from const char* to char` means, that you used a string literal (which is a pointer to a constant character) and assigned it to a single character variable (one element of the `char` array).
> 4 votes

---
Tags: arduino-ide, string, loop
---


# Question
Title: generate x item long list for gyverportal drop-down selection
I am trying to make a drop down selection with gyverportal. The issue is that I don't know how many items there are so the list cannot be hard coded. Here is an example from github:

```
GP.SELECT("sel", "val 1,val 2,val 3", valSelect);
//where sel is the name of the field and valselect is the currently selected item.

```

I am very confused with the different types of text (char, char\*, const char, const char\*, String, char array\[10\]...just to name a few) and the operations with them seem a nightmare. I think gyverportal expects a "char\*" for the list.

for context: The items are loaded from EEPROM and the number is stored in Length.

what I need is:

for 0 items: "none"

for 5 items: "1,2,3,4,5,none"

for 10 items: "1,2,3,4,5,6,7,8,9,10,none"

```
int Length=5; //I have five items to select from
char* dropdownoptions= "";
  if (Length<1){
    dropdownoptions="none";
  }else{
    char Answ[60]="1,";
    for (int i=1; i<=Length; i++){
      char part[3];
      String str=String(i+1);
      str.toCharArray(part, 3);
      strcat(Answ,part);
      strcat(Answ,",");
    }
    strcpy(dropdownoptions,Answ);
    strcat(dropdownoptions,"none");
  }
  Serial.println (dropdownoptions);

```

This code has been rewritten like 30 times and compiles, but crashes the board (esp8266) aka boot-looping

Ideally this is what I would like to do

```
dropdownoptions= "";
    for (int i=1; i<=Length; i++){
      dropdownoptions+=i;
      dropdownoptions+=",";
    }
    dropdownoptions+="none";

```

# Answer
As explained by chrisl in his answer, you have to declare `dropdownoptions` as an array of `char` large enough to hold the whole string, including the terminating `'\0'`. If you know beforehand the maximum value of `Length`, you could size the array accordingly. Otherwise, you may compute the required size as a function of `Length`:

```
int str_length;  // size of the string, including the final '\0'
if (Length < 10)
    str_length = 2 * Length + 5;
else
    str_length = 3 * Length - 4;  // assume Length < 100
char dropdownoptions[str_length];

```

Then you have to write the contents into this array. One way to do it would be to write each individual piece into a temporary array, then copy it to the array `dropdownoptions` by using string concatenation. My preferred way of filling the array, however, is the “zero-copy” method consisting of writing the pieces straight into the right place of the final array. This requires some pointer manipulation. If you are too uncomfortable with pointers, you may skip this answer. But if you want to learn and get some practice, please read on.

Let `p` be a pointer to the current array position where you want to write. You can pass this pointer to `sprintf()` in order to write a piece of data into the buffer at the right place. `sprintf()` returns the number of bytes written, not counting the terminating `'\0'`, and you can then advance the pointer `p` by this exact amount in order to know where to write the next piece. In code:

```
char *p = dropdownoptions;  // current write position
for (int i = 1; i <= Length; i++) {
    p += sprintf(p, "%d,", i);
}
sprintf(p, "none");

```

There is one drawback to using `sprintf()` though: if you get the size of the array wrong and too short, you will end up writing past its end and corrupting your memory. If you want to be defensive, you should keep track of the amount of available space remaining, and use the function `snprintf()` instead. This function takes, as a second parameter, the number of bytes available in the buffer, and it will never overflow that buffer. I find that the easiest way of keeping track of the remaining space is to initialize a pointer to the end of the array (technically, “one past the end” of the array), and compute the available space as `end-p`:

```
char *p = dropdownoptions;  // current write position
const char *end = dropdownoptions + str_length;  // end of the array
for (int i = 1; i <= Length; i++) {
    int count = snprintf(p, end - p, "%d,", i);
    p += min(count, end - p);
}
snprintf(p, end - p, "none");

```

The reason of `min()` being used here is that `snprintf()` may return a number larger than the available space: if the buffer is too small, this function returns the number of characters that *would had been written* (not counting the terminating `'\0'`) had the buffer been large enough.
> 1 votes

# Answer
The reason why your code crashes is, that you are trying to write to a non-valid pointer.

With the line

```
char* dropdownoptions= "";

```

you are declaring a pointer to a character (meaning a 2 bytes big memory address) and let it point to a string literal. All string literals are placed in the read-only section of the RAM by the compiler and cannot be changed. Thus with this line you only have a pointer (memory address), but not a buffer/memory space to write to. Later you are trying

```
strcpy(dropdownoptions,Answ);

```

which wants to write to the memory location/address, where `dropdownoptions` points to. But it is in the read-only section, it cannot be written, so your code crashes. And its better, that it crashes than writing data to some random memory location, where something important might be placed.

Doing

```
dropdownoptions="none"

```

is ok, since the literal string `"none"` is also placed in the read-only section. So in this case only the pointer changes, not the underlying data.

---

If you want to write to `dropdownoptions`, you need to declare it as a character array:

```
char dropdownoptions[70] = "";

```

Make it big enough, that it can hold the biggest string, that you expect. The rest of your code should then work like it is. Though the conversion from the integer `i` to a string can be done shorter:

```
char part[3];
itoa(i+1, part, 10);

```

Then `part` contains the number as null-terminated string, thus you can use the `strX` functions on it.
> 1 votes

---
Tags: esp8266, string
---


# Question
Title: Is there any way to efficiently code reading of four sensors and sending a serial output once it does detect a reading?
I am actually wondering if there's a way to efficiently do this block of code. There are two things in my specifications and these are:

1. Four IR Sensors that detects blockage. Basically just to trigger it HIGH or LOW
2. Once one of the sensors got tripped/triggered, it sends a Serial output

In order to do that, I made this code. Basically just stuffing digitalRead and their if conditions in the loop. Is there any way to make the code shorter all the while make it faster for the Serial to get sent?

```
#define IRSignal1 2
#define IRSignal2 3
#define IRSignal3 4
#define IRSignal4 5

int IRVal1;
int IRVal2;
int IRVal3;
int IRVal4;

void setup() {
  // put your setup code here, to run once:
  pinMode(IRSignal1, INPUT);
  pinMode(IRSignal2, INPUT);
  pinMode(IRSignal3, INPUT);
  pinMode(IRSignal4, INPUT);

  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  IRVal1 = digitalRead(IRSignal1);
  IRVal2 = digitalRead(IRSignal2);
  IRVal3 = digitalRead(IRSignal3);
  IRVal4 = digitalRead(IRSignal4);

  if (IRVal1 == LOW) {
    Serial.print('1');
  }
  if (IRVal2 == LOW) {
    Serial.print('2');
  }
  if (IRVal3 == LOW) {
    Serial.print('3');
  }
  if (IRVal4 == LOW) {
    Serial.print('4');
  }
}

```

If you have tips, or a go-to resource for efficient coding practices that also helps with memory allocation, shorter code, and speed, I would also love to hear them if that's alright with you.

I use both arduino mega and uno in case this information is useful.

# Answer
> 3 votes
There are always other ways to code something (at least if it's non-trivial). What does 'efficiency' mean to you, in this case? If speed is a concern, increase the baud rate. Whenever at least one sensor is HIGH for longer than one loop iteration, the serial output time will be controlling. Other ways to optimize speed would be to put your loop code in an infinite loop inside either the `loop()` function or the end of the `setup()` function, saving the call and and return and function entry code of the loop function. Likewise, you can read the input registers directly and save the four calls to `digitalRead()`.

But either of your Arduinos is more than fast enough (i.e., way faster than the phenomena it would be tracking), that there's little point in optimizing.

Update:

> As for my second statement under my code about efficient coding practices, its about memory allocation, speed, and shorter code because what if in the future there's going to be a dozen of IR Sensors there, sill it still maintain speeds?

Even your Uno is still fast enough, with enough memory, to manage a dozen such sensors to the level of processing demonstrated in your supplied code - and then some!

However, I would already be thinking ahead to processing multiple sensors without multiple repetitions of your code, which brings up another kind of efficiency: the best use of your time.

If you kept an array of sensor data and looped over it, processing each sensor in turn, one set of code that works correctly once, will work correctly 'n' times. It will be more easily read by someone else (or your future self who, if you're like me, has forgotten some of the details), and it will be easier to fix or expand if you only have to get it right in one place instead of 'n' places.

Want to change what the terminal output looks like when your project has grown to 12 or 14 sensors? It's *easy*, when you only have to get it right in one place!

I'd be thinking about an array of sensor data containing, for each sensor, its pin number, present state, and any information that might be relevant in the future - sensor location, for example.

Depending on how you expand your processing, you could conceivably run out of speed or memory, but based on your presented code, that day looks a ways off. And you did mention there is a Mega standing by ... :-)

# Answer
> 1 votes
As others have noticed, this code will be more than fast enough for its intended purpose, so you should not feel obliged to optimize it further. That being said, I do see an inefficiency that you may be interested in hearing about, hence this answer.

If an IR sensor turns LOW and *stays LOW*, the program will send the appropriate message repeatedly, as fast as it can. Since the code runs way faster than the serial port, this will soon fill up the serial port's output buffer. When this happens, `Serial.print()` will not be able to put its message into that buffer anymore. Facing this situation, it will switch from its regular *non-blocking* more of operation to a different, *blocking* mode. In this mode, it will block the program while waiting for the serial port to make some room in the buffer, and only then will it put its message there and return. The end result is that the program will be slowed down and match the speed of the serial port: only 960 executions of the `loop()` function per second.

An interesting side effect of this situation is that, when the sensor stops detecting some blockage, the Arduino will nevertheless continue sending the messages that say that a blockage is detected. It will continue doing so for about 66 ms: the time needed to empty the 63-byte serial output buffer.

If you are concerned about this issue, an easy way to alleviate it would be to increase the baud rate. This will not change the qualitative behavior, but it will make these things happen faster. I suggest you consider to instead change the communication protocol you have defined for the Arduino: instead of repeatedly sending information about the current state of the sensors, it could send information about the state *changes*. That is: one message is sent when a detector turns HIGH, and a different message is sent when it turns LOW. Alternatively, it could send the full state information (what sensors are LOW or HIGH) periodically, or every time that state changes, or a combination of both. I do not know what you are doing with this information on the other side of the serial link, so I cannot say which option may be the more appropriate for you.

You wrote in a comment that you may consider in the future driving a motor instead of sending serial messages. If you go this way, you will definitely have to work on state *changes*. In order to run continuously, a motor does not require you to repeatedly press the “ON” button a thousand times per second, and it will not turn off all by itself just because you stopped turning it on. Instead, you turn it on once and leave it alone, and it will stay on. When you want it to stop, you have to actively turn it off. The turn on/turn off actions are required only to *change* the state of the motor, not to keep the current state.

# Answer
> 0 votes
The simplest way to do this is with digital interrupt, however the limitation here is that the standard Uno has only 2 interrupt capable pins (2,3) so it would not work with 4 sensors. However other boards like the ESP8266 support interrupts on nearly all pins (just needs ICACHE\_RAM\_ATTR declaration in the function called)

```
void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  //attach interrupts to trigger function on pin state change
  attachInterrupt(digitalPinToInterrupt(2), pinAtriggered, CHANGE);
  attachInterrupt(digitalPinToInterrupt(3), pinBtriggered, CHANGE);
}

void loop(){
}
//if using ESP8266 it would look like this:
//ICACHE_RAM_ATTR void pinAtriggered() {
void pinAtriggered(){
  Serial.println("triggered");
}
void pinBtriggered(){
  Serial.println("triggered");
}

```

---
Tags: arduino-uno, arduino-mega, sensors, code-optimization
---


# Question
Title: 74HC595N breaks when not connected to 5V
I'm trying to build a simple LED controller using this shift register, however when I remove the 5V power source, the device breaks down. The error message was : "This device broke because of: Voltage at pin STCP is 5v, while maximum is Vcc = 0v". There isn't any current in the circuit to break it down. Can anyone explain to me why it behaves that way?

Basically, I connected the output of the register to resistors and LEDS. Here is my wiring diagram:

Here is my code:

```
const int SER  =8;   //Serial Output to Shift Register
const int LATCH =9;  //Shift Register Latch Pin
const int CLK  =10;  //Shift Register Clock Pin

void setup()
{
 //Set pins as outputs
 pinMode(SER, OUTPUT);
 pinMode(LATCH, OUTPUT);
 pinMode(CLK, OUTPUT);

 digitalWrite(LATCH, LOW);                //Latch Low
 shiftOut(SER, CLK, MSBFIRST, B10101010); //Shift Most Sig. Bit First
 digitalWrite(LATCH, HIGH);               //Latch High - Show pattern
}

void loop()
{
 //Do nothing
}

```

# Answer
> 0 votes
Yes, you should not disconnect Vcc from a chip as long as you have active signal lines running to it, which have a voltage level different than ground. To be safe: Just remove the power from your whole circuit before removing the power lines - or only remove the power lines once you have removed all other connections.

This depends on the used chip. But most chips with digital data/signal lines have internal protection diodes connected to the pins. If you provide a voltage above the limit, then a current can flow through the protection diode into the Vcc line of the chip. This is done to protect the internal hardware connected to the pin (since the whole chip can endure more than a single pin by its own).

With removing the Vcc connection to the chip you are lowering Vcc to ground level, so way below the level of a HIGH signal line. Thus the current can flow through the pins protection diode to Vcc and feed power to the chip through the signal pin. But the protection diodes are not made for enduring a significant power draw for more than very short spikes. So when doing that you can fry the protection diodes. And you cannot predict, if it will fail short (creating a short between the pin and Vcc, preventing further communication through this pin) or fail open, in which case the chip might still work (if the pins internal hardware is still OK).

For that reason some datasheets will define the voltage limits of the digital input pins dependent on Vcc. In the datasheet of the 75HC595 section 7.3 "Recommended Operating Conditions" you will see the "V\_I Input voltage" with the limits to be 0V and Vcc.

---
Tags: shift-register
---


# Question
Title: Writing multiple inputs to serial port using a while loop
I am trying to get the serial monitor to prompt me to input two settings - the PWM level and the Resonance level. I am being prompted to input the PWM level, but before I can input the Resonance level it is set to zero and then I am asked again for the PWM level.

I am using Serial.flush(); inbetween the commands to clear the serial input, but I still cannot input the Resonance level before it is set to zero.

Here is my code:

```
int PWMPin = 10;       // Pin 10 connects to MOSFET gate on breadboard
int ResPin = 4;        // Pin for the resonator stage

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);   // Define baud rate for console to be 9600
  pinMode(PWMPin, OUTPUT);
  pinMode(ResPin, OUTPUT);

}

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

Serial.println("What PWM level do you want to test?");   // Testing only
 while (Serial.available() == 0) {
     // Wait for user input
  }
  int test_level_PWM = Serial.parseInt();
    analogWrite(PWMPin, test_level_PWM);
    Serial.print("PWM Level: ");
    Serial.println(test_level_PWM);

Serial.flush();

Serial.println("What Resonance level do you want to test?");
 while (Serial.available() == 0) {
     // Wait for user input
  }
  int test_level = Serial.parseInt();
    analogWrite(ResPin, test_level);
    Serial.print("Resonance Level: ");
    Serial.println(test_level);

   delay(1000);

```

Here is the serial monitor output. I was able to input the PWM level but the Resonance level was set to zero immediately after and then I was asked to input the PWM level again.

# Answer
Your line

`Serial.flush();`

is probably intended to remove additional input after the expected numerical input. But that's not what it's doing. (See @jurai's comment)

Either avoid additional input like NewLine characters, or remove them using something like

`while (Serial.available()) {delay(1); Serial.read();}`

( The delay(1); takes care of slowly coming in serial data at 9600 Baud )
> 1 votes

---
Tags: arduino-uno, serial, pwm, input, analogwrite
---


# Question
Title: How many times can I upload a program or sketch to my Arduino Uno Clone Board?
I'm about to work on my very first project using arduino (I'm just about to buy one next week), and one of our professor says that we can only upload a program or sketch in an Arduino Uno Board for approximately 8 times. He also added that if we're using a clone version, it'll can only last for 2 sketch uploads. Is this true or is he bluffing? Thank you in advance.

# Answer
> 28 votes
He's talking complete and utter gibberish. To quote from the ATMega328P datasheet:

> * High Endurance Non-volatile Memory Segments
>     + 32KBytes of In-System Self-Programmable Flash program Memory
>     + 1KBytes EEPROM
>     + 2KBytes Internal SRAM
>     + ***Write/Erase Cycles: 10,000 Flash***/100,000 EEPROM
>     + Data Retention: 20 years at 85°C/100 years at 25°C(1)
>     + Optional Boot Code Section with Independent Lock Bits
>         - In-System Programming by On-chip Boot Program
>         - True Read-While-Write Operation
>     + Programming Lock for Software Security

So you have at least 10,000 uses out of it before it starts to go flakey.

# Answer
> -1 votes
I have firmware 94% flash - it took me a week to kill it. And this is a second device I killed this way. It's a Pro Micro clone. So I suggest solder a pcb with a reusablle port to change the card

---
Tags: arduino-uno
---


title: Adafruit thermal printer prints weak

text:
# Question
Title: Adafruit thermal printer prints weak
I am currently hooking up my arduino to an adafruit mini thermal printer. When a button is pressed, some code is executed which then sends some information to the thermal printer.

Everything works fine except the thermal printer print is very weak and can barely be seen as soon as the printer needs to print more than 3-5 chars. Any ideas why? Both, the arduino and the thermal printer are hooked up to 9V batteries.

Here is the code

```
#include "Adafruit_Thermal.h"

// Here's the new syntax when using SoftwareSerial (e.g. Arduino Uno) ----
// If using hardware serial instead, comment out or remove these lines:

#include "SoftwareSerial.h"
#define TX_PIN 6 // Arduino transmit  YELLOW WIRE  labeled RX on printer
#define RX_PIN 5 // Arduino receive   GREEN WIRE   labeled TX on printer

SoftwareSerial mySerial(RX_PIN, TX_PIN); // Declare SoftwareSerial obj first
Adafruit_Thermal printer(&mySerial);     // Pass addr to printer constructor

int buttonIn = 8;
int val = 0;

void setup() {
  pinMode(7, OUTPUT);
  digitalWrite(7, LOW);

  pinMode(buttonIn, INPUT);

   mySerial.begin(19200);  // Initialize SoftwareSerial
   //Serial.begin(19200); // Use this instead if using hardware serial
   printer.begin();        // Init printer (same regardless of serial type)
}

void loop() {
  // put your main code here, to run repeatedly:
     val = digitalRead(buttonIn);
     if(val == HIGH)
     {
        printer.println("test");
        printer.sleep();      // Tell printer to sleep
        delay(3000L);         // Sleep for 3 seconds
        printer.wake();       // MUST wake() before printing again, even if reset
        printer.setDefault();

     }
}

```

Did I set up anything false? Is the power supply not enough? The adafruit was sent with a selftest from the seller where everything seemed to be fine.

Left, seller test, second from left, my selftest, third and fourth from left are example printer and charset tests.

And here you can see how everything is wired together.

Thank you very much!

# Answer
The datasheet states:
Requires 5-9VDC @ 1.5Amp power supply during print.

In my experience this printer provides best results when operated at its upper limit. I am using a 9V 2A power supply for that. A bettery is definitiverly not enough.
> 2 votes

# Answer
Proper care of your thermal transfer printer is critical to keeping it at peak performance for as long as possible. Keep reading for five tips to keep your thermal transfer printer running optimally so you don’t have to spend on unnecessary new parts or wasted media down the line.

1. Maintain The Right Heat And Speed Ratio These two things are true:

High print speeds can improve throughput Higher heat increases the darkness of your print and therefore the contrast of your barcodes. However, the wrong ratio can lead to print issues and even damage your printhead.

We generally recommend running your printer on a relatively slow setting. This uses less heat and ensures a crisp, clear printed image. On a similar note, we recommend you avoid increasing heat settings without guidance from a professional.

If you work with a supplier who sets up and tests your printer with your media prior to shipping it to you, they have likely adjusted the heat and speed ratio to one suitable for your application.

Maintaining a proper heat and speed ratio will ensure a scannable barcode and extend the life of your printhead so you can avoid costly waste and unnecessary part replacements.

2. Keep The Print Head Clean Keeping your print head clean is imperative to maintaining your printer. Without regular cleaning, your print head will be more susceptible to abrasion during printing. This can reduce image quality and shorten the life of your printer.

We recommend you establish a schedule for regular print head cleaning. Our technical team endorses cleaning this part whenever you replace the label roll or install a new ribbon.

3. Protect The Print Head From The Media To safeguard the print head against abrasion, use a thermal transfer ribbon that’s slightly wider than the media.
4. Don’t Use Razor Blades Or Box Cutters Unless you’re using a model with a peeler or applicator, you should only use tools such as the printer’s tear bar or scissors to remove labels. Razor blades, box cutters, and other inappropriate tools can easily slip and cut the driver roller. These cuts can create voids in your printed labels leading to misreads.
5. Avoid “Ribbon Wrinkles” If you’re seeing seemingly random diagonal lines on your print you’re probably dealing with ribbon wrinkles. The main culprit of ribbon wrinkles is too much heat, so your first option is to lower the heat setting. If that doesn’t work, make sure your printer is set up properly. Check that the ribbon is loaded correctly, the media guides are set properly, and the head pressure is balanced. If you’re still experiencing issues you might want to reach out to your supplier to ensure your media and ribbon combination is ideal.

Regards, Peter
> 0 votes

---
Tags: arduino-uno, serial, softwareserial, adafruit, serial-data
---


# Question
Title: How to connect a thermal printer to an ESP32?
I want to attach my GOOJPRT Thermal Printer (I believe model QR701, communication RS232) to my ESP32 but I cannot seem to get them working.

I tried all the Adafruit Thermal Printer library examples but get the same error each and every time:

```
"Error compiling for board ESP32 Dev Module."

```

I guess the libraries are not meant for the ESP32. I also tried the "Thermal Printer Library" by Larry Bank (which should be compatible with the ESP32 according to its github docs) but there I cannot figure out how to connect the wires of thermal printer to the ESP32 correctly.

Of course, I do not ask for a specific solution, I am just looking for someone to point me in the right direction!

This is an image of the exact thermal printer I have

*Full error message from Adafruit Thermal Printer examples:*

```
C:\Users\Thomas\Documents\Arduino\libraries\SoftwareSerial-master\SoftwareSerial.cpp:41:27: fatal error: avr/interrupt.h: No such file or directory
compilation terminated.
Multiple libraries were found for "Adafruit_Thermal.h"
 Used: C:\Users\Thomas\Documents\Arduino\libraries\Adafruit_Thermal_Printer_Library
 Not used: C:\Users\Thomas\Documents\Arduino\libraries\Adafruit-Thermal-Printer-Library-master
Multiple libraries were found for "SoftwareSerial.h"
 Used: C:\Users\Thomas\Documents\Arduino\libraries\SoftwareSerial-master
 Not used: C:\Users\Thomas\Documents\Arduino\libraries\EspSoftwareSerial
exit status 1
Error compiling for board ESP32 Dev Module

```

*Second error message from Adafruit Thermal Printer example after removing the manually installed SoftwareSerial.h:*

```
A_printertest:21:28: fatal error: SoftwareSerial.h: No such file or directory
Multiple libraries were found for "Adafruit_Thermal.h"
compilation terminated.
 Used: C:\Users\Thomas\Documents\Arduino\libraries\Adafruit_Thermal_Printer_Library
 Not used: C:\Users\Thomas\Documents\Arduino\libraries\Adafruit-Thermal-Printer-Library-master
exit status 1
SoftwareSerial.h: No such file or directory

```

# Answer
> -1 votes
You need to use the \<HardwareSerial. h\> library. SoftwareSerial is for Arduino boards. "Thermal Printer Library" by Larry Bank is for GOOJPRT PT-210 and uses Bluetooth. Won't work for QR-701. Instead of using Adafruit Library, you can try with this: ThermalPrinter.

This May Help, Peter

---
Tags: esp32
---


# Question
Title: Serial communication between python and Arduino nano BLE sense 33 for running six DC motor
I am controlling six DC motors by varying their voltage. I have figured out the voltage required for each motor in python; now it's time to send this voltage through Arduino Nano BLE Sense 33 to run the six DC motors via serial communication. Can anyone help me to figure out its solution?

```
Python Code:

from time import sleep
import serial
import struct
ser = serial.Serial('COM7', 9600)

while True:
     ser.write(struct.pack('BBBBBB',200,210,220,230,240,180))  ## PWM
     ser.readline()
     sleep(.5)

Arduino Code:
const int ledPin[6] = {4, 7, 8, A5, 13, A0};
const int ledPin1[6] = {2, 6, 9, A4, 12, A1};
const int ledPin2[6] = {3, 5, 10, A3, 11, A2};

int x;
void setup() {
  Serial.begin(9600);
  for (int k = 0; k < 6; k++) {
    pinMode(ledPin[k], OUTPUT);
    pinMode(ledPin1[k], OUTPUT);
    pinMode(ledPin2[k], OUTPUT);
  }
  Serial.setTimeout(1);
}
void loop() {
  for (int i = 0; i < 6; i++) {
    while (!Serial.available());
    x = Serial.readString().toInt();
    dir(ledPin[i], x, ledPin1[i], ledPin2[i]);
  }
}

float dir(int Pin, float x, int Lpin1, int Lpin2) {
  analogWrite(Pin, abs(x));
  if (x < 0) {
    digitalWrite(Lpin1, HIGH);
    digitalWrite(Lpin2, LOW);
  }
  else if (x > 0) {
    digitalWrite(Lpin1, LOW);
    digitalWrite(Lpin2, HIGH);
  }
  else {
    digitalWrite(Lpin1, LOW);
    digitalWrite(Lpin2, LOW);
  }
}

```

# Answer
> 0 votes
Here is your Arduino `loop()` should look like:

```
void loop()
{
    if(Serial.available() > 0)
    {
        for (int i = 0; i < 6; i++)
        {
            while (!Serial.available());
            int x = Serial.read();
            dir(ledPin[i], x, ledPin1[i], ledPin2[i]);
        }
    }
}

```

Haven't tested it though.

---
Tags: arduino-ide, communication, python
---