title: Bluetooth module(HC 05) issues

text:
# Question
Title: Bluetooth module(HC 05) issues
I am trying to make a Bluetooth controlled 4WD robot. i was following a tutorial i found online (https://howtomechatronics.com/tutorials/arduino/arduino-robot-car-wireless-control-using-hc-05-bluetooth-nrf24l01-and-hc-12-transceiver-modules/). After successfully connecting my 2 HC 05 Bluetooth module i used the script from the tutorial and modified it slightly so it would work for my set up. The code for the robot:

```
//Code for Slave
#define enA 9
#define in1 8
#define in2 7
#define enB 10
#define in3 6
#define in4 5
int xAxis, yAxis;
unsigned int  x = 0;
unsigned int  y = 0;
int motorSpeedA = 0;
int motorSpeedB = 0;
void setup() {
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  Serial.begin(9600); // Default communication rate of the Bluetooth module
}
void loop() {
  // Default value - no movement when the Joystick stays in the center
  x = 510 / 4;
  y = 510 / 4;
  // Read the incoming data from the Joystick, or the master Bluetooth device
  while (Serial.available() >= 2) {
    x = Serial.read();
    Serial.print("X: ");
    Serial.println(x);
    delay(10);
    y = Serial.read();
    Serial.print("Y: ");
    Serial.println(y);
  }
  delay(10);
  // Convert back the 0 - 255 range to 0 - 1023, suitable for motor control code below
  xAxis = x*4;
  yAxis = y*4;
  // Y-axis used for forward and backward control
  if (yAxis < 470) {
    backMov;
    // Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  }
  else if (yAxis > 550) {
    fowardMov;
    // Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(yAxis, 550, 1023, 0, 255);
    motorSpeedB = map(yAxis, 550, 1023, 0, 255);
  }
  // If joystick stays in middle the motors are not moving
  else {
    motorSpeedA = 0;
    motorSpeedB = 0;
  }
  // X-axis used for left and right control
  if (xAxis < 470) {
    // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
    int xMapped = map(xAxis, 470, 0, 0, 255);
    // Move to left - decrease left motor speed, increase right motor speed
    motorSpeedA = motorSpeedA + xMapped;
    motorSpeedB = motorSpeedB - xMapped;
    // Confine the range from 0 to 255
    if (motorSpeedA > 255) {
      motorSpeedA = 255;
    }
    if (motorSpeedB < 0) {
      motorSpeedB = 0;
    }
  }
  if (xAxis > 550) {
    // Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
    int xMapped = map(xAxis, 550, 1023, 0, 255);
    // Move right - decrease right motor speed, increase left motor speed
    motorSpeedA = motorSpeedA - xMapped;
    motorSpeedB = motorSpeedB + xMapped;
    // Confine the range from 0 to 255
    if (motorSpeedA < 0) {
      motorSpeedA = 0;
    }
    if (motorSpeedB > 255) {
      motorSpeedB = 255;
    }
  }
  // Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
  if (motorSpeedA < 70) {
    motorSpeedA = 0;
  }
  if (motorSpeedB < 70) {
    motorSpeedB = 0;
  }
  analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
  analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
}
void fowardMov(){
  digitalWrite(in2,HIGH);
  digitalWrite(in4,HIGH);
  digitalWrite(in1, LOW);
  digitalWrite(in3, LOW);
}

void backMov(){
  digitalWrite(in1,HIGH);
  digitalWrite(in3,HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in4, LOW);
}

```

The code for the Controller:

```
#define Xaxis A0
#define Yaxis A1

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

void loop() {
  // put your main code here, to run repeatedly:
 Serial.write(analogRead(Xaxis)/4);
 Serial.write(analogRead(Yaxis)/4);
 delay(20);
}

```

After uploading the code i tried to move it but it wasn't working so i put print statements to see the value of X and Y. initially it didn't work so i swapped the Bluetooth modules i had and reconnected them. i also changed this line.

```
 while (Serial.available() >= 2)

```

To this

```
 if (Serial.available() > 0)

```

i started to receive values from the master to the slave but i noticed the values were the same for x and y so i searched for another tutorial on the internet and found this (https://create.arduino.cc/projecthub/andriy-baranov/arduino-4wd-rc-car-639953?ref=similar&ref\_id=18369&offset=3) reading his code i wondered how did the slave work. According to the official Arduino documentation Serial.read() does not take in any arguments but i still tried it and it didn't work. I decided to retry the code from the first tutorial i checked this time it looked like it was working so i tried moving the joystick and the serial monitor printed correct values for both at first then it swaps their values then freezes. How can i stop it from freezing and swapping the values? Also why doesn't the while loop run forever isn't the amount of data in the serial buffer always higher than 2? Thank you.

# Answer
> 1 votes
There is an issue with the way in which the data is sent and received because it assumes the transmission will remain perfectly synchronised for the lifetime of the programme. Consider what would happen if one byte were to be dropped due to a communication error – the x and y data would be swapped for further transmissions.

**Original Sender**

```
void loop() {
  // put your main code here, to run repeatedly:
 Serial.write(analogRead(Xaxis)/4);
 Serial.write(analogRead(Yaxis)/4);
 delay(20);
}

```

**Original Receiver**

```
void loop() {
  // Default value - no movement when the Joystick stays in the center
  x = 510 / 4;
  y = 510 / 4;
  // Read the incoming data from the Joystick, or the master Bluetooth device
  while (Serial.available() >= 2) {
    x = Serial.read();
    Serial.print("X: ");
    Serial.println(x);
    delay(10);
    y = Serial.read();
    Serial.print("Y: ");
    Serial.println(y);
  }
  delay(10);
  . . .
}

```

Therefore, there needs to be a way to synchronise to the first byte of the message. This can be achieved by using message packets where the start and end of the message are delimited with unique characters, e.g. `{` and `}`, similar to the JSON format.

As another example, the NMEA GPS standard uses `$` and `\n` to delimit messages, and `,` to delimit fields. It also has a checksum at the end.

Here is a non-blocking algorithm which builds upon Majenko's `readline()` example and the Blink Without Delay example to read a packet. `ReadPacket()` returns true when incoming data has been accumulated into a valid packet. The LED is flashed to indicate that the MCU hasn't frozen.

**New Sender**

```
void loop()
{
    Serial.print("{");                  // First character delimiter.
    Serial.print(analogRead(Xaxis));    // Full resolution. No need to divide by 4.
    Serial.print(",");                  // Field delimiter.
    Serial.print(analogRead(Yaxis));    // Full resolution. No need to divide by 4.
    Serial.print("}");                  // Last character delimiter.
    delay(20);
}

```

**New Receiver**

```
void loop()
{
    //
    // TASK 1: Blink without delay to indicate that MCU hasn't frozen.
    //
    const unsigned int INTERVAL = 250;
    unsigned long current_timestamp = millis();
    static unsigned long previous_timestamp = current_timestamp;
    static bool led_state = false;
    if (current_timestamp - previous_timestamp >= INTERVAL)
    {
        led_state = !led_state;
        digitalWrite(LED_BUILTIN, led_state);
        previous_timestamp += INTERVAL;
    }

    //
    // TASK 2: Read and parse data packet.
    //
    static char packet[100];
    const byte NUM_FIELDS = 2;
    unsigned int fields[NUM_FIELDS];
    static unsigned int x = 512;   // Full resolution. No need to divide by 4.
    static unsigned int y = 512;   // Full resolution. No need to divide by 4.
    bool new_x = false;
    bool new_y = false;
    if (ReadPacket(Serial, packet, sizeof(packet)))
    {
        Serial.print(F("Received packet >"));
        Serial.print(packet);
        Serial.println(F("<"));

        // Parse the packet for x and y values at full resolution.
        const char delimiters[] = "{,}";
        char* field;
        int i = 0;
        field = strtok(packet, delimiters);
        while (field != NULL && i < NUM_FIELDS)
        {
            Serial.print("field = ");
            Serial.println(field);
            fields[i] = atoi(field);
            Serial.print("fields[");
            Serial.print(i);
            Serial.print("] = ");
            Serial.println(fields[i]);
            field = strtok(NULL, delimiters);
            i++;
        }
        if (i == NUM_FIELDS)
        {
            if (x != fields[0])
            {
                new_x = true;
                x = fields[0];  // Full resolution. No need to multiply by 4.
                Serial.print("New x = ");
                Serial.println(x);
            }
            if (y != fields[1])
            {
                new_y = true;
                y = fields[1];  // Full resolution. No need to multiply by 4.
                Serial.print("New y = ");
                Serial.println(y);
            }
        }
    }

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

    //
    // TASK 3: Process x and y values.
    //
    if (new_x || new_y)
    {
        Serial.println("Processing new values.");

        . . .
    }
}

bool ReadPacket(Stream& stream, char *const packet, const unsigned int SIZE)
{
    const char FIRST = '{';
    const char LAST = '}';
    static bool read_until_last = false;
    static unsigned int i = 0;
    char ch;

    if (stream.available())
    {
        ch = stream.read();

        if (ch == FIRST)
        {
            Serial.println(F("Received FIRST."));
            i = 0;
            packet[0] = ch;
            read_until_last = true;
            return false;
        }
        if (read_until_last)
        {
            i++;
            if (i > SIZE - 2)
            {
                Serial.println(F("Buffer overrun. Resetting to look for next packet."));
                i = 0;
                read_until_last = false;
                return false;
            }
            if (ch == LAST)
            {
                Serial.println(F("Received LAST."));
                packet[i++] = ch;
                packet[i] = 0;
                read_until_last = false;
                return true;
            }
            else
            {
                Serial.print(F("Received char >"));
                Serial.print(ch);
                Serial.println("<");
                packet[i] = ch;
                return false;
            }
        }
    }
    return false;
}

```

# Answer
> 0 votes
Your setup is WAY too complex! Simplify your setup to the point where it only deals with just the piece that is giving you problems; in your case serial port comms between master and slave. Solve JUST THAT problem, and then move on

---
Tags: serial, programming, bluetooth
---


# Question
Title: How to gradually increase and decrease the speed of a motor using IR remote
I am making an IR controlled helicopter and I have the very basic part of the code done, but I don't know how to make the motor gradually increase speed. I want the motor to gradually increase speed when you hold the button on the IR remote and hold its speed when you stop pushing the button. And the same for when the helicopter goes down. Here is the code:

```
   #include <IRremote.h>
   #include <Servo.h>
   #define enA 9
   #define enB 11
   #define in1 6
   #define in2 7
   #define in3 4
   #define in4 5

   Servo ball1;

   int IR_RECEIVE_PIN = 2;
   IRrecv IrReceiver(IR_RECEIVE_PIN);
   decode_results results;

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

     ball1.attach(10);

     pinMode(in1, OUTPUT);
     pinMode(in2, OUTPUT);
     pinMode(in3, OUTPUT);
     pinMode(in4, OUTPUT);
   }
   void loop() {
     if (IrReceiver.decode(&results)) {
       switch (results.value) {

         case 0xFFA857:
           Serial.println("case: UP");
           digitalWrite(enA, 255);
           digitalWrite(in1, HIGH);
           digitalWrite(in2, LOW);
           break;

         case 0xFFE01F:
           Serial.println("case: DOWN");
           digitalWrite(enA, 120);
           digitalWrite(in1, LOW);
           digitalWrite(in2, LOW);
           break;

         case 0xFF18E7:
           Serial.println("case: FORWARD");
           ball1.write(90);
           break;

         case 0xFF10EF:
           Serial.println("case: LEFT");
           digitalWrite(in3, LOW);
           digitalWrite(in4, LOW);
           break;

         case 0xFF5AA5:
           Serial.println("case: RIGHT");
           digitalWrite(in3, HIGH);
           digitalWrite(in4, LOW);
           break;

         case 0xFF48B5:
           Serial.println("case: BACKWARD");
           ball1.write( ? ); // I need help on the direction of the linear servo
           break;
       }

       Serial.println(results.value, HEX);
       IrReceiver.resume();
     }
   }

```

It is the same code I used to control a RGB LED (But modified). Would it be possible to upload this code to an IC? I already programmed my UNO as an ISP, but there seems to be a problem. Also, I am using a linear servo for the pitch of the helicopter, can someone please show me how to change the direction of a linear servo? I have one that is similar to the Pico linear servo.

# Answer
> 0 votes
You could separate reading the controls and taking actions and there are several ways of doing that, one example shown below where the switch() can be used to read all commands and according to the value call one or more atomic functions. For instance, one function to change speed and another one to change direction, and perhaps calling several functions in a row for more complex tasks like take off and land (I have no idea how those helicopter projects works).

On each case you do the validation, min and max allowed values, dependencies on other factors and alike.

```
void loop() {

  if (IrReceiver.decode(&results)) {

    switch (results.value) {

      case 0xFFA857: // up
        verticalSpeed = verticalSpeed + verticalSpeedStep;
        if (verticalSpeed > maxVerticalSpeed) verticalSpeed = maxVerticalSpeed;
        setVericalMotor();
        break;

      case 0xFFE01F: //down
        verticalSpeed = verticalSpeed - verticalSpeedStep;
        if (verticalSpeed < 0) verticalSpeed = 0;
        setVericalMotor();
        break;

    }
  }
}

void setVericalMotor() {
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(enA, verticalSpeed);
}

```

As for your question regarding the servo, they usually run from 0 to 180 degrees, so tey anything in that range as the "reverse" for 90 degrees for Forward (normally that should be 0 or 180).

---
Tags: motor
---


title: consecutive analogRead()

text:
# Question
Title: consecutive analogRead()
Has anyone noticed that if calling `analogRead()` in a consecutive way that the value drops by a bit as opposed to just doing a single read?

And is this to be expected?

I am using a Seeeduino XIAO.

# Answer
You need a short delay between analog reads due to the time it takes to complete a reliable ADC reading. In depth technical explanations can be found here, note that it refers to AVR architecture.
> 1 votes

---
Tags: analogread
---


title: LCD display weird characters

text:
# Question
Title: LCD display weird characters
Im a newbie. I have a problem with displaying text in LCD (16x2). It shows incorrect message in the lcd. Here is the code and the picture that gives the wrong output : Kindly help Thank you.

```
#include "SIM900.h"
#include <SoftwareSerial.h>

#include "sms.h"
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//gsm
SMSGSM sms;

int numdata;
boolean started  = false;
char smsbuffer[160]; //message
String newsms;
char n[20];
unsigned char i;
//lcd
int sensorPin = A0;    // select the input pin for the potentiometer
int sensorValue = 0;  // variable to store the value coming from the sensor
int outputValue = 0;   // value output to the %
int outputValue1 = 0;   // value output to cursor

void setup()
{
  //Serial connection.
  //gsm
    lcd.begin(16, 2);

  Serial.begin(9600);

//  lcd.setCursor(0, 1);
//  lcd.clear();
//  lcd.print("   Wireless Public       via GSM"); //55 chars
//  lcd.setCursor(0, 2);
//  lcd.print("    Notice Board "); //55 chars
   Serial.println("GSM Shield testing.");
  if (gsm.begin(2400)) {
    Serial.println("\nstatus=READY");
    started = true;
  }
  else Serial.println("\nstatus=IDLE");

  //lcd
  // set up the LCD's number of columns and rows:

};

void loop()
{

  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 1023, 0, 100);
  outputValue1 = map(sensorValue, 0, 1023, 0, 200);

  //scroll = lcd.scrollDisplayLeft();
  if (started) {
    //Read if there are messages on SIM card and print them.
    if (gsm.readSMS(smsbuffer, 160, n, 20))
    {
      //lcd
      lcd.clear();
      lcd.setCursor(0, 2);
      lcd.print("SMS Received!");
      delay(2000);
      lcd.clear();
      lcd.setCursor(0,1);
      Serial.println(n);
      Serial.println(smsbuffer);
      lcd.print(smsbuffer);
      delay(1000);
//      lcd.clear();
    }
    delay(1000);
  }
}

```

# Answer
> 1 votes
The first thing to try is replacing `lcd.begin(16, 2)` with `lcd.begin(20, 4)`. The image of your LCD looks like a 20 char by 4 line display. Based on your comments, it seems that the SMS part of your code is working because it's outputting the correct characters to the serial monitor. I would focus on the LCD code and connections to your Arduino.

# Answer
> 1 votes
I arrived a little late; however I'm leaving some further information to Debug similar problems for those who arrive here in the Future.

**Regarding the Question**

As already answered above:
\- You are specifying your LCD as a 16 Column with 2 Rows (1602); and in your picture you clearly have a 20 Column with 4 Rows.

**Change:**

```
lcd.begin(16, 2);

```

**To:**

```
lcd.begin(20, 4);

```

**How LCD Works**

Take into consideration that LCD works as a Matrix and both Columns and Rows are Zero Based Index. That is; when you set the LCD Cursor Columns or Rows; you start counting with 0.

See Example Bellow:

```
lcd.setCursor(0, 2);

```

The 1st Parameter (Zero) Represents Columns.
The 2nd (Two) Represents Rows.

Therefore on the 1st Parameter: "0" (Column); (Considering you're reading from Left to Right and Top to Bottom); You Set the Cursor on the very 1 Column on the LCD.

The 2nd Parameter (2): you’l be Setting char on the 3rd Row (Line).

**Note:** 3rd and not 2nd; because both Columns and Rows are "Zero Based" Indexed.

**Debugging LCD Issues**

1. Check If your LCD is Properly Wired. You may have switched a wire; wire not properly plugged or broken. Specially if you’re not using a I2C back module). Wiring without I2C (“I Squared C”) module can be confusing in certain occasions.
2. Check your Library and Hardware. Make sure you’re using the correct library (I2C library: if your LCD has the module: use a compatible I2C Library; and specify the LCD parameters accordingly). In case you don’t have a I2C module; then use a library to with a workaround for that situation. (You specify all the Pins).
3. Check you Code: Check the way you initialize your LCD. i.e: lcd.begin(16,2); or lcd.begin(20, 4);
4. Make sure you print inside LCD Index. Setting the cursor outside its bounds can also cause “weird” chars.
5. There can be other situations related with improper wiring or some sort of short circuit with other components connected to your project that can also produce weird characters.
6. In certain circumstances; pressing Reset; Cutting the Power for a little while or Re-Uploading the project fixes the issue.
7. Not clearing the LCD whenever there is New data can simulate the effect of weird characters; but actually they are old data characters that remained there.

**Writing Custom Characters to LCD**

As you've Probably Noticed you are Unable to print the a Custom Character (i.e: Degree Symbol) on your LCD. That can be solved by Creating your own (Custom) char and Declare it on your Code. I won't explain every detail, in order to avoid going off topic and to avoid providing an extensive and hard-to-read answer. Instead will leave an example, that is easy to understand and 2 Links bellow with further information regarding Custom Characters.

**Links:**

**Example for Degree Character**

```
/* LCD Custom Characters
*******************************************/
// This is your Char Definition in Bytes:
byte DegreeDef[8] = { B01100, B10010, B10010, B01100, B00000, B00000, B00000, B00000 };

// This is the byte Char to be used to write to LCD.
const byte Degree = 0x2;

void LCDInitialization()
{
  // LCD Initialiation Code Here
  // ...

  // Initialize Custom Characters.
  lcd.createChar(2, DegreeDef);

  // Do Something Else...
}

void PrintToLCD()
{
  // Note:
  // "lcd.write" is Different from "lcd.print".
  // Use "write" to Print your Custom LCD Characters.
  lcd.setCursor(0, 1);
  lcd.write(Degree);
}

```

I hope this helps debugging your issue.

# Answer
> 1 votes
Hello I had the same problem and noticed that if you setup the lcd screen in this order:

```
LiquidCrystal lcd (d7, d6, d5, d4, , en, rs) ;

```

you get some weird character showing up... but if you do this way:

```
LiquidCrystal lcd (rs, en, d4, d5, d6, d7) ;

```

you don't get any weird character.

---
Tags: arduino-uno, lcd, gsm, potentiometer
---


# Question
Title: I am in need of a usable communication library on 1-4 pins of ATTiny84 instead of I2C
I messed up when designing my PCB and just assumed that I could use software slave I2C with ATTiny84.

The reason I did so is - I needed to use all of the analog inputs.

The pins I have on my connector are:

PB0 (pin 2), PB1 (pin 3), PB2 (pin 5) and PA0 (pin 13)

Is there an alternative to I2C or a different communication protocol I could use to connect multiple of these slave boards to a master (ATMEGA328 etc.)?

Thanks a lot, I can provide any further information.

# Answer
> 1 votes
That is a lot of pins, so this really boils down to your application and what you want to optimize for.

You could do a bit-banged software I2C slave on these pins. "Bit-bang" means you just write a program to flip the bits on the pins rather than handing the bytes off to the hardware which would do the same thing (although sometimes faster or without using up CPU cycles). This would require either finding some existing code to implement the protocol, or sitting down with the documentation for the protocol and writing it yourself. Depending on your goals, the second option might be a great learning experience and take away some of the magic from this stuff. It is all just 1s and 0s and once you really internalize that, you realize that you can do almost anything with these little chips regardless of hardware or library support.

---
Tags: i2c, communication, attiny
---


title: SN76489 - Ready pin not working?

text:
# Question
Title: SN76489 - Ready pin not working?
I'm testing the **SN76489AN** chip with Arduino and I'm able to play the 3 tones I want etc BUT I don't understand why the READY pin is not working? The datasheet says the pin goes high when the chip is ready and low when it's busy with processing a command. But the **READY pin is always low!** I've got 2 brand new pieces of the chip and they both act this way. I've even tried to pull-up this pin but it didn't help. I see everyone is just using `delayMicroseconds` in their examples, so I guess it is a common problem but it's just strange... Is it a bug in the chip or what? Does anyone know?

Thanks!

# Answer
> 2 votes
The READY signal is open-collector. It will therefore require a pullup-resistor. Test circuit in datasheet shows a 2 kohm resistor. You could try with that. Alternatively use the internal pullup resistor on the input pin but this may be too large (weak).

Cheers!

# Answer
> 0 votes
I had this problem, but the mistake was that I had missed the clock pin on my breadboard by one row, so there was no clock signal.

---
Tags: audio
---


# Question
Title: Rounding to the next upper (or lower) 0.1
I'm reading from a temperature sensor. I get float values with 2 decimals. I want to round them to nearest 0.1.

This is my sketch:

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

void loop() {
  float temperature = 21.81;
  float rounded_temperature = round(temperature * 10) / 10.0;
  Serial.print("21.81 ->");
  Serial.println(rounded_temperature);
  delay(1000);

  temperature = 21.79;
  rounded_temperature = round(temperature * 10) / 10.0;
  Serial.print("21.79 ->");
  Serial.println(rounded_temperature);
  delay(1000);

  temperature = 21.77;
  rounded_temperature = round(temperature * 10) / 10.0;
  Serial.print("21.77 ->");
  Serial.println(rounded_temperature);
  delay(1000);

  temperature = 21.70;
  rounded_temperature = round(temperature * 10) / 10.0;
  Serial.print("21.70 ->");
  Serial.println(rounded_temperature);
  delay(1000);
}

```

This is the output:

```
21.81 ->21.85
21.79 ->21.75
21.77 ->21.75
21.70 ->21.75

```

And this is the output I would... Rounded to "0" and not "5".

```
21.81 ->21.80
21.79 ->21.80
21.77 ->21.80
21.70 ->21.70

```

# Answer
Using roundf() function:

float rounded\_temperature = roundf(temperature * 10) / 10;
> 3 votes

# Answer
`float` variables do not have a number of decimal places. They are merely an approximation anyway. Instead it's when you *print* that you decide how many decimals to display.

```
Serial.println(temperature, 1); // Print with 1 decimal place

```

Or to put it into a string:

```
char buf[8]; // Room for 7 characters plus NULL terminator
float val=23.81;

dtostrf(val, -7, 1, buf); // 7 characters with 1 decimal place and left aligned (negative width)

```
> 1 votes

# Answer
I often store the floating point data that I get from a sensor in integer to preserve the decimal precision that I want by multiple it by 10 before casting it into an integer. It is easier and more efficient (compare to string or float) to send over to another system. This is also how many sensors representing and store the floating data (e.g. TMP275) as well.

To achieve what you want, here is what I would do:

```
#include <math.h>

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

  float i=21.81;
  float j=21.79;
  float k=21.77;
  float p=21.70;

  // convert to integers
  int l = (int) round(i*10);  // 218
  int m = (int) round(j*10);  // 218
  int n = (int) round(k*10);  // 218
  int o = (int) round(p*10);  // 217

  // Convert back to actual floating point for display
  Serial.println((float)l/10);  //21.80
  Serial.println((float)m/10);  //21.80
  Serial.println((float)n/10);  //21.80
  Serial.println((float)o/10);  //21.70
}

```
> 1 votes

---
Tags: programming
---


title: Replace CH340 With FTDI

text:
# Question
Title: Replace CH340 With FTDI
I have built a arduino midi octapad with a Clone of arduino nano that contain a ch340 chip but hairless midi says FTDI driver doesn't installed i installed that driver but it still show that error so can i replace the ch340 chip with a FTDI chip to resolve this Problem... ?

# Answer
> 1 votes
When you search for "FTDI" in one of the hairless-midiserial repos on github (I looked at this and this one), you find what looks like your error message (though you didn't actually put it in your question:

```
./src/PortLatency_win32.cpp:        emit debugMessage("FTDI drivers don't seem to be installed. Not attempting any FTDI latency tricks.");

```

Also the repos have a class in PortLatency.h with the description:

```
A simple class to manage latency reduction of FTDI-based serial ports.

```

This gives us some information:

* The message above is not an error message, but a debug message. It might work despite not having an FTDI
* The class description suggests, that the program wants to use some tricks to reduce the latency in the communication. These tricks seem to be FTDI specific. When the above debug message appears, these tricks are not used. Thus your performance may be significantly worse than with an FTDI chip. Also one of the repos has an open issue about problems with the CH340, which states, that it just doesn't work correctly. It was updated in May and still has no solution. I would not bet on getting help there. (Also the ground repo, that the other was forked off, wasn't updated since 5 years.)
* You cannot fix that debug message by installing the FTDI drivers, because you don't use an FTDI chip.

As we are on Arduino SE here, we cannot really help you with that program running on your PC.

Of course you can use an extra FTDI chip/board and connect it to the RX and TX lines of the Arduino (not using the CH340 USB serial chip on the Arduino itself). But I support Majenkos comment about just migrating to an Arduino with native USB connection (means the USB communication is done by the Arduinos microcontroller directly, not by an extra chip) (for example the Micro, but there are a lot more Arduinos with native USB). That enables you to manipulate the type of USB connection, thus you can let the Arduino directly appear and work as an USB midi device. Then you don't need the hairless-midiserial program anymore.

---
Tags: ftdi, ch340
---


# Question
Title: Increase or decrease const byte value inside the code with a push button
I'm kind of new in the Arduino world. I decided to make a self learning project with an Arduino where it controls a conveyor that simply moves from right to left and back again. There is a start and stop button. On each end of the conveyor are inductive sensors to stop the motor when it reaches the end position. After a delay, the conveyer starts again the opposite direction. Inside the code I have a cycle counter that stops the conveyer after a certain number of cycles. Now my question is, how could I change the value of the cycle counter using two push buttons. One to increase the other to decrease.

If there is somebody who could help I would appreciate. Thanks already

```
const byte sensorLinksEnd  =  2;
const byte sensorRechtsEnd =  3;
const byte startPin        =  4;
const byte stopPin         =  5;
const byte relaisLinks     =  6;
const byte relaisRechts    =  7;

enum {relaisAn, relaisAus};
enum {warten, on, rechts, haltrechts, links, haltlinks, off};
byte schritt = warten;
byte zyklus = 20; //cycles
const byte maxzyklus = 20; //max cycles

void setup() {
  Serial.begin(115200);
  Serial.println(F("Start...."));
  pinMode(sensorLinksEnd, INPUT);
  pinMode(sensorRechtsEnd, INPUT);
  pinMode(startPin, INPUT);
  pinMode(stopPin,  INPUT);
  pinMode(relaisLinks, OUTPUT);
  digitalWrite(relaisLinks, relaisAus);
  pinMode(relaisRechts, OUTPUT);
  digitalWrite(relaisRechts, relaisAus);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop() {
  schrittkette();
}

void schrittkette()
{
  static unsigned long lastmillis;
  const unsigned long pauseZeit = 5000; // in ms
  if (digitalRead(stopPin))
  {
    schritt = off;
  }
  switch (schritt)
  {
    case warten:
      if (digitalRead(startPin))
      {
        zyklus = 0;
        schritt = on;
      }
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      break;
    case on:
      digitalWrite(LED_BUILTIN, HIGH);
      schritt = rechts;
      break;
    case rechts:
      digitalWrite(relaisRechts, relaisAn);
      if (digitalRead(sensorRechtsEnd))
      {
        digitalWrite(relaisRechts, relaisAus);
        schritt = haltrechts;
        lastmillis = millis();
      }
      break;
    case haltrechts:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      if (millis() - lastmillis > pauseZeit)
      {
        schritt = links;
      }
      break;
    case links:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAn);
      if (digitalRead(sensorLinksEnd))
      {
        digitalWrite(relaisLinks, relaisAus);
        schritt = haltlinks;
        lastmillis = millis();
      }
      break;
    case haltlinks:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      if (millis() - lastmillis > pauseZeit)
      {
        if (zyklus == maxzyklus)
        {
          schritt = off;
        }
        else
        {
          zyklus++;
          schritt = rechts;
        }
      }
      break;
    case off:
      digitalWrite(LED_BUILTIN, LOW);
      schritt = warten;
      break;
  }
}

```

# Answer
The `const` keyword tells the C/C++ compiler that the variable is a constant and cannot be changed in your code anymore.

Simply remove `const` and you can modify `maxzyklus` by using 2 digital inputs.

```
byte maxzyklus = 20; //max cycles

```
> 1 votes

---
Tags: button, constants
---


title: How to wake up Arduino with an rtc?

text:
# Question
Title: How to wake up Arduino with an rtc?
I am doing a data logger with an Arduino Mega2560 and I want to use a code to make it sleep when no measure is needed and wake it up with an RTC when time comes. The reason I want this is because I intend to run the code on a Pro Mini later so I need to save as much energy as I can. I am able to put the arduino to sleep using the alarm interrupt when a minute is passed but it doesn't wake up from sleep afterwards.

Here is the code I am using:

```
#include <Wire.h>
#include <RtcDS3231.h>
#include <avr/sleep.h>

const byte interruptPin = 2;
volatile bool alarm = 0;
volatile byte counter = 0;

RtcDS3231<TwoWire> rtcObject(Wire);

void setup() {

  Serial.begin(9600);
  Serial.println("Initialisation");
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);

  rtcObject.Begin();

  RtcDateTime timestamp = RtcDateTime(__DATE__, __TIME__);
  rtcObject.SetDateTime(timestamp);

  rtcObject.Enable32kHzPin(false);
  rtcObject.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmOne);

  DS3231AlarmTwo alarm2(
    0,
    0,
    0,
    DS3231AlarmTwoControl_OncePerMinute);

  rtcObject.SetAlarmTwo(alarm2);
  rtcObject.LatchAlarmsTriggeredFlags();

}

void loop() {
  if (alarm == true){
    handleAlarm();
    if (counter == 1){
      mesure();
      counter = 0;
      delay(100);
      sleepNow();
    }
  }
}

void handleInterrupt() {
  alarm = true;
  counter ++;
  Serial.println(counter);
}

void handleAlarm() {
  alarm = false;
  rtcObject.LatchAlarmsTriggeredFlags();
}

void mesure(){
  RtcDateTime timestamp = rtcObject.GetDateTime();

  Serial.print("time interrupt at: ");
  char time[10];

  sprintf(time, "%d:%d:%d",
          timestamp.Hour(),
          timestamp.Minute(),
          timestamp.Second()
         );
Serial.println(time);
}

void sleepNow() {
  Serial.println("Entering sleeping");
  delay(100);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // sleep mode is set here
  sleep_enable();                         // enables the sleep bit in the mcucr register
  attachInterrupt(digitalPinToInterrupt(interruptPin),wakeUpNow, FALLING);  // use interrupt 0 (pin 2) and run function
  sleep_mode();                           // here the device is actually put to sleep!!
  // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP

  sleep_disable();         // first thing after waking from sleep: disable sleep...
  detachInterrupt(digitalPinToInterrupt(interruptPin));      // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.
}

void wakeUpNow() {
  // execute code here after wake-up before returning to the loop() function
  // timers and code using timers (serial.print and more...) will not work here.
  // we don't really need to execute any special functions here, since we
  // just want the thing to wake up
Serial.println("Woke up");
delay(100);
}

```

I want to understand how to wake it up properly so I can later make it sleep first in the loop and wake it up only if an interrupt is detected from the rtc.

Thank you for your help !

# Answer
You may not need to use an RTC to wake up. Jeelabs has done extensive work on low-power consumption maybe you just need to use the jeelib library from Github. They even sold (not anymore) ultra low power optimized UNO compatible devices (https://jeelabs.org/202x/jnc/). You find jeelib on github on the linked page.

Look at the Sleepy class. It does some low level power saving magic directly with the hardware. It would be interesting to extract that class from Ports.h and Ports.cpp and try if it works standalone.

You simply use it with: Sleepy::loseSomeTime(32); and it will power down the whole MCU for some time. https://github.com/jeelabs/jeelib/blob/635113edea74b1290713360649679c3a13016304/Ports.h#L346

It uses the watchdog timer of the MCUs:

```
ISR(WDT_vect) { Sleepy::watchdogEvent(); }

```
> 1 votes

# Answer
If you use the DS3232RTC library then you can setup an alarm which is like an alarm. I have put a good tutorial on how to do that below.

https://thekurks.net/blog/2018/2/5/wakeup-rtc-datalogger

There is also other threads on arduino.cc you should check out. They might have additional work-arounds.

https://forum.arduino.cc/index.php?topic=333654.0

https://forum.arduino.cc/index.php?topic=99588.0
> 0 votes

---
Tags: interrupt, rtc, sleep, atmega2560
---


title: RaspberryPi Pico SPI and nrf24l01

text:
# Question
Title: RaspberryPi Pico SPI and nrf24l01
I am programming a RaspberryPi Pico with the Arduino IDE. Works pretty well, but now I try to control an nrf24l01 module.

My code compiles but I do not know on which pins the SPI bus has to be hocked up. I tried to connect to different pins according the pinout https://datasheets.raspberrypi.org/pico/Pico-R3-A4-Pinout.pdf (for example 2 sck, 3 miso, 4 mosi), but nothing worked so far.

Does anybody know what the default pins are or how to control them? I also would like to control other SPI hardware, for example a display.

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

const uint64_t address = 0x1;
byte sendData[1];

#define CSN_PIN  5
#define CE_PIN   6
RF24 radio(CE_PIN, CSN_PIN);

byte counter = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println(“radio starting");

  if (!radio.begin())
  {
    Serial.println("radio hardware is not responding!!");
    while (1) {}
  }
  radio.openWritingPipe(address);
}

void loop()
{
  Serial.print("Counter: ");
  Serial.println(counter);

  sendData[0] = counter;

  radio.write( sendData, sizeof(sendData));

  counter++;
}

```

# Answer
> 4 votes
1. For Arduino-pico core

\** MISO - pin GP16

\** MOSI - pin GP19

\** CS - pin GP17

\** SCK - pin GP18
2. Arduino-mbed core

\** MISO - pin GP4

\** MOSI - pin GP3

\** CS - pin GP5

\** SCK - pin GP2

---
Tags: spi, nrf24l01+, raspberrypi-pico
---


# Question
Title: How do I make another action repeat inside a loop?
*So, I've just started programming Arduino (and also in general), so I'm doing basic things, like switching on and off LED's.*

I've made them light in a sequence and then turning them off (in the same sequence), and now I wanted to use 2 buttons, one to make them do the same thing as before (light and turning LED's off in sequence) repeatedly, and the other to turn them off.

The problem is that curently they only light up once, and not repeatedly, I think I would've needed another loop, but i found out that you can't use 2 of them.

Can anyone help me? here's the code

```
int LED1 = 2;
int LED2 = 3;
int LED3 = 4;
int LED4 = 5;
int LED5 = 6;
int buttonON = 7;
int buttonOFF = 8;

void setup()
{
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(LED5, OUTPUT);
  pinMode(buttonON, INPUT_PULLUP);
  pinMode(buttonOFF, INPUT_PULLUP);
}

void loop ()
{
  if (digitalRead(buttonON)== LOW)
  {
    delay(300), digitalWrite(LED1, HIGH);
    delay(50), digitalWrite(LED2, HIGH);
    delay(50), digitalWrite(LED3, HIGH);
    delay(50), digitalWrite(LED4, HIGH);
    delay(50), digitalWrite(LED5, HIGH);
    delay(300), digitalWrite(LED1, LOW);
    delay(100), digitalWrite(LED2, LOW);
    delay(100), digitalWrite(LED3, LOW);
    delay(100), digitalWrite(LED4, LOW);
    delay(100), digitalWrite(LED5, LOW);
  }
 if (digitalRead(buttonOFF)== LOW)
 {
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
  digitalWrite(LED3, LOW);
  digitalWrite(LED4, LOW);
  digitalWrite(LED5, LOW);
 }
}

```

P.S. if anyone has other general tips I would really apreciate them

# Answer
You have written your question beautifully. In your case, according to your logic, the button has to be kept pressed, so that the LEDs are lit in the order you desire. The single loop() function is part of the Arduino sketch but it is never a limitation.

One way to solve your problem is to make the LED drive logic independent of the button press state.

* Once you detect the button press, store the event in one variable.
* Let us call it `ButtonStatus`.
* So, soon after the keypress is detected, update the `ButtonStatus` variable to TRUE.
* Your LED drive logic can check this variable value to decide whether to drive the LEDs or not
* Soon after you detect another press of the second button, you can update the variable value to FALSE.
Here is the Arduino simulation output for your code and the code suggested by @cat

below is after adapting the solution from cat

The simulation links are here: Original problem solution 1

```
int LED1 = 2;
int LED2 = 3;
int LED3 = 4;
int LED4 = 5;
int LED5 = 6;
int buttonON = 7;
int buttonOFF = 8;
int ledEffectON;
void setup()
{
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(LED5, OUTPUT);
  pinMode(buttonON, INPUT_PULLUP);
  pinMode(buttonOFF, INPUT_PULLUP);
}

void loop ()
{
  if (digitalRead(buttonON)== LOW)
      ledEffectON = true;

  if (digitalRead(buttonOFF)== LOW)
      ledEffectON = false;

  if(ledEffectON)
  {
    delay(300), digitalWrite(LED1, HIGH);
    delay(50), digitalWrite(LED2, HIGH);
    delay(50), digitalWrite(LED3, HIGH);
    delay(50), digitalWrite(LED4, HIGH);
    delay(50), digitalWrite(LED5, HIGH);
    delay(300), digitalWrite(LED1, LOW);
    delay(100), digitalWrite(LED2, LOW);
    delay(100), digitalWrite(LED3, LOW);
    delay(100), digitalWrite(LED4, LOW);
    delay(100), digitalWrite(LED5, LOW);
  }
}

```

Link to docs on Pushbuttons. Wokwi Arduino simulator simulates debounce by default - just like real-world switched. Debounce is a very important technique that you should consider adding to the code. To disable the "bounce" option, use the below trick!

```
{ "bounce": "0" }

```
> 3 votes

# Answer
By using `delay()` it blocks the rest of the code. The programme needs to keep track of two buttons and update the lightshow at appropriate times, therefore a non-blocking style of coding is needed similar to the Blink Without Delay example where the `delay()` is replaced with a timer using `millis()` that is checked periodically. This allows other things to be checked periodically as well, e.g. the buttons.

Also the button contacts tend to bounce several times for several milliseconds when they change state sending a train of on/off pulses to the MCU, so they need to be debounced. You can find many debouncing algorithms online, but here's a simple debouncer that I put on GitHub.

```
void loop ()
{
  static bool doLightshow = false;

  static Debouncer buttonOn(buttonON);
  static Debouncer buttonOff(buttonOFF);

  buttonOn.Update();
  buttonOff.Update();

  if (buttonOn.Fall())
  {
    Serial.println("buttonOn falling edge.");
    doLightshow = true;
  }
  else if (buttonOff.Fall())
  {
    Serial.println("buttonOff falling edge.");
    doLightshow = false;
  }

  if (doLightshow)
  {
    // Do lightshow.
    . . .
  }
  else
  {
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED4, LOW);
    digitalWrite(LED5, LOW);
  }
}

```

Due to the way you've neatly written your code, you can probably pick out a pattern in the lightshow.

| State | Delay time | LED pin | LED state |
| --- | --- | --- | --- |
| 0 | 300 | LED1 | HIGH |
| 1 | 50 | LED2 | HIGH |
| 2 | 50 | LED3 | HIGH |
| 3 | 50 | LED4 | HIGH |
| 4 | 50 | LED5 | HIGH |
| 5 | 300 | LED1 | LOW |
| 6 | 100 | LED2 | LOW |
| 7 | 100 | LED3 | LOW |
| 8 | 100 | LED4 | LOW |
| 9 | 100 | LED5 | LOW |

This lends itself well to creating a Finite State Machine that can be stored in an array of structures:

```
typedef struct LightshowData
{
  unsigned int delayTime;
  byte ledPin;
  bool ledState;
};

const byte numStates = 10;

const LightshowData lightshowData[numStates] =
{
  { 300, LED1, HIGH },
  {  50, LED2, HIGH },
  {  50, LED3, HIGH },
  {  50, LED4, HIGH },
  {  50, LED5, HIGH },
  { 300, LED1, LOW },
  { 100, LED2, LOW },
  { 100, LED3, LOW },
  { 100, LED4, LOW },
  { 100, LED5, LOW }
};

```

The state machine can now cycle through the array in a non-blocking manner:

```
    // Do lightshow.
    static byte state = 0;
    unsigned long currentTimestamp = millis();
    static unsigned long previousTimestamp = currentTimestamp;

    if (currentTimestamp - previousTimestamp >= lightshowData[state].delayTime)
    {
      previousTimestamp += lightshowData[state].delayTime;
      digitalWrite(lightshowData[state].ledPin, lightshowData[state].ledState);
      state = ++state % numStates;
      Serial.print("state = ");
      Serial.println(state);
    }

```

You may want to reset `state` to 0 after a negative edge on `buttonOff`, otherwise the lightshow will continue where it left off after being stopped and restarted.

Here's the Wokwi simulation of the lightshow with 250 Ω protection resistors for the LEDs.

Wokwi simulates button bounce by default to more accurately model the real world, so it's advisable to have some form of button debouncing.
> 6 votes

# Answer
You simply need to save the state of the LEDs in a new variable ...

```
void loop ()
{
  if (digitalRead(buttonON)== LOW)
      ledEffectON = true;

  if (digitalRead(buttonOFF)== LOW)
      ledEffectON = false;

  if(ledEffectON)
  {
    delay(300), digitalWrite(LED1, HIGH);
    delay(50), digitalWrite(LED2, HIGH);
    delay(50), digitalWrite(LED3, HIGH);
    delay(50), digitalWrite(LED4, HIGH);
    delay(50), digitalWrite(LED5, HIGH);
    delay(300), digitalWrite(LED1, LOW);
    delay(100), digitalWrite(LED2, LOW);
    delay(100), digitalWrite(LED3, LOW);
    delay(100), digitalWrite(LED4, LOW);
    delay(100), digitalWrite(LED5, LOW);
  }
}

```
> 2 votes

---
Tags: arduino-uno, led, button, code-review, loop
---


# Question
Title: a code to implement a simple traffic signal and also display on LCD which color is ON?
I have tried code given below for simple traffic signal and also display on LCD which color is ON, but it didn't work. Please me to make it work.

```
int red = 10;
int yellow = 9;
int green = 8;
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup(){
    pinMode(red, OUTPUT);
    pinMode(yellow, OUTPUT);
    pinMode(green, OUTPUT);
}

void loop(){
    changeLights();
    delay(1500);
}

void changeLights(){
    lcd.print("red");
    digitalWrite(yellow,LOW );
    digitalWrite(red, HIGH);
    digitalWrite(green,LOW );
    delay(3000);
    lcd.print("yellow");
    digitalWrite(yellow,HIGH );
    digitalWrite(red,LOW );
    digitalWrite(green,LOW );
    delay(3000);
    lcd.print("green");
    digitalWrite(yellow,LOW );
    digitalWrite(red,LOW );
    digitalWrite(green,HIGH );
    delay(3000);
    //if(
}

```

# Answer
Write a sketch to test your LCD.

```
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 4, 2);
void setup(){
    lcd.begin();
    lcd.print("Hello World!");
}
void loop() {
    lcd.setCursor(0, 1);
    lcd.print(millis() / 1000);
}

```

Make sure the R/W pin is connected to GND on your breadboard. You may need to connect the contrast pin to 5V. Ideally it should be connected to the wiper of a 10KOhm trimpot with either end connected to GND & 5V (so you can vary the contrast).

Once that set-up works change your code

```
 void setup(){
     lcd.begin();
     lcd.print("Traffic signals");
     delay(500);
     pinMode(red, OUTPUT);
     pinMode(yellow, OUTPUT);
     pinMode(green, OUTPUT);
 }

 void loop(){
     changeLights();
     lcd.setCursor(0,0);
 }

```
> 3 votes

# Answer
A small update to your code

1. Added `lcd.begin();` function
2. added `lcd.clear();` function so that old characters will be removed before adding new display

Here is the complete code

```
int red = 10;
int yellow = 9;
int green = 8;
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
  lcd.begin(16, 2);
  pinMode(red, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(green, OUTPUT);
}

void loop() {
  changeLights();
  delay(1500);
}

void changeLights() {
  lcd.clear();
  lcd.print("red");
  digitalWrite(yellow, LOW );
  digitalWrite(red, HIGH);
  digitalWrite(green, LOW );
  delay(3000);
  lcd.clear();
  lcd.print("yellow");
  digitalWrite(yellow, HIGH );
  digitalWrite(red, LOW );
  digitalWrite(green, LOW );
  delay(3000);
  lcd.clear();
  lcd.print("green");
  digitalWrite(yellow, LOW );
  digitalWrite(red, LOW );
  digitalWrite(green, HIGH );
  delay(3000);
  //if(
}

```

The output would look like this:

Here is the link to the Arduino simulator example
> 0 votes

---
Tags: arduino-uno, led, lcd, code-review
---


title: Can bool variable be NULL

text:
# Question
Title: Can bool variable be NULL
I want to know if bool variable can be null, or it must have to be true or false:

Base on Arduino description: A bool holds one of two values, true or false. (Each bool variable occupies one byte of memory.)

# Answer
A `bool` value must be either `0` or `1`, or `false` and `true` respectively. It is *undefined behavior* for it to be any other value. When assigning a value to a `bool`, the compiler will automatically force it to be 0 if it is already 0, or 1 if it is not.

However, as it is a full byte, it is possible to store another value. As mentioned before, however, this is undefined behavior. This means that if it ever happens, or will absolutely happen, the program can do *anything*: for example, crash the program, output random data, or act like it's truthy, falsy, or both! In fact, that *can* (again, no guarantees) happen if you store the value 2:

```
#include <cstdio>

int main() {
    union b_c {
        unsigned char c;
        bool b;
    };
    b_c c;
    c.c = 2;

    if(c.b) puts("true!");
    if(!c.b) puts("false!");
}

```

(this is designed to run on a computer, but the same thing could happen on an Arduino). Check out what happens when you run it: it outputs both `true!` and `false!`! This obviously doesn't make sense, but because we violate the rules by making a `bool` `2`, we loose all guarantees.

---

So, how is this relevant to your question? There's no valid value a `bool` can store other than `true` and `false`. In C++, `null` is defined as "an integer literal with value zero". So, if you were to assign `null` to a `bool`, it would be stored as false. If you want a separate null value, you're better off using another type that takes up a single byte (e.g. `unsigned char` or `uint8_t`, same thing) and storing e.g. `0` for `false`, `1` for `true`, and `2` for null.
> 2 votes

# Answer
A bool is literally that - a boolean value. So either 1 or 0 - true or false.

In C only pointers can be NULL. Every other primitive type is a value, and NULL is not a value.
> 1 votes

---
Tags: variables
---


# Question
Title: Programing in Assembly for the Digispark
I've been given a digispark and am looking to write straight assembly code for it. Anyone know how to get started with this? I've been successful in getting the Arduino IDE set-up but would really like to avoid writing assembly in-line...

# Answer
There seems to be some specific attiny flag required but by the gcc in order to make the genereated hex file work with digispark. Take a look here https://github.com/pda/digispark-asm.
> 1 votes

# Answer
> I've been given a digispark and am looking to write straight assembly code for it. Anyone know how to get started with this? I've been successful in getting the Arduino IDE set-up but would really like to avoid writing assembly in-line...

The Arduino IDE build support assembly files (.S). Nerd Ralph has written a blog on the subject. There you will find all the details and how to write both inline and pure assembly files. He is really god at digging out all the details and sharing his findings.
> 1 votes

# Answer
In 2021, I use VSC + Platformio.

I create a main.asm file in which I put the code from https://github.com/pda/digispark-asm.

In the "platformio.ini" file I define the digispark as :

\[platformio\]

default\_envs = digispark-tiny

\[env:digispark-tiny\]

platform = atmelavr

board = digispark-tiny

I run the code, upload it to a digispark and this works amazingly well.
> 1 votes

---
Tags: assembly
---


# Question
Title: Using Arduino LMIC library with EnableInterrupt
I am using the EnableInterrupt library, infact the only library that I can find that allows me to use six interrupts to wake the Arduino. However when I use it with the LMIC library (Matthijs Kooijman ) the "Forward uplink data message" is not sent during initial registration, only if #include \<EnableInterrupt.h\> is commented out does it work. I am using a RFM95 with the following LMIC pin assignments:

const lmic\_pinmap lmic\_pins = { .nss = 10, .rxtx = LMIC\_UNUSED\_PIN, .rst = 9, .dio = {3, 8, LMIC\_UNUSED\_PIN}, };

This must be something to do with the library sharing ISRs. Could somebody point to which parts of the LMIC library so as not to have this conflict?

I have tried swapping 8 for A5 and it again only works when the line is commented. Any help would be greatly appreciated.

# Answer
> 1 votes
This is the best I can get to work with 6 available pin change interrupts - just enough!

```
#define EI_ARDUINO_INTERRUPTED_PIN
#define EI_NOTPORTB  // DISABLE FOR LMIC
#define EI_NOTPORTD  // DISABLE FOR LMIC

```

---
Tags: arduino-uno, interrupt, lora
---


# Question
Title: How to control Shift registers output individually bitwise
so i am working on a project which needs a lots of bit manipulation and shifting out the bits to control the pins of shift registers individually.

So i am using 2 shift registers daisy chained with 16 LEDS. Now, what i want is that, i want to control the LEDs individually just by shifting out the bits

here is what i tried

first Attempt

```
int latchPin = 4;   // Latch pin of 74HC595 is connected to Digital pin 5
int clockPin = 5;   // Clock pin of 74HC595 is connected to Digital pin 6
int dataPin = 3;    // Data pin of 74HC595 is connected to Digital pin 4

byte leds=0b1000000000000001; // byte has 16 bits

void setup()
{

  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void loop()
{

  updateShiftRegister();

}

void updateShiftRegister()
{
   digitalWrite(latchPin, LOW);

   shiftOut(dataPin, clockPin, LSBFIRST, leds);
   digitalWrite(latchPin, HIGH);
}

```

Does not work! the 2nd shift register seems to be copying the first shift register which i don't want

In second attempt, i tried the masking method with HEX data type. Here is it.

```
int latchPin = 4;   // Latch pin of 74HC595 is connected to Digital pin 5
int clockPin = 5;   // Clock pin of 74HC595 is connected to Digital pin 6
int dataPin = 3;    // Data pin of 74HC595 is connected to Digital pin 4

byte leds=0xFFFF & 0x8001; // used hex masking method

// 0xFFFF = 1111111111111111
// 0x8001 = 1000000000000001
// After & it should be 1000000000000001

void setup()
{

  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void loop()
{

  updateShiftRegister();

}

void updateShiftRegister()
{
   digitalWrite(latchPin, LOW);

   shiftOut(dataPin, clockPin, LSBFIRST, leds);
   digitalWrite(latchPin, HIGH);
}

```

This too makes same effect like the attempt 1 above.

Now here is what i want and need...

```
byte leds = 0b1000000000000001

/* As you can see the index 0 and index 15 of the byte led
  is set 1 or high which should produce +ve to the 15th pin of first register and 8th pin of second register.

```

but whenever i try this, it seems that one of the register is copying another one.

So, is there any way to shift out bits to control the shift register outputs individually?

if yes then please give a clear example code with a clear explanation.

if no then, please suggest me some alternative ways which can be used in the same way i want , of course with example code and explanation.

Schematic: arduino.cc/en/Tutorial/Foundations/ShiftOut

Thank You so much for your precious time.

Looking forward to your replies .

:)

# Answer
> 2 votes
You have two problems with your code:

* `byte` is equal to `unsigned char` and can only hold exactly one byte, aka 8 bits (not 16 bits like your comment says). But you are trying to assign a 16bit number to it. The upper 8 bits are cut out in that process. They are lost. If you want to hold a 16bit number, you need to use a data type, that is at least 16 bits in its size, for example `uint16_t` (or you can use `unsigned int`, though in such situations it is often better to use a type, which has the same size on all platforms).

```
  uint16_t leds = 0b1000000000000001;

```
* The `shiftOut()` function has this declaration in wiring\_shift.c:

```
  void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)

```

You can see, that `val` (which is the data, that should be shifted out) is of type `uint8_t`, the same as `byte`, which also can only hold 8 bits. The upper 8 bits of a 16bit value would be cut off and the function also just transmits 8 bits, nothing more (When you look at its implemention in the mentioned file, you will see a for loop with 8 as limit).

Instead you should call that function for every byte, that you want to transmit in a single transmission; 2 times in your case because you have 2 shift registers.

So the resulting program would look something like this:

```
int latchPin = 4;   // Latch pin of 74HC595 is connected to Digital pin 5
int clockPin = 5;   // Clock pin of 74HC595 is connected to Digital pin 6
int dataPin = 3;    // Data pin of 74HC595 is connected to Digital pin 4

uint16_t leds=0b1000000000000001; // uint16_t has 16 bits

void setup()
{

  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void loop()
{

  updateShiftRegister();

}

void updateShiftRegister()
{
   digitalWrite(latchPin, LOW);

   // Shiftout lower byte by masking the other byte with bitwise AND (&)
   shiftOut(dataPin, clockPin, LSBFIRST, leds & 0xFF);
   // Shiftout higher byte by shifting the bit pattern 8 bits to the right
   // resulting in the high byte getting to the position of the low byte
   // and then masking away anything else than the new position of the high
   // byte data
   shiftOut(dataPin, clockPin, LSBFIRST, (leds >> 8) & 0xFF);
   digitalWrite(latchPin, HIGH);
}

```

Note, that the masking with the bitwise AND operator is not really necessary here, but I like to do such things explicitly to make it more clear.

---

> So I need to store almost 50 bits in the variable to control the columns so can 'uint' method be useful in this case ?

In that case I would use a byte array to hold the data. With 50 bits you are at 6.25 or 7 bytes (since you cannot have sub bytes). The declaration would be something like this:

```
byte leds[] = {0b00011001, ... }; // list the byte data here

```

And then you can shift that out with a for loop:

```
void updateShiftRegister()
{
   digitalWrite(latchPin, LOW);
   for(int i=0;i<sizeof(leds)/sizeof(leds[0]);i++){
       shiftOut(dataPin, clockPin, LSBFIRST, leds[i]);
   }
   digitalWrite(latchPin, HIGH);
}

```

Note that `sizeof(leds)` will return the size of the `leds` array in bytes. I also divided through the size of a single element of the array to get the number of elements in the array instead of bytes. In this case this is the same, but since datatypes might change while the code progresses it is better to be save than sorry.

> i tried the masking method with HEX data type.

The data, that comes out is the same. The Arduino only knows of binary data. It doesn't know of different representions (like binary, HEX or decimal). The compiler will already convert that to the target value. So for the Arduino both ways are equivalent.

# Answer
> 1 votes
The function `shiftOut()` only works for 8-bit values, as its documentation says.

Additionally, a `byte` can only store 8 bits. It doesn't matter how many bits you try to assign. (The compiler should have given you a warning, but the IDE likes to hide this.)

You need to write your own output function to shift out 16 bits, AFAIK.

---
Tags: arduino-uno, shift-register, bit
---


# Question
Title: how to write a program in Arduino that pairs a single Rx to multiple Tx modules? i want to learn implementing this protocol
I have two Attiny85 communicating over 433mhz radio (Rx & Tx on either ends) using virtual wire library, how will the programming be to pair them by the press of a button on either module ? i have so far been able to pair them both through the program (exclude any external devices by giving a node ID to listen to in my Rx) or think of adding DIP switches (but i run out of pins & combinations sooner). I am expecting something similar to a commercial product where i can connect/pair multiple Tx modules to a single Rx base station in a press of a button on the Tx side. so i am seeking some technical expertise on the idea to understand such programming technique/methods.

Regardless of using 433mhz or a NRF24L01 module or anything else, i want to know how this feature of pairing module together is made.

*------* Edit 22 July 2021: This is added here in response from Crisl's comment

you have correctly understood my question, yes i want to learn how such a pairing protocol is implemented, i am not too concerned about the device for the communication gateway.

this question is regarding the protocol, and not about a specific circuit

*------* I am a mechanical engineer by profession, with a hobby towards programming & electronics, so kindly spare some patience/detail in explaining this concept/technique.

# Answer
If it is sufficient to distinguish between the two (or several) transmitters and you don't need to exclude intrusions, accidental or otherwise, a "protocol" can be as simple as:

XMTRID BYTECOUNT BYTE\[0\] BYTE\[1\] ... BYTE\[COUNT-1\]

, where each of the above represents a single byte. Does the library include message integrity checking, such as a checksum? If not, and the physical conditions warrant, you might add that to your protocol as well, and include an expectation by the transmitter that it receives an acknowledgement or rejection of correct reception (ACK or NAK) within a short time and will re-transmits the same message if it hasn't received an ACK. Then you'll want a message ID byte that increments for each new message (but not for retramsmission), so the receiver can reject a retransmission (if, say, its attempt to acknowledge had been lost).

Then your protocol could look something like this:

XMTRID MSGID CHKSUM BYTECOUNT BYTE\[0\] BYTE\[1\] ... BYTE\[COUNT-1\]

. and it just keeps getting better from there as you add features for robustness, security, and whatever else you might need it to accomplish. But I'm guessing this is already sufficient.

Update: To clarify:

```
XMTRID    - ID of sending 433MHz radio (any value you like, as long as each device has its own).
MSGID     - An incrementing number (rollover allowed), a new one for each *new* message
            (enables the receiver to distinguish new messages from resent ones).
CHKSUM    - A sum of bytes in the message to let the receiver check the message integrity.
BYTECOUNT - The number of message bytes to follow.
BYTE[0] ... BYTE[BYTECOUNT-1] - The actual message data.

```
> 1 votes

---
Tags: attiny85, virtualwire
---


# Question
Title: Arduino and fingerprint scanner - can I get the fingerprint scanner data?
I am currently planning a thesis that involve scanning fingerprints and storing the data in a database. The problem is that I do not know if it is possible for me/us to get the fingerprint data or variables scanned by the fingerprint scanner.

I tried searching on google, of course, but I don't see any information on how to display the data in a form such as binary. I'm not sure if I can extract the data from the Arduino then store it in a website/database (---which to be fair, since fingerprints can be confidential, I understand if some articles don't provide a sample.)

Is it possible to get and extract the fingerprint scan data? For example, converting the scanned data in to a binary representation (011010101 etc.)

# Answer
I'm a software engineer that works with biometric sensors. The answer is, it will vary **greatly** depending on the scanner you've chosen. Some hardware solutions have built-in subject enrollment and database matching; some simply collect an image and return it in an appropriate format- sometimes an image file (e.g. PNG), or a template file (a binary representation of a subject and/or their fingerprint(s)).

For you, I **highly** recommend avoiding the pain of interfacing with an Arduino at such a low level, and use a Raspberry Pi or other full computer to write a collection program with your vendor's SDK. Linux is supported by all the major players I've worked with, and that will drastically ease integration with whatever database or website you have in mind. Many vendors have built-in enrollment, storage, and matching examples as part of their SDKs that will help you get up and going in short order

**EDIT**: As this is an Arduino SE, I realize **I should give a microcontroller-friendly answer as well**. There are indeed scanners like this. It does templating and matching on board if I understand correctly, and the provided library does indeed allow you to transfer those templates over serial. Granted, you still have to get that data from your Arduino to a computer of some sort, so I still think a Pi is the shorter putt ;)
> 13 votes

# Answer
There is a discussion thread on Quora discussing finger print scanners that provide raw output. The Quora author recommends a Futronic device which comes with an API for raw image collection. They also discussed NeuroTechnology which apparently also has a downloadable image database. Looking at the neurotechnology website they also have some interesting SDK options. These of course all give you an image not the binary output you described.

It strikes me that a binary encoded output would likely be the result of a recognition algorithm, or a resultant / generated security key. Not sure that is what you intended by your question?

There are a mass of academic papers on open finger print scanning algorithms.

I did a bit of google searching for people capturing raw data from Arduino compatible devices. Didn’t find anyone saying it was easy. Please post back here if you make progress.

Hope this helps get you started.
> 9 votes

# Answer
Echoing my comment on SO with more information:

Commercial fingerprint sensors like this one do local store and compare and do not expose the actual image or binary signature. What they transmit to the microcontroller are ID's and match success.

If you need the binary data of the image itself you may be able to write your own image processing algorithm, perhaps using machine learning, and use a simple video camera connected to a microcontroller that in turn will send the captured image to your web server for processing.

Arduino can be programmed to capture still images and transfer a bitmap file to a server, such devices (microcontroller and cameras) are widely available.
> 3 votes

---
Tags: arduino-ide
---


# Question
Title: How to read wireless doorbell's indicator LED circuit
I have a cheap wireless doorbell. My plan is to include an ESP8266 and power the doorbell from the microcontroller 3.3V output as the doorbell also runs on 3V

I specifically chose a model with a LED, as I thought it should be easy to use the LED as a trigger on the ESP8266 and consume as a digital input.

I've soldered two wires from the LED positive and negative solder points. What I find strange is that I measure 3V between the PCB ground and the positive LED wire when the doorbell is not triggered. If I measure between the negative LED wire and positive LED wire, I see a voltage spike corresponding to each LED flash (it flashes 5 times). I plan to debounce this in software.

I did not expect to measure a voltage when the doorbell is not triggered between the positive LED wire and the PCB ground, and this will definitely not work as I intended.

*Disclaimer: I'm not an electronic engineer, and my test equipment consists of a multimeter.*

I've included a photo of the PCB. It is labelled "QH-823A-19" but searching for this on the Internet has provided no usable information.

What have I tried?

1. I've tried to trace the tracks running to the LED solder points, but the tracks run under some components which makes this hard
2. I've tried to measure different points on the board for a positive 3V spike when the LED flashes, no success

Any advice on how to achieve this? Am I going about this the wrong way?

# Answer
> 1 votes
Your LED is connected between V+ and the GPIO of the microcontroller. This is a common arrangement because historically microcontrollers have been able to sink more current than they can source. It's also easier to make a "low side" constant current source, which this custom chip may have, to reduce the number of external components needed.

To read the state you need to take the voltage at the cathode of the LED referenced to the ground of the doorbell circuit. This will give you a voltage at or near the board supply voltage when the LED is off, and a lower voltage (near zero but probably not zero) when the LED is on.

If the voltages are within the threshold voltages VIH and VIL of the ESP8266 then you can just directly read that level as a logic level. If not then you may need to "condition" the voltage to give proper logic levels.

For example you could use a comparator (an op-amp running in "saturated" mode) to compare that voltage to a single threshold voltage that is roughly half way between the HIGH and LOW voltages. That would then swing the output between the supply and ground voltage levels giving you a much cleaner signal.

Or you may use an analog input (the ESP8266 only has one, and that is quite a crude one with only 1.1V maximum allowed on it, so a voltage divider will be needed) to measure the voltage and do the comparison in software.

Another option would be to remove the LED completely and replace it with an optocoupler, thus making the LED itself an electronically operated button to the ESP8266. This will also keep the ESP8266 ganvalically isolated from the doorbell.

# Answer
> 0 votes
# Schmitt Trigger using a Comparator

If you follow @Majenko's advice of using a comparator, you could add some hysteresis to it with a few resistors to create an inverting Schmitt trigger. This will increase the noise immunity and thus reduce the noise going to the ESP8266. The following simulation has a noisy input transformed into square pulses. It also performs a small level shift from an input of 3 V to an output of 3.3 V.

*Figure 1 – Schmitt trigger circuit.*

*Figure 2 – Schmitt trigger simulation.*

# Hysteresis versus Low-Pass Filtering

There is a subtle difference between hysteresis and low-pass filtering.

The following experimental circuit, Figure 3, demonstrates this difference with an interactive simulation where you can click on the switches to add/remove noise and add/remove filtering.

The low-pass filter has a cut-off frequency of 40 Hz.

I've set the high-going threshold, Vt+, to 2.31 V and the low-going threshold, Vt-, to 1.54 V. I calculated these figures from the 74HC14 datasheet using the thresholds for 3 V at 25°C and scaling them for 3.3 V.

*Figure 3 – Circuit showing difference between hysteresis and low-pass filtering.*

Hysteresis provides greater noise immunity and reshapes a slowly changing signal into a square wave ready for a digital input. But it can't filter out noise spikes that breach its threshold levels. These spikes would cause the Schmitt trigger to output square pulses. See the orange section of Figure 4.

Low-pass filtering filters out high frequency spikes which could breach the upper and lower thresholds of a Schmitt trigger. See the green section of Figure 4. Note that it also introduces a phase shift. If the noise were created by switch-bounce, then the low-pass filter would be performing debouncing. The blue section represents the ideal world where there is no noise, no need of filtering, and the output is in phase with the input.

*Figure 4 – Simulation of hysteresis versus low-pass filtering.*

---
Tags: esp8266, iot
---


# Question
Title: How can I maintain switch state when in sleep mode?
I'm using a esp8266 to build a remote control to power a gas fireplace. I'm using this guide to try and maximize battery life.

The concept is the controller uses its built in WiFi to access a RESTful API on a remote server; If the API discovers"1", it should close a switch and the fireplace turns on. If the arduino reads a "0" via the API it opens the switch and the fireplace turns off. After discovery and performing the required action the unit calls **Deepsleep** and shuts off for ten seconds, whereupon it powers up and the cycle repeats itself again.

I just realized that if the controller powers off, I don't know what happens to the switch. If the fireplace was turned on, what happens when deep sleep starts. Is there a way (special switch?) that maintains its state in deepsleep mode?

# Answer
Yes, there is such 'switch'. You could use **JK Flip-Flop** to hold the last output. JK Flip-Flop has `J`, `K` and `clock` inputs and **If J and K are different** then the output takes the value of J at the next clock edge.
> 1 votes

# Answer
You can get a *latching relay*. These come in two flavours - *Unipolar,* where you energise one pin to turn it on, and energise the other to turn it off, and *Bipolar,* where the direction of the current through the coil turns on or turns off.

Unipolar is easier to drive since you just need two transistors, diodes and resistors. Bipolar is harder, since you need a H-bridge (motor driver), but requires less wires to connect it up (2 as opposed to 3).

In both cases it is just a short pulse that is needed to switch the relay into a different state - there is no need to maintain the output, so is ideal for *deep-sleep* mode where everything is turned off except the RTC.
> 1 votes

# Answer
During my Deep Sleep experiments I noticed that a couple of pins held their state through a Deep Sleep reset, but I didn't write it down anywhere. Simple observation suggests that **any** of the pins that wiggle during boot will NOT be retained, which leaves just GPIO4 and GPIO5 for likely candidates. Try it and see!

During Deep Sleep the pins hold their state, although they're using weak FETs equivalent to 2uA source/sink current. The boot cycle following Sleep clobbers most of the GPIOs. Sigh.
> 1 votes

---
Tags: esp8266, battery, sleep
---


title: Pro Mini - Using RAW pin for 3.3v input

text:
# Question
Title: Pro Mini - Using RAW pin for 3.3v input
I design a PCB that one of its components is a 3.3v Pro Mini. Since I want it versatile regarding powering the PCB (3.3v or 5.0v) I want to know if it is a good practice to supply 3.3v to Pro Mini's RAW pin( rather than to the VCC Pin ).

# Answer
It is not ideal, no. The RAW pin first goes into a 3.3V voltage regulator whose dropout voltage is up to 200mV (worst case). That means that you would get around 3.1V out, and it wouldn't be properly regulated.

Oh, it would *work*, but the power won't be stable, which means that any analogue readings that you make that don't directly use the (shakily) regulated "3.3V" (now 3.something else V) in the generation of the analog signal (such as a simple potentiometer) will be inaccurate.

Also output logic voltages will be lower than expected which may have an effect if communicating with something whose upper input threshold is at or near the 3.3V mark (such as many 5V devices).
> 6 votes

---
Tags: power, arduino-pro-mini
---


title: ESP32 and SQLite - ALTER TABLE problem

text:
# Question
Title: ESP32 and SQLite - ALTER TABLE problem
I'm using an ESP32 and SQLite3 from https://github.com/siara-cc/esp32\_arduino\_sqlite3\_lib Everything is OK except the ALTER TABLE command. When I try

```
    ALTER TABLE TAB_JOUEUR RENAME TO TAB_NEW_JOUEUR

```

I get a "SQL logic error". I just see that the default source code will not compile with the ALTER TABLE option if SQLITE\_OMIT\_ALTERTABLE is defined. So at the begining of the .c source, I added:

```
 #if defined(SQLITE_OMIT_ALTERTABLE)
      #undef SQLITE_OMIT_ALTERTABLE
#endif

```

But result is the same.... Any idea?

# Answer
Well. After searching a lot here's the way todo a "RENAME" for a table. It's a bit tricky... Renaming table in ESP SQLite is very interesting because SQLite has very limited features for editing table. So you can't add field, remove and so on. The only way is to create a new tmp table, copy the content of the orginal one into this tmp table, drop the original one and rename the tmp with the name of the new one. DROP TABLE is OK with the ESP version of SQLite, but as said in the question, ALTER RENAME don't work.

So here is the way to do:

**1-What tables do we have?**

When we init the ESP, we call

```
  sqlite3_initialize();

```

and then we give SQLite the file it will use for saving data with a call to sqlite3\_open() giving the name of a previously created file.

All our own tables will be saved into this file but also definitions of our tables. For that, SQLite create system table. So in the database we have our own tables but also the SQLlite system tables

**2 - The data base schema table**

One of the most important table is the database schema one. Its name depend on the version of SQLite. With the version we use on ESP8266 or ESP32, its name is *sqlite\_master* . This table has 4 fields:

* type. Value can be 'table', 'index', 'view', or 'trigger'
* name. Value is the name of the data. If type='table', name is the name of
the table defined in this record
* tbl\_name. Name of the table. So if type='name', tbl\_name = name
* rootpage. An int which is the index in the Btree used by SQLite to access the data
* sql. The code to create the table

**3-Check the schema**

To check the content of this specific table, just make a CREATE TABLE then SELECT * FROM sqlite\_master

Here is what I've done and the result:

The CREATE TABLE CALL:

*create TABLE IF NOT EXISTS TAB\_JOUEUR ('tjoueur\_id' INTEGER,"tjoueur\_prenom" TEXT , "tjoueur\_nom" TEXT, "tjoueur\_ville" TEXT , PRIMARY KEY("tjoueur\_id" AUTOINCREMENT))*

The result of the SELECT * FROM sqlite\_master

* type = table
* name = TAB\_JOUEUR
* tbl\_name = TAB\_JOUEUR
* rootpage = 2
* sql = CREATE TABLE TAB\_JOUEUR ('tjoueur\_id' INTEGER,"tjoueur\_prenom" TEXT , "tjoueur\_nom" TEXT,"tjoueur\_ville" TEXT , PRIMARY KEY("tjoueur\_id" AUTOINCREMENT))

and then

* type = table
* name = sqlite\_sequence
* tbl\_name = sqlite\_sequence
* rootpage = 3
* sql = CREATE TABLE sqlite\_sequence(name,seq)

As you can see the sql field relative to the table "TAB\_JOUEUR" as the CREATE call but it's not a pure copy of the original CREATE call. The original one as "create" in lower case, had extra spaces and has a "IF NOT EXISTS" which we don't have in the sql field of sqlite\_master. But the part between the () is **exactly** the same (single quote for tjoueur\_id, double for tjoueur\_nom, extra spaces...)

**4 - The trick**

In order to rename a table, you just have to make a SELECT on sqlite\_master in order to get the record of the table you want to rename. Then, change the content of the sql field to replace the "old name" by the "new one", and perform an update, using the rootpage as id. So like that:

```
void alter_table(String old_name, String new_name){

int rc ;
String data_rootpage;
String data_sql;
int pos_start;
char *err_msg = 0;

String query_sql = "SELECT rootpage,sql FROM sqlite_master WHERE type='table' AND name = '"+old_name+"'";

const char* sql = query_sql.c_str();
rc = sqlite3_prepare_v2(db_handle, sql, -1, &stmt, NULL);
rc = sqlite3_step(stmt);
data_rootpage = (const char *)sqlite3_column_text(stmt, 0);
data_sql = (const char *)sqlite3_column_text(stmt, 1);

// Find first ( in the string
pos_start = data_sql.indexOf ('(');
String tmp = "CREATE TABLE "+new_name+" "+data_sql.substring(pos_start);

query_sql = "UPDATE sqlite_master SET sql='"+tmp+"', name='"+new_name+"', tbl_name='"+new_name+"' WHERE rootpage = "+data_rootpage;
sql = query_sql.c_str();
rc = sqlite3_exec(db_handle, sql, 0, 0, &err_msg);

sqlite3_close(db_handle);
sqlite3_initialize();
sql_connect("/littlefs/transcom.db", &db_handle);}

```

It's basic and don't have test (you must add some!). I start by searching for the record concerning the "old\_name" table. In the sql field I search for the "(" and then I replace the first part of the sql field data with the new name of the table. Then I update. Notice I don't escape the quote because I've previously make a CREATE call without any ' or " (easier!)

After that, I perform a sqlite3\_close() then re-open with sqlite3\_initialize(); If you don't do that, SQLite don't take change in account (maybe there is a cache for data).

**5 - Great but... not enought!**

If you try this, you'll get an error on the update call. That's because for you, "user", sqlite\_master is a read only table. So you can't update it. In order to prevent writing on some table (like the sqlite\_master one), when SQLite create it, it sets a "read only" flag. The trick is to edit the source code in order to give to this flag, the value of "read and write". In the sqlite3.c of the LIB, it's a line 17420. You'll see:

```
  #define TF_Readonly        0x0001    /* Read-only system table */

```

Just change it by

```
   #define TF_Readonly        0x0000    /* Read-only system table */

```

So when SQLite will create a system table, it will set a read+write flag and so, you would be able to update the sqlite\_master table. You need to compile again de lib (on Arduino IDE, just select a wrong board, try to compile, get an error, select ESP32 and compile again and the IDE will perform a full compilation of the lib)

If you have trigger, and some other specific feature, maybe it would be nice to check the result of the select * from sqlite\_master in order to see if some records need also to be updated. But for basic table, this will do the job.

Hope this will help.

***Edit***

If you add an index (or more than one) to your table, you'll have also to update 'index" records from sqlite\_master. They are like that:

* type = index
* name = index\_ttest\_nom
* tbl\_name = TAB\_TEST
* rootpage = 6
* sql = CREATE UNIQUE INDEX index\_ttest\_nom ON TAB\_TEST (ttest\_nom)

So just update the tbl\_name value giving the new name of the table, and update the sql field the same way.
> 1 votes

---
Tags: esp32
---


title: SIM800L and UNO can't request web page

text:
# Question
Title: SIM800L and UNO can't request web page
I know this module is super old but the network I am on still uses GPRS so should work.

This is the module:  I am using the Adafruit example scipt FONAtest. I can connect to GPRS

```
    <--- SHUT OK
    ---> AT+CGATT=1
    <--- OK
    ---> AT+SAPBR=3,1,"CONTYPE","GPRS"
    <--- OK
    ---> AT+SAPBR=3,1,"APN","live.vodafone.com"
    <--- OK
    ---> AT+CSTT="live.vodafone.com","",""
    <--- OK
    ---> AT+SAPBR=3,1,"USER",""
    <--- OK
    ---> AT+SAPBR=3,1,"PWD",""
    <--- OK
    ---> AT+SAPBR=1,1
    <--- OK
    ---> AT+CIICR
    <--- OK
FONA>

```

There is credit on the SIM so it has data for sure, I can also send SMS.

There are several different approaches people seem to take (altering AT commands) to persuade this device to work, pretty sure I have tried all of them :) I always get a timeout when trying to read or GET a webpage.

I have tried several combinations via terminal and I seem to connect ok but get no further. It has worked once, but that was in a different part of town.

How do I check that the GPRS is actually connected? Any troubleshooting tips?

There is a dedicated 2A 5V connected to the unit, it isn't dropping out AFAIK. Do you have a rock-solid AT sequence that always works?

Also, there seem to be SAPBR commands that don't work at all, not sure why?

# Answer
It highly depends on the URL you are trying to fetch.
Those modules DO NOT understand secure HTTP/S. They only understand plain unsecure HTTP.
Most web pages nowdays don't offer unsecure HTTP access and always redirect the request to a HTTP/S server. So in my opinion the usefulness of those devices is very limited when it comes to internet access.

If you have full control over the web server you should disable the enforcement of a secure connection.

Beyond that. The sequence you posted is just for activating GPRS.

I also found the FONA sample for fetching a page not very reliable but I was able to request the page multiple time. Perheps you have your module in a place with low signal strenght. Does your module offer an u.fl connector for a better antenna?
> 1 votes

# Answer
Don't know why, I had to manually set the DNS t0 8.8.8.8 using `AT+CDNSCFG?`

It had DNS entries in there but they didn't want to resolve for some reason.
> 1 votes

---
Tags: communication
---


# Question
Title: As a novice, how do I program my Atmega328p?
I bought a board which the above MCU is the atmega328p. Since I haven't used atmel MCU before, now it's a bit confusing. Are the ATMEGA and STM32 programmers not universal? What programming methods can this chip support? Is there serial programming or SWD programming? Need help. Many thanks!

# Answer
> 4 votes
> **Are the ATMEGA and STM32 programmers not universal?**

They are not the same. As far as I know their programming arrangements are completely distinct.

> **What programming methods can this chip support?**

* Traditional AVR In-Circuit-Serial-Programming (ICSP) using a 2x3 header pin connector and one of a variety of programmers such as the STK500 which has low-cost clones like the Pololu AVR programmer (less than $10). These programmers typically connect to a PC's USB port and can be used either with the software development tools from Atmel (now Microchip) or using the Arduino integrated development environment (IDE) which uses a program named avrdude to communicate with the ATMega328P (or other AVR family MCUs). ICSP is sometimes called In System Programming (ISP). It uses the MCU's SPI interface and you have to be careful what other circuitry is attached to those pins when you program the device.
* Serial-port programming by communicating with a pre-loaded "bootloader" program installed in the ATMega328P. This is the normal way to use the Arduino IDE but it depends on having that bootloader installed. Most bare ATMega328Ps are sold without this bootloader installed. All "Arduino" boards will have a bootloader installed in their MCU and many will have a serial-to-USB interface on-board so that the board can be plugged in to a PC directly. Otherwise you would need a USB-to-Serial interface like the Adafruit FTDI friend or many others.

There is also a high-voltage programming method but that isn't something a novice would need to use. I believe it is most often needed when you have configured the MCU in such a way that the above methods cannot be used. For example after having disabled the reset pin so it can be used as an IO pin that can be pulled to GND without resetting the MCU.

You can use an Arduino to emulate a programmer and use that to program boards that lack a USB serial interface. This is called Arduino as ISP

Microchip's newer generation of AVR MCUs use a different programming method than ICSP called UPDI.

# Answer
> 1 votes
> What programming methods can this chip support? Is there serial programming or SWD programming?

The Arduino IDE (a free download) supports programming in C++. The IDE pre-processes your code (which they call a "sketch") slightly but it is still C++.

You can drop into assembler if you absolutely must, but the C++ compiler does a good job of producing efficient code, almost always.

With the assistance of a serial interface (many Arduinos, like the Uno, have one built-in connected to a USB interface) you can quickly and easily upload your code. The wherewithal to do that is built into the IDE.

---
Tags: atmega328, bootloader, electronics
---


title: Accelerometer value meaning

text:
# Question
Title: Accelerometer value meaning
I'm currently using the MPU-6050 accelerometer to receive the acceleration and angular velocity data. I'm trying to process the data for my experiment but I can't understand the exact meaning of it. I have threee questions about the situation. I append the arduino code below.

First, I happen to know that the AcX value of the code below means how much the sensor is inclined along the x axis. Is there other way to get acceleration directly? or Do I have to use formula(v = v\_0 + a\*t)?

Second, for the gyro sensor, I can't understand the meaning of the value. Does it sends the angular velocity or angular acceleration and if it is one of these, what's the limit?

Third, according to code, it receives data in the form of 2^14(14bit) but sometimes it sends value way over the limit. How can I translate raw data to rather regular unit like degree and rad?

Thank you

```
const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,GyX,GyY,GyZ;

void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);
  Serial.println("CLEARDATA");
  Serial.println("LABEL,TIME,AcX,AcY,AcZ,GyX,GyY,GyZ");
}

void loop(){
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers

  // deviding the 16bit input??
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

  //Serial.print("AcX = ");
  Serial.print(AcX);
  Serial.println(",");
  //Serial.print(",");
  //Serial.print(" | AcY = ");
  //Serial.print(AcY); Serial.print(",");
  //Serial.print(" | AcZ = ");
  //Serial.print(AcZ); Serial.print(",");
  //Serial.print(" | GyX = ");
  //Serial.println(GyX);
  //Serial.print(" | GyY = ");
  Serial.println(GyY); //Serial.print(",");
  //Serial.print(" | GyZ = ");
  //Serial.println(GyZ);
  delay(200);
}

```

# Answer
> Is there other way to get acceleration directly? or Do I have to use formula(v = v\_0 + a\*t)?

The code appears to be currently retrieving the raw X, Y & Z acceleration and storing it in AcX, AcY & AcZ. The equation "v = v\_0 + a\*t" appears to be deriving velocity. So the question is confusing.

> ...for the gyro sensor, I can't understand the meaning of the value. Does it sends the angular velocity or angular acceleration

The accelerometer sensors measure acceleration. As the last question ultimately asked for angles, the gyroscope is not needed. However, on page 12 in the MPU-6050 specifications the dimensions of the gyroscope is given in degrees per second or angular velocity. Likely the mechanism within the chip depends on the Coriolis effect

> ...and if it is one of these, what's the limit?

On the same page the MPU-6050 chip specification shows a table containing values such as GYROSCOPE SENSITIVITY & Full-Scale Range. Consider reading these and other values regarding the gyroscope.

> ...according to code, it receives data in the form of 2^14(14bit) but sometimes it sends value way over the limit.

The code retrieves a high 8 bit and low 8 bit value for each axis of the accelerometer and the gyroscope. This makes a 16 bit value. Not a 14 bit value.

> How can I translate raw data to rather regular unit like degree and rad?

1. To obtain an angle in degrees only the accelerometer is required.
2. Consider calibrating the accelerator for offset and magnitude errors before using the raw values.
3. Consider constraining the problem such that the accelerometer is only rotated around the Z-axis.
4. The angle can be found by taking the inverse tangent of the ratio of the calibrated X acceleration and calibrated Y acceleration.

Other considerations:

* If angles are desired in 3 dimensional space consider using commonly referred to values such as pitch, roll & yaw. In which case many situate the accelerometer such to use these equations:

The above equations, a discussion and some example code can be found here.

* So far, all the equations discussed use trigonometry and can go to infinity (unusable results) given certain inputs. The mathematical equivalent of gimbal lock if you will. To avoid this consider using quaternions. This mathematical method of representing rotation in 3 dimensional space does not suffer the above problem, is easier for computers to calculate and is used extensively in computer graphics.
> 1 votes

---
Tags: arduino-uno, mpu6050, accelerometer
---