title: NRF24L01 writing fail

text:
# Question
Title: NRF24L01 writing fail
My arduino uno with the NRF24L01 combination gives failed messages on writing.

Using the basic example code 'getting started' literally copied from: http://tmrh20.github.io/RF24/GettingStarted\_8ino-example.html, my serial monitor constantly writes 'failed' (See attached screenshot)

The setup is for my Arduino uno as described in the table on http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo#PP (Arduino pin for TMRh20 RF24 Library)

The code:

```
/*
* Getting Started example sketch for nRF24L01+ radios
* This is a very basic example of how to send data from one node to another
* Updated: Dec 2014 by TMRh20
*/
#include <SPI.h>
#include "RF24.h"
#include <printf.h>

/****************** User Config ***************************/
/***      Set this radio as radio number 0 or 1         ***/
bool radioNumber = 1;
/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */
RF24 radio(7,8);
/**********************************************************/
byte addresses[][6] = {"1Node","2Node"};
// Used to control whether this node is sending or receiving
bool role = 0;
void setup() {
  Serial.begin(115200);
  printf_begin();
  Serial.println(F("RF24/examples/GettingStarted"));
  Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));

  radio.begin();
  // Set the PA Level low to prevent power supply related issues since this is a
 // getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.
  radio.setPALevel(RF24_PA_LOW);

  // Open a writing and reading pipe on each radio, with opposite addresses
  if(radioNumber){
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
  }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
  }
  radio.printDetails();
  // Start the radio listening for data
  radio.startListening();
}
void loop() {

/****************** Ping Out Role ***************************/
if (role == 1)  {

    radio.stopListening();                                    // First, stop listening so we can talk.

    Serial.println(F("Now sending"));
    unsigned long start_time = micros();                             // Take the time, and send it.  This will block until complete
     if (!radio.write( &start_time, sizeof(unsigned long) )){
       Serial.println(F("failed"));
     }

    radio.startListening();                                    // Now, continue listening

    unsigned long started_waiting_at = micros();               // Set up a timeout period, get the current microseconds
    boolean timeout = false;                                   // Set up a variable to indicate if a response was received or not

    while ( ! radio.available() ){                             // While nothing is received
      if (micros() - started_waiting_at > 200000 ){            // If waited longer than 200ms, indicate timeout and exit while loop
          timeout = true;
          break;
      }
    }

    if ( timeout ){                                             // Describe the results
        Serial.println(F("Failed, response timed out."));
    }else{
        unsigned long got_time;                                 // Grab the response, compare, and send to debugging spew
        radio.read( &got_time, sizeof(unsigned long) );
        unsigned long end_time = micros();

        // Spew it
        Serial.print(F("Sent "));
        Serial.print(start_time);
        Serial.print(F(", Got response "));
        Serial.print(got_time);
        Serial.print(F(", Round-trip delay "));
        Serial.print(end_time-start_time);
        Serial.println(F(" microseconds"));
    }
    // Try again 1s later
    delay(1000);
  }
/****************** Pong Back Role ***************************/
  if ( role == 0 )
  {
    unsigned long got_time;

    if( radio.available()){
                                                                    // Variable for the received timestamp
      while (radio.available()) {                                   // While there is data ready
        radio.read( &got_time, sizeof(unsigned long) );             // Get the payload
      }

      radio.stopListening();                                        // First, stop listening so we can talk
      radio.write( &got_time, sizeof(unsigned long) );              // Send the final one back.
      radio.startListening();                                       // Now, resume listening so we catch the next packets.
      Serial.print(F("Sent response "));
      Serial.println(got_time);
   }
 }
/****************** Change Roles via Serial Commands ***************************/
  if ( Serial.available() )
  {
    char c = toupper(Serial.read());
    if ( c == 'T' && role == 0 ){
      Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
      role = 1;                  // Become the primary transmitter (ping out)

   }else
    if ( c == 'R' && role == 1 ){
      Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
       role = 0;                // Become the primary receiver (pong back)
       radio.startListening();

    }
  }
} // Loop

```

While my other arduino has the same setup only radioNumber = 0 on that one.

The monitor output:

My setup:

EDIT: Ok so i managed to run printDetails() (thanks for the help on that one) This came up with:

```
STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0x65646f4e31 0x65646f4e32
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0x65646f4e31
RX_PW_P0-6   = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA        = 0x3f
EN_RXADDR    = 0x02
RF_CH        = 0x4c
RF_SETUP     = 0x03
CONFIG       = 0x0e
DYNPD/FEATURE    = 0x00 0x00
Data Rate    = 1MBPS
Model        = nRF24L01+
CRC Length   = 16 bits
PA Power     = PA_LOW

```

on arduino one, and with the following on arduino 2 with radionumber = 1

```
STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0x65646f4e32 0x65646f4e31
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0x65646f4e32
RX_PW_P0-6   = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA        = 0x3f
EN_RXADDR    = 0x02
RF_CH        = 0x4c
RF_SETUP     = 0x03
CONFIG       = 0x0e
DYNPD/FEATURE    = 0x00 0x00
Data Rate    = 1MBPS
Model        = nRF24L01+
CRC Length   = 16 bits
PA Power     = PA_LOW

```

# Answer
I'm currently writing a driver (for fun) and noticed that if the clock line is not at the correct idle logic level when the CS pin goes low, the chip freaks out and gives me issues when reading/writing registers. This may or may not help you, but figured it would be worth a shot to mention it.

Edit: The chip expects CPOL 0, so I used a pull down resistor on the clock line. So it will by default idle low.
> 1 votes

# Answer
See how/whether Arduino actually communicates with the master nRF, before tackling the problem of the tx/rx.

Use the code given below to print out the tx and rx radio registers (no libraries required except SPI). You will need to use the right values for CE and CSN pins. Post the data in your question, there are many several people on stack exchange who will be able to help you find the solution.

```
#include <SPI.h>
#define CE_pin 4
#define CSN_pin 5
#define MOSI_pin 11
#define MISO_pin 12
#define SCK_pin 13
byte data_in;

byte radio1_tx_addr[5] = {0xC5, 0xC5, 0xC5, 0xC5, 0xC5};
byte radio2_tx_addr[5] = {0x31, 0x31, 0x31, 0x31, 0x31};

void setup() {
  Serial.begin(115200);
  pinMode(CE_pin, OUTPUT);//chip enable set as output
  pinMode(CSN_pin, OUTPUT);//chip select pin as output
  pinMode(MOSI_pin, OUTPUT);//SPI data out
  pinMode(MISO_pin, INPUT); //SPI data in
  pinMode(SCK_pin, OUTPUT);//SPI clock out
  SPI.setBitOrder(MSBFIRST);//SPI Most Significant Bit First
  SPI.setDataMode(SPI_MODE0);// Mode 0 Rising edge of data, keep clock low
  SPI.setClockDivider(SPI_CLOCK_DIV2);//Run the data in at 16MHz/2 - 8MHz
  digitalWrite(CE_pin, HIGH);//RX mode
  digitalWrite(CSN_pin, HIGH);//SPI idle
  SPI.begin();//start up the SPI library
  delay(100);

  nrf_set_TX_ADDR(radio1_tx_addr); // set TX/RX addresses
  nrf_set_RX_ADDR_P1(radio2_tx_addr);

  Serial.print("CONFIG");
  nrf_read_register(0x00);
  Serial.print("EN_AA");
  nrf_read_register(0x01);
  Serial.print("EN_RXADDR");
  nrf_read_register(0x02);
  Serial.print("SETUP_AW");
  nrf_read_register(0x03);
  Serial.print("SETUP_RETR");
  nrf_read_register(0x04);
  Serial.print("RF_CH");
  nrf_read_register(0x05);
  Serial.print("RF_SETUP");
  nrf_read_register(0x06);
  Serial.print("STATUS");
  nrf_read_register(0x07);
  Serial.print("OBSERVE_TX");
  nrf_read_register(0x08);
  Serial.print("RPD");
  nrf_read_register(0x09);
  Serial.print("RX_ADDR_P0");
  nrf_read_register(0x0A);
  Serial.print("RX_ADDR_P1");
  nrf_read_register(0x0B);
  Serial.print("RX_ADDR_P2");
  nrf_read_register(0x0C);
  Serial.print("RX_ADDR_P3");
  nrf_read_register(0x0D);
  Serial.print("RX_ADDR_P4");
  nrf_read_register(0x0E);
  Serial.print("RX_ADDR_P5");
  nrf_read_register(0x0F);
  Serial.print("TX_ADDR");
  nrf_read_register(0x10);
  Serial.print("RX_PW_P0");
  nrf_read_register(0x11);
  Serial.print("RX_PW_P1");
  nrf_read_register(0x12);
  Serial.print("RX_PW_P2");
  nrf_read_register(0x13);
  Serial.print("RX_PW_P3");
  nrf_read_register(0x14);
  Serial.print("RX_PW_P4");
  nrf_read_register(0x15);
  Serial.print("RX_PW_P5");
  nrf_read_register(0x16);
  Serial.print("FIFO_STATUS");
  nrf_read_register(0x17);
  Serial.print("DYNPD");
  nrf_read_register(0x1C);
  Serial.print("FEATURE");
  nrf_read_register(0x1D);
}

void loop() {
}

void nrf_read_register(byte reg) {
  digitalWrite(CSN_pin, LOW);
  SPI.transfer(reg);
  data_in = SPI.transfer(0x00);
  digitalWrite(CSN_pin, HIGH);
  Serial.print(": 0x");
  Serial.print(reg,HEX);
  Serial.print(" => 0x");
  Serial.println(data_in,HEX);
  delay(10);
}

void nrf_set_TX_ADDR(byte x) {
  digitalWrite(CSN_pin, LOW);
  SPI.transfer(0x30);
  SPI.transfer(x[0]);
  SPI.transfer(x[1]);
  SPI.transfer(x[2]);
  SPI.transfer(x[3]);
  SPI.transfer(x[4]);
  digitalWrite(CSN_pin, HIGH);
  delay(10);
}

void nrf_set_RX_ADDR_P1(byte x) {
  digitalWrite(CSN_pin, LOW);
  SPI.transfer(0x2B);
  SPI.transfer(x[0]);
  SPI.transfer(x[1]);
  SPI.transfer(x[2]);
  SPI.transfer(x[3]);
  SPI.transfer(x[4]);
  digitalWrite(CSN_pin, HIGH);
  delay(10);
}

```
> 0 votes

---
Tags: arduino-uno, nrf24l01+
---


# Question
Title: could not convert 'digitalWrite(8u, 1u)' from 'void' to 'bool'
I am trying to make some LED lights to turn on when i flick a switch on my RC crontroller. I will connect the signal wire from RC controller to pin 8. The plan is: if i flick the swich, the LED's (pin 12,11,10,9) will turn on, and if i don't flick the swich the LED's wont turn on. This is a Arduino nano what will be connected on a drone.I found another question HERE, but there was no real answers. I get a error that say:

> exit status 1 could not convert 'digitalWrite(8u, 1u)' from 'void' to 'bool'

How can i fix this? Should i write the code another way?

Arduino Code:

```
    void setup() {

  pinMode(4, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, INPUT);

}

void loop() {

  if (digitalWrite(8, HIGH));
    digitalWrite(12, HIGH);
    digitalWrite(11, HIGH);
    digitalWrite(10, HIGH);
    digitalWrite(9, HIGH);
  else
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);

  digitalWrite(4,HIGH);
  delay(1500);
  digitalWrite(4,LOW);
}

```

# Answer
> 1 votes
You should be using `digitalRead(8)` instead of `digitalWrite(8, HIGH)`. Your sketch is also missing some curly brackets.

```
void setup(){
  pinMode(4, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, INPUT);
}

void loop(){
  if(digitalRead(8) == HIGH){
    digitalWrite(12, HIGH);
    digitalWrite(11, HIGH);
    digitalWrite(10, HIGH);
    digitalWrite(9, HIGH);
  }
  else{
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
  }
  digitalWrite(4,HIGH);
  delay(1500);
  digitalWrite(4,LOW);
}

```

The use of `delay()` will block the sketch from doing anything else, and should be replaced with a `millis()` timer. Have a look at the `BlinkWithoutDelay` example in the IDE.

# Answer
> 1 votes
This line of code is the source of your problem.

> ```
> void loop() {
>
>   if (digitalWrite(8, HIGH));
>
> ```

If expressions expect a boolean (true/false), but if you check the documentation for `digitalWrite()`, you’ll see it returns “Nothing” (i.e. `void`).

You need to use `digitalRead()` to check the current state of the pin.

---
Tags: arduino-ide, arduino-nano, led, drone
---


# Question
Title: Preforming impedance termination for UART Communication (TX and RX) pins
I need two Arduino devices (Arduino Mega and Nano) to communicate with each other via UART. The two Arduino devices are long distance apart from each other. The distance is `1.5` meters.

* The *Arduino 1* TX pin is connected to *Arduino 2* RX pin.
* The *Arduino 1* RX pin is connected to *Arduino 2* TX pin.

Now, I have to use resistor to preform impedance termination so that the long distance does not cause transmitting and receiving issues between the two devices. I did some research and *found* an image that shows the signal differences when impedance termination is preformed and when it is not.

I have *two* questions:

**1**. Since the distance between both Arduino devices is `1.5` meters, what resistor value should I use? How is that calculated?

**2**. Where do you put the resistors? It's not really clear on where to connect the resistors. Between ground and the RX pins on each device?

I don't know the gauge ratings of my wire but if that information is needed, I am using this wire.

# Answer
The relevant parameter is not the length of the link, but its characteristic impedance. For a twisted pair connection, this is typically in the order of 100 to 120 Ω. It should be specified in the datasheet. Your cable is not a twisted pair, but its geometry is quite close. Just make sure that there is a ground or Vcc line between the two data wires in order to minimize cross-talk. If you want to compute that impedance yourself, here is an online calculator.

Connect the resistor in series with the TX pin, i.e. between the pin and the data wire. Note that the pin already has an internal output resistance of about 25 Ω, so you would add no more than 100 Ω in series.

If you search online about termination resistors, you may learn tat they are often put between the receive pin and ground, or even at both the sending and the receiving end. In high frequency applications, the latter is often the preferred configuration, as it prevents the signal to be reflected from either end of the link. However, for logic-level signals, that configuration would attenuate the signal too much. On the other hand, terminating only at the receiver would put excessive load on the TX pin. Thus, sender-side termination is your best option. A resistor in series with TX does not prevent a reflection at the RX end, but it prevents the reflected signal to be reflected again and cause oscillations.
> 2 votes

---
Tags: communication, uart, resistor
---


# Question
Title: Connecting Winsen ZE11-C2H4 Sensor to Arduino
How should I connect the ZE11 Ethylene Sensor to an Arduino Uno? I want to know how to attach the pins of the sensor to the Arduino and which resistor I should use. I'm very unprofessional at working with circuits so I most likely will need step-by-step help. To make things easier, I am attaching the datasheet associated with the sensor. The pin identification and technical parameters are on pages 3-4. Also if someone taught me how to do advanced coding for this project then that would be great. Please note that Winsen is a company based in China, so some things can be inaccurate because of translation. Any help is appreciated.

# Answer
Pin 5 & pin 6 are UART Bus. To use UART, connect pin 5 with TX pin on Arduino and pin 6 to RX pin on Arduino. Details about communication settings are at 4th page. I can't find library for that sensor so guess you're on your own.

UART also Know as Serial communication.
> 0 votes

---
Tags: arduino-uno, sensors, pins, robotics, wires
---


# Question
Title: I2C_graphical_LCD_display, fatal error: avr/pgmspace.h: No such file or directory
I have a problem with an ESP32 devkit V1 card. I'm trying to connect a WG12864A Winstar mod graphics display via the I2C MCP23017 adapter (RobotDyn), using Nick Gammon's `I2C_graphical_LCD_display.h` library.

Everything works well by connecting it to the Arduino Uno - Duemilanove board. Loading the sketch `LCD_Demo_Using_I2C` present in the library is compiled correctly without errors.

If I connect the display to ESP32 devkit V1, I try to compile it I get the following error:

```
C: \ Users \ Topolino \ Documents \ Arduino \ libraries \ I2C_graphical_LCD_display-master / I2C_graphical_LCD_display.h: 62: 26: fatal error: avr / pgmspace.h : No such file or directory.
Compilation terminated.
exit status 1
Error during compilation for DOIT ESP32 DEVKIT V1 card.

```

I tried to compile it with PlatformIO presents the usual compilation error. You can help me, someone has some ideas to solve the problem.

# Answer
The authors of the ESP32 core didn't bother to create a proper set of compatability shims for the PROGMEM system - chiefly because it's not needed for ESP32 operation.

We did for chipKIT, though, and you can grab a copy of ours here and place it in with the core files for the ESP32 in your Arduino installation (you only need the `pgmspace.h` file, and place it in an `avr` folder inside the core source folder).

It's completely architecture agnostic and basically defines some pretty much empty macros, and maps `_P` variants of various functions to the non `_P` alternatives.
> 1 votes

---
Tags: esp32
---


# Question
Title: How can I concatenate these two values as a string?
I've tried all the supposed solutions for the exact error, pasted into google, that I could find on every forum including this one and no matter the alleged solution I will either get the error about unsigned int to char\*, the error below, or invalid pointers.

Why is this platform so completely unfriendly in data type conversion? It's almost as if the creator/s never wanted any data types to be able convert.

Here's my code that is apparently useless:

```
  char* DeviceName = "Device-" +  ESP.getChipId();
  wifiManager.autoConnect(DeviceName);

```

Error: invalid conversion from 'const char\*' to 'char\*' \[-fpermissive\] char\* DeviceName = "Device-" + ESP.getChipId();

Then I tried to use the pointers, but I have no idea what I'm doing and I keep getting invalid pointer errors, and/or invalid conversion errors.

# Answer
> 0 votes
You can use the c function sprintf(, , ...) The char array has to be big enough to hold your text plus a null to terminate the string.

```
#include <Arduino.h>

void setup() {
  Serial.begin(115200);
  delay(1000);
  char out[20];
  sprintf(out, "Device-%08X",ESP.getChipId()); // %08X\n formats the hex and pads with 0s.

  Serial.println(out);
}

void loop() {}

```

Output:

```
Device-005D4D9D

```

---
Tags: arduino-ide, c++, c
---


# Question
Title: D1 mini does not resume operation as expected after deep sleep
I'm trying to get the D1 mini to return operation after `ESP.deepsleep()`. The code below compiles and gives the expected output for the first run. Five seconds after the announcement that that the device is going to sleep, there is a brief flash on the on board LED and I get a string of garbage on the serial monitor. Ideas for things to try would be appreciated.

```
// Testing d1 mini deep sleep
// D0 and RST are connected

/*  platformio.ini:
  [env:d1_mini]
  platform = espressif8266
  board = d1_mini
  framework = arduino
  monitor_speed = 115200
*/

#include <Arduino.h>

void blink();

void setup() {
  Serial.begin(115200);
  pinMode(D0, WAKEUP_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  blink();
  delay(1000);
  Serial.println("Going for some deep sleep");
  ESP.deepSleep(5e6); // 5e6 is 5 seconds
}

void blink() {
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
}

```

As you can guess I'm running this with platformio. The output on the serial monitor is:

```
stefan@Cameron ~/.../Projects/Deep sleep $ platformio device monitor --baud 115200
--- Miniterm on /dev/ttyUSB0  115200,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
Going for some deep sleep
sl␀l��|␀�l�|␂␌␌␄�␄l�␌c|ǃ␃�␛�r�cd�c��gg�doo���␌cpp��$sd{d␛�{��o�c�gbx␀�

```

There is a blink of the LED on the first run, nothing there either after the apparent reset.

# Answer
> 2 votes
The garbage is because the ESP8266 outputs boot information at 76800. This should include the boot reason and may help you understand why the code's not working as expected.

Try changing your Serial speed to 76800 in your code (just so that your messages don't end up being gibberish), use 76800 on platformio's monitor and you should be able to at least see what the D1 says it's doing.

You should see a line that ends in something like:

> rst cause: x, boot mode:(y, z)

*x* should be 1 ("Power reboot"), 2 ("External reset or wake-up from Deep-sleep" - obviously what you want), 3 ("Software WDT" - the software watchdog went off) or 4 ("Hardware WDT reset" - the hardware watchdog timer went off)

boot mode indicates where the runtime image came from - *y* should be 3 ("Flash"); anything else is really unlikely for your setup.

There's more info on this at ESP8266 Reset Causes and Common Fatal Exception Causes

If you try this please post how it goes! I'd like to hear more about what's going on here.

# Answer
> -1 votes
Try and clear out the whole memory. Maybe there is something that is messing it up.

I tried your code and it works for me. I do not have a D1 mini but I can't see any reason for it not to work. (due to hardware reasons)

I would include a delay and then output a newline in the setup. As it is your loop print is written after the boot info and gets lost at the end of the line.

Like I said, your code worked for me. But I find this more user friendly. https://raw.githubusercontent.com/wemos/D1\_mini\_Examples/master/examples/02.Special/DeepSleep/Blink/Blink.ino

Check again your connections. (I'm sure you have done that a dozen times)

---
Tags: esp8266, reset
---


# Question
Title: Getting at the PS_ON pin on a RAMPS1.4 mounted to a Mega
Got it! Check end of post for solution.

I'm running a Mega 2560 with a RAMPS 1.4 Shield which is usually used for 3D printing applications. For my use case I only want to get at the stepper motor drivers. The RAMPS is pulling its own 12V power supply (using an old xbox 360 brick rated for 12V and have tested with a multimeter) and the Arduino is pulling 5V from an RPI. But for some reason I seem unable to get the stepper motor A4988 drivers to pull anything from the 12V power supply. The LED on the RAMPS turns on, and the stepper drivers are pulling a little power (also tested) but obviously not enough to get them to make the motors turn. In other words, the RAMPS isn't using the external power supply.

I'm NOT using any of the 3D printer firmware like Marlin since it can't compile on Raspbian and I only want to get at the Stepper Motor Drivers and now in my case the PS\_ON pin...

Here's the schematic:

My code for trying to get the motors to turn (and flip the PS\_ON switch) is as follows:

```
int PS_ON = 12;
int X_STEP_PIN = 54;
int X_DIR_PIN = 55;
int X_ENABLE = 38;
int NUM_OF_STEPS = 400;
int WAIT_TIME = 500;
int LED_PIN = 13;

void setup(){

  digitalWrite(LED_PIN, HIGH);

  delay(2000);

  pinMode(PS_ON, OUTPUT);

  delay(20000);

  pinMode(X_DIR_PIN, OUTPUT);
  pinMode(X_STEP_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(X_ENABLE, OUTPUT);

  digitalWrite(PS_ON, LOW);
  digitalWrite(X_ENABLE, LOW);

  digitalWrite(X_DIR_PIN, HIGH);
  for(int n = 0; n < NUM_OF_STEPS; n++){
    digitalWrite(X_STEP_PIN, HIGH);
    digitalWrite(X_STEP_PIN, LOW);
    delay(WAIT_TIME);
    digitalWrite(LED_PIN,!digitalRead(LED_PIN));
  }

  delay(3000);

  digitalWrite(X_DIR_PIN, LOW);
  for(int n = 0; n < NUM_OF_STEPS; n++){
    digitalWrite(X_STEP_PIN, HIGH);
    digitalWrite(X_STEP_PIN, LOW);
    delay(WAIT_TIME);
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
  }
}

void loop(){

}

```

Any thoughts would be appreciated.

Here's how I got it to work.

Firstly if you're going to use a Xbox 360 PSU to power the RAMPS you need to tie together the red wire and the blue wire to force the box out of standby and make it give out a constant 12V (if you buy a 3rd party psu then the wire colors/layout will be different and you're on your own, but all the ones made by Microsoft for the base xbox 360 are color coded like this, including current Xbox One PSUs as far as I can tell).

There's also the option of connecting the blue to VCC and the red to GND on the RAMPS board (im not sure why that also works, but it's also mentioned in the docstring of the config.h or config\_adv file under power supply settings in the Marlin firmware which is where I got the idea)

At that point, if you're reading 12V on a multimeter on the 5A rail of the RAMPS, make sure the RAMPS is able to power itself without the Arduino, if it can you should be good to go. There seems to be no need to get at the PS\_ON at this point and you can power the RAMPS without any firmware.

# Answer
Got it working without using any firmware, going to sleep. Will update post in the morning for how I got it working for anyone else with a similar question in the future.
> 0 votes

---
Tags: programming, power, hardware, raspberrypi
---


# Question
Title: Fail programing a Sonoff Dual with Arduino IDE
1) I have a Sonoff Dual, which I wish to upload a Sketch.

2) Other Sonoff basic devices programed the same way, with succes. But when uploading the sketch the ( even the generic `Blink` sketch ) - I do not get any response from the Sonoff device.

3) pins were soldered correctly according this tutorial

4) Uploading the sketch succeeds, using FTDI set to 3.3v.

What might be the reason for it ? What can I do more to check it ? my only guess is that something has happened to Sonoff device - but it uploads successfully.

Guy

**Code (edit2)**

```
    /*
  Blink

  Turns an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
  it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  the correct LED pin independent of which board is used.
  If you want to know what pin the on-board LED is connected to on your Arduino
  model, check the Technical Specs of your board at:
  https://www.arduino.cc/en/Main/Products

  modified 8 May 2014
  by Scott Fitzgerald
  modified 2 Sep 2016
  by Arturo Guadalupi
  modified 8 Sep 2016
  by Colby Newman

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/Blink
*/
#define LED_BUILTIN 12
// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  delay(2000);
  Serial.println("HELLLLLLO");
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

```

**Upload**

```
Build options changed, rebuilding all
Sketch uses 251224 bytes (50%) of program storage space. Maximum is 499696 bytes.
Global variables use 28080 bytes (34%) of dynamic memory, leaving 53840 bytes for local variables. Maximum is 81920 bytes.
Erasing 0x80000 bytes starting at 0x00000000
Uploading 255376 bytes from /tmp/arduino_build_214375/Blink.ino.bin to flash at 0x00000000
................................................................................ [ 32% ]
................................................................................ [ 64% ]
................................................................................ [ 96% ]
..........                                                                       [ 100% ]

```

**Addede1: Port Selection:**

note: when taken port was not connected ( connects to USB0)

**edit3: erasing using `esptool.py`:**

```
guy@desktop:~$ esptool.py --port /dev/ttyUSB0 --chip esp8266 erase_flash
esptool.py v2.5.0
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP8285
Features: WiFi, Embedded Flash
MAC: 60:01:94:ad:bf:34
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 2.4s
Hard resetting via RTS pin...

```

# Answer
Your code is not good to detect if it works.

The esp8266 Serial needs some time until it prints. First print after the Serial.begin() isn't printed. I guess the reason is the USB chip.

According to schematic, the LED in Sonoff Dual is on pin 12
> 1 votes

---
Tags: esp8266, arduino-ide
---


# Question
Title: Trying to run Timer1 in ATmega2560 with assembly
I have a slight problem with Timer1 in arduino (ATmega2560) while coding it in assembly. I try to run the Timer1 in CTC mode - I configure everything well in my opinion, but the TCNT1 just doesn't increment each clock cycle, as it should. I checked the registers in Atmel Studio and everything seems okay, but maybe I forgot about something?

Here is the code

```
.ORG 0
jmp start

.ORG 0x22
call isr_toggle_PA0

.ORG 0x400
start:
LDI R16, HIGH(RAMEND)
OUT SPH, R16
LDI R16, LOW(RAMEND)
OUT SPL, R16 ; initialize stack pointer
clr r16

ldi r16, 0xff
out DDRA, r16 ; port A output
ldi r16, 0x00
out DDRD, r16 ; port D input
clr r16

ldi r20, 1<<OCIE1A
sts TIMSK1, r20 ; enable Timer1 A comapre match interrupt
sei

ldi r20, HIGH(25000)
sts OCR1AH, r20
ldi r20, LOW(25000)
sts OCR1AL, r20

ldi r20, 0b00000010 ; CTC mode, int clk;
sts TCCR1A, r20
ldi r20, 0b000000101 ; prescaler /1024
sts TCCR1B, r20
ldi r20, 0
sts TCCR1C, r20

; --- start main
main:

inc r16
rjmp main
; --- end main

isr_toggle_PA0: // toggle bit on PA0
    ldi r16,0x00000001
    in r17, PORTA
    eor r17,r16
    out PORTA, r17
    reti

```

Thank you and have a good day :)

# Answer
> 3 votes
Here:

```
ldi r20, 0b00000010 ; CTC mode, int clk;
sts TCCR1A, r20
ldi r20, 0b000000101 ; prescaler /1024
sts TCCR1B, r20

```

you are setting the bit `WGM11` on `TCCR1A`. The timer then runs in mode 2 (PWM, Phase Correct, 9-bit) rather than mode 4 (CTC).

---
Tags: timers, avr, atmega2560, assembly
---


# Question
Title: Code working well on Arduino Uno is not working with Mega 2560
Following is the code block from my script. It uses timer1. Why it is not compatible with Arduino Mega?

```
TCCR1A = theTCCR1A; // 0b10000010;
  /*10 clear on match, set at BOTTOM for compA.
   00 compB disconected initially, toggled later to clear on match, set at BOTTOM.
   00
   10 WGM1 1:0 for waveform 15.
   */
  TCCR1B = 0b00011001;
  /*000
   11 WGM1 3:2 for waveform 15.
   001 no prescale on the counter.
   */
  TIMSK1 = 0b00000001;
  /*0000000
   1 TOV1 Flag interrupt enable.
   */
  sei();             // Enable global interrupts.
  // Set outputs pins.
  DDRB   = 0b00000110; // Set PB1 and PB2 as outputs.
  pinMode(13, OUTPUT); // Set trigger pin to output

```

# Answer
It's not working because code you write is code that will work only on ATmega328. Every ATmega328 chip will run this code without any problem. If you want that Mega does same task as Uno, then you have to rewrite whole code and use Arduino functions(such as `pinMode`, `digitalRead` etc..) or read ATmega2560 datasheet and use ATmega2560 registers. Also Search for `ATmega2560 pin layout`, you'll need it if you want use registers.
> 0 votes

---
Tags: interrupt
---


title: FastLED: Can't address led individually

text:
# Question
Title: FastLED: Can't address led individually
I'm unable to access the first led in my strip with this code:

```
void loop()
{
  leds[0] = CRGB::White; FastLED.show(); delay(100);
  leds[0] = CRGB::Black; FastLED.show(); delay(100);
}

```

Instead, it blinks 3 leds, though I expect it to blink only the first one.

Here's how my setup code looks like:

```
#define DATA_PIN    1
#define CLK_PIN   5
#define LED_TYPE    WS2812B
#define COLOR_ORDER RGB
#define NUM_LEDS    60
CRGB leds[NUM_LEDS];

#define BRIGHTNESS          10

void setup() {
  delay(1000); // Power-up delay

  // tell FastLED about the LED strip configuration
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);

  // set master brightness control
  FastLED.setBrightness(BRIGHTNESS);
}

```

The led was bought from here: https://www.aliexpress.com/item/0-5-5M-30-60-LEDs-M-2811-Pixels-Programmable-Individual-Addressable-LED-Strip-light-WS2811/32849630888.html?spm=a2g0s.9042311.0.0.8e664c4dU4dru2

# Answer
The description in the link of where you bought the strip says:

> Description:
>
> 1. LED Type: 5050SMD with External IC WS2811 （1 IC control 3leds）

So, this is probably as intended.

Note the application circuits in the datasheet for the controller IC (WS2811) \[Page 5\] where, for 5V, you can address a single LED, but for a 12V configuration, you must group the LEDs in sets of 3.
> 5 votes

---
Tags: esp8266, nodemcu, rgb-led
---


# Question
Title: Receiving junk values in Arduino serial monitor console
I want to send a character from a Zigbee transmitter to an Arduino Mega 2560. After the character is received, Arduino should send some data back to Zigbee. But Arduino is always receiving junk values at the console. If I send a character, suppose 'a', instead of 'a', Arduino console is always showing 'y'. It is the same for every character I send.

```
#include <EEPROM.h>
#include <SoftwareSerial.h>
SoftwareSerial XBee(19, 18); // RX, TX
int addr = 0;
unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 1000;  //the value is a number of milliseconds
void setup()
{

  XBee.begin(9600);
  Serial1.begin(9600);
  Serial.begin(9600);
  startMillis = millis();  //initial start time
 }
void loop()
{
  int id = 1;
  EEPROM.write(addr, id);
  if (Serial1.available()>0)
    {
      currentMillis = millis();  //get the current "time" (actually the number of milliseconds since the program started)
  if (currentMillis - startMillis >= period)  //test whether the period has elapsed
  {
    char recbyte=Serial.read();
    Serial.print(recbyte);
    // delay(1500);
    Serial1.write(id);
    Serial1.write(" 30 ");
    Serial1.write(" 99 ");
    Serial1.write(" 72 ");
    Serial1.write(" 1098 ");
    Serial1.write(" 728 ");
    Serial1.write(" 578 ");
    // Serial1.write("$");
    Serial1.write('PS=1\r\n');
    Serial1.end();
    startMillis = currentMillis;
  }
    }
}

```

# Answer
> 1 votes
You have created a SoftwareSerial instance called XBee which is taking pins 17 and 18. You then use Serial1 which is pins 17 and 18.

You do not want, nor need, the XBee SoftwareSerial instance, since you are using hardware serial pins. Delete it and all references to it.

Also, you are turning off Serial1 after using it, which means it will never work again:

```
Serial1.end();

```

You would only use that instruction in very very specific circumstances. Delete it.

After checking to see if there is data available to read on Serial1 you then proceed to try and read it from Serial:

```
char recbyte=Serial.read();

```

That should be:

```
char recbyte=Serial1.read();

```

You are writing to EEPROM on every single iteration of loop:

```
EEPROM.write(addr, id);

```

It is likely that you have already killed your EEPROM. C'est la vie...

---
Tags: serial, atmega2560
---


title: Resetting I2c Address - MLX90614

text:
# Question
Title: Resetting I2c Address - MLX90614
I was using my MLX90614 IRTherm sensor flawless and bought two more. I have connected two sensors serial with pull-ups to `SDA --> A4 and SCL --> A5`. After digging the internet I found out that I should change their default slave addresses to different addresses so that Arduino can recognize their 7-bit slave addresses. After changing their address, now I can't read either two new serial MLX'es or my old MLX.

* I might have messed up with their addresses and don't know how to reset their addresses.
* How can i connect multiple sensors/ how can i change their adress properly?

> reading sensor data

```
#include <Wire.h> // I2C library, required for MLX90614
#include <SparkFunMLX90614.h> // SparkFunMLX90614 Arduino library

IRTherm therm; // Create an IRTherm object to interact with throughout

const byte LED_PIN = 8; // Optional LED attached to pin 8 (active low)

void setup()
{
  Serial.begin(9600); // Initialize Serial to log output
  therm.begin(0x5A); // Initialize thermal IR sensor
  therm.setUnit(TEMP_F); // Set the library's units to Farenheit
  // Alternatively, TEMP_F can be replaced with TEMP_C for Celsius or
  // TEMP_K for Kelvin.

  pinMode(LED_PIN, OUTPUT); // LED pin as output
  setLED(LOW); // LED OFF
}

void loop()
{
  setLED(HIGH); //LED on

  // Call therm.read() to read object and ambient temperatures from the sensor.
  if (therm.read()) // On success, read() will return 1, on fail 0.
  {
    // Use the object() and ambient() functions to grab the object and ambient
    // temperatures.
    // They'll be floats, calculated out to the unit you set with setUnit().
    Serial.print("Object: " + String(therm.object(), 2));
    Serial.write('°'); // Degree Symbol
    Serial.println("F");
    Serial.print("Ambient: " + String(therm.ambient(), 2));
    Serial.write('°'); // Degree Symbol
    Serial.println("F");
    Serial.println();
  }
  setLED(LOW);
  delay(500);
}

void setLED(bool on)
{
  if (on)
    digitalWrite(LED_PIN, LOW);
  else
    digitalWrite(LED_PIN, HIGH);
}

```

> Setting address
>
> ```
> #include <Wire.h> // I2C library, required for MLX90614
> #include <SparkFunMLX90614.h> // SparkFunMLX90614 Arduino library
>
> IRTherm therm; // Create an IRTherm object to interact with throughout
>
> const byte oldAddress = 0x5A;
> const byte newAddress = 0x5B;
>
> void setup()
> {
>   Serial.begin(9600); // Initialize Serial to log output
>   Serial.println("Press a key to begin");
>   while (!Serial.available()) ;
>
>   therm.begin(oldAddress); // Try using the old address first
>
>   byte address;
>   if (!therm.readID()) // Try reading the ID registers
>   {
>     // If the read fails, try re-initializing with the
>     // new address. Maybe we've already set it.
>     therm.begin(newAddress);
>
>     if (therm.readID()) // Read from the ID registers
>     { // If the read succeeded, print the ID:
>       Serial.println("Communicated with new address.");
>       Serial.println("ID: 0x" +
>                      String(therm.getIDH(), HEX) +
>                      String(therm.getIDL(), HEX));
>     }
>     else
>     {
>       Serial.println("Failed to communicate with either address.");
>     }
>   }
>   else
>   {
>     // If the read suceeds, change the address to something
>     // new.
>     if (!therm.setAddress(newAddress))
>     {
>       Serial.println("Failed to set new address.");
>     }
>     else
>     {
>       Serial.println("Set the address to 0x" + String(newAddress, HEX));
>       Serial.println("Cycle power to try it out.");
>     }
>   }
> }
>
> void loop()
> {
>
> }
>
> ```

Edit 1: Datasheet

# Answer
Page 13 of 35 in the datasheet states:

> In order to provide access to any device or to assign an address to a SD before it is connected to the bus system, the communication must start with zero SA followed by low RWB bit. When this command is sent from the MD, the MLX90614 will always respond and will ignore the internal chip code information.

Supposedly, all you have to do is to connect only one device and use the address zero to read/write the registers.
> 1 votes

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


# Question
Title: Can SPI and serial.begin be used at the same time?
I have two modules where I want to control them through a single Arduino UNO.

I guess Serial.begin(9600) uses serial port and UART. But Im not sure about SPI.

Can I use SPI library hence the SPI communication together with serial communication(serial.begin) at the same time to communicate with two different modules?

# Answer
Yes. UART and SPI are completely different things. One uses pins 0/1, the other uses pins 11/12/13, and they use separate hardware and control registers inside the chip.
> 3 votes

---
Tags: spi
---


# Question
Title: How to Connect Dc motor with encoder (pololou) with motor shield and Arduino Mega 2560?
I tried to search a bout how to connect plolou motor with encoder to arduino mega and the motor control shield as in those pics  if any one knows how to connect those to each other please tell me

# Answer
A quick look on Pololu's website reveals that:

```
    Color   Function
  --------  --------------------------------------------
    Red     motor power (connects to one motor terminal)
    Black   motor power (connects to the other motor terminal)
    Green   encoder GND
    Blue    encoder Vcc (3.5 – 20 V)
    Yellow  encoder A output
    White   encoder B output

```

Thus: Red goes to M1A and Black goes to M1B on the motor shield. The remaining wires are for the encoder and go to Arduino pins. Green goes to Arduino GND, Blue goes to 5V, Yellow and White go to the digital i/O pins of your choice.

Note: Your motor shield has extra 5V and GND pins so you can connect the Blue and Green wires there.
> 1 votes

---
Tags: arduino-motor-shield
---


# Question
Title: How to read the raw data from GY-85 module?
This module has 3 sensors. Gyroscope, Accelerometer and Magnetometer.

I think I'm reading the raw data in the wrong way.

For example, for the magnetometer HMC5883L, I'm using this code which I copied from a library and it gives the correct values, but when I use the same code for reading the raw data from the accelerometer ADXL345 then it's not what it should be according to different sources I've read.

1. The magnetometer HMC5883L:

```
void HMC5883L_print_Serial(void)
{
  int16_t x,z,y;
  uint8_t data[6];
  float heading,heading_in_degrees,declination_angle_YANBU;

  data_read(data);

  // This one doesn't
  x = data[1] << 8 | data[0];
  z = data[3] << 8 | data[2];
  y = data[5] << 8 | data[4];

  // This one works OK
  /*x = data[0] << 8 | data[1];
  z = data[2] << 8 | data[3];
  y = data[4] << 8 | data[5];*/

  heading = atan2(y,x);
  declination_angle_YANBU = ((3.0 + (52.0 / 60.0)) / (180 / M_PI));  // in yanbu city it's
  heading += declination_angle_YANBU;

  // Correct for heading < 0deg and heading > 360deg
  if (heading < 0){
    heading += 2 * PI;
  }

  if (heading > 2 * PI){
    heading -= 2 * PI;
  }

  heading_in_degrees = heading * 180 / M_PI;
  Serial.println(heading_in_degrees);
  _delay_ms(20);

}

```
2. The accelerometer ADXL345

```
void ADXL345_print_Serial(void){
  int16_t x,z,y;
  uint8_t data[6];

  ADXL345_read_raw(data);

  // This one gives values from -255 to +255
  x = data[1] << 8 | data[0];
  z = data[3] << 8 | data[2];
  y = data[5] << 8 | data[4];

  // This one give values from -32768 to +32768
  /*x = data[0] << 8 | data[1];
  z = data[2] << 8 | data[3];
  y = data[4] << 8 | data[5];*/
    Serial.print(x);Serial.print("\t");
    Serial.print(y);Serial.print("\t");
    Serial.println(z);
    _delay_ms(100);
}

```

So basically I want to learn how to work with these sensors and also I want to know the principles about each one, because I'm confused between then I feel they are the same and each one provides similar functions; like, tilt sensing.

# Answer
One of the places where the datasheets for the sensors of the GY-85 module can be found is here: https://www.hotmcu.com/gy85-9dof-imu-sensor-module-p-298.html
The following information comes from these datasheets:

Both the HMC5883L and the ADXL345 have internal registers which are numbered consecutively. When reading more than one register they are most efficiently read in the order they are numbered. For each of the three axes both sensors use two 8-bit registers to hold the measured value.

In the HMC5883L the register with the lower number holds the most significant byte (MSB) and the register with the higher number holds the least significant byte (LSB). This means that in a consecutive read the MSB is read first followed bij the LSB. When you combine these two bytes into one 16 bit number (datatype int) you have to shift the MSB-holding byte (the first byte received) 8 places to the left and "OR-in" the LSB-holding byte (the second byte received).
In the ADXL345 the internal numbering is the other way around: the register with the lower number holds the LSB and the register with the higher nummer holds the MSB. When reading, the LSB is red first followed by the MSB. So this time you have to shift the second byte received and "OR-in" the first byte received.

Both sensors give the measured value as a 16-bit 2-complement number, corresponding to datatype int (Arduino Uno). An 16-bit int can hold values from -32,768 to +32,767 but the sensors don't (can't) use this full range:
The ADXL345 has an adjustable range with a maximum of 13 bits (-4096 to +4095).
The HMC5883L has a range of 12 bits (-2048 to +2047).
> 1 votes

---
Tags: sensors, accelerometer, gyroscope, magnetometer
---


# Question
Title: Vary voltage using relay. Is this possible?
I am planning to control a RGB lamp using Arduino. The lamp is 24V and I want to be able to control the brightness of the lamp. I found a relay that will let me control the 3 channels (red green and blue), but will only let me turn it on and off (Not control brightness)

I am looking for a way to control the lamp both on/off and brightness. What component will do the same as my relay, but also let me use the varying voltage from the arduino to control my 24V lamp? (Just like a transistor)

I have an external 24V powersupply along with 5V for the arduino

Thanks!

# Answer
No, you can't vary the voltage with a relay. The only way you could do it with a relay would be to have a selection of different voltages available, and then use multiple relays to select which voltage is used. Less than ideal.

You need to use PWM to create a square wave with varying duty cycle. The duty cycle (the percentage of time the power is on within a given period) defines the average voltage of the output. That PWM needs to be fed into a MOSFET which will in turn control the 24V power to the lamp.

It's exactly the same as driving RGB LED strips, except it's in the shape of a lamp not a long strip.
> 5 votes

# Answer
Yes it is possible to vary voltage with a relay. A relay is simply a 2 way 3 pole switch.

simulate this circuit – Schematic created using CircuitLab

By switching in a resistor to the supply voltage you have lowered the voltage and will dim the 24V light source. The actual resistor value will depend on how dim you want to go. Make sure the resistor is rated for the load you plan to place on it.
> 2 votes

---
Tags: transistor
---


# Question
Title: How to remove the sketch for the LCD and retaining the sketch for the MPU6050?
I just got this from the internet and I only want to use the sketch for the MPU6050. Can someone help me to remove the code for the LCD? I'm sorry, I'm just noob when it comes to programming.

Here is my source: Earthquake Detector using Arduino and MPU-6050

Here is the sketch:

```
#include <LiquidCrystal.h>

#include <Wire.h>

#include <MPU6050.h>

#define minval -5

#define maxval 3

MPU6050 mpu;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()

{   lcd.begin(16, 2);

Serial.begin(115200);

pinMode(7,OUTPUT);

pinMode(8,OUTPUT);

lcd.print("   EarthQuake ");

lcd.setCursor(0, 1);

lcd.print("   Detector");

delay (2000);

lcd.clear();

// Initialize MPU6050

Serial.println("Initialize MPU6050");

while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))

{ Serial.println("Could not find a valid MPU6050 sensor, check wiring!");

delay(500);}

mpu.setThreshold(3);

// Check settings

checkSettings();

}

void checkSettings()

{

Serial.println();

Serial.print(" * Sleep Mode:        ");

Serial.println(mpu.getSleepEnabled() ? "Enabled" : "Disabled");

Serial.print(" * Clock Source:      ");

switch(mpu.getClockSource())

{case MPU6050_CLOCK_KEEP_RESET:     Serial.println("Stops the clock and
keeps the timing generator in reset"); break;

case MPU6050_CLOCK_EXTERNAL_19MHZ: Serial.println("PLL with external
19.2MHz reference"); break;

case MPU6050_CLOCK_EXTERNAL_32KHZ: Serial.println("PLL with external
32.768kHz reference"); break;

case MPU6050_CLOCK_PLL_ZGYRO:      Serial.println("PLL with Z axis
gyroscope reference"); break;

case MPU6050_CLOCK_PLL_YGYRO:      Serial.println("PLL with Y axis
gyroscope reference"); break;

case MPU6050_CLOCK_PLL_XGYRO:      Serial.println("PLL with X axis
gyroscope reference"); break;

case MPU6050_CLOCK_INTERNAL_8MHZ:  Serial.println("Internal 8MHz
oscillator"); break;

}

Serial.print(" * Gyroscope:         ");

switch(mpu.getScale())

{case MPU6050_SCALE_2000DPS:        Serial.println("2000 dps"); break;

case MPU6050_SCALE_1000DPS:        Serial.println("1000 dps"); break;

case MPU6050_SCALE_500DPS:         Serial.println("500 dps"); break;

case MPU6050_SCALE_250DPS:         Serial.println("250 dps"); break:}

Serial.print(" * Gyroscope offsets: ");

Serial.print(mpu.getGyroOffsetX());

Serial.print(" / ");

Serial.print(mpu.getGyroOffsetY());

Serial.print(" / ");

Serial.println(mpu.getGyroOffsetZ());

Serial.println();}

void loop()

{   Vector rawGyro = mpu.readRawGyro();

Vector normGyro = mpu.readNormalizeGyro();

Serial.print(" Xraw = ");

Serial.print(rawGyro.XAxis);

Serial.print(" Yraw = ");

Serial.print(rawGyro.YAxis);

Serial.print(" Zraw = ");

Serial.println(rawGyro.ZAxis);

if(normGyro.XAxis > maxval || normGyro.XAxis < minval && normGyro.YAxis >
maxval || normGyro.YAxis  < minval && normGyro.ZAxis > maxval ||
normGyro.ZAxis  < minval)

{ digitalWrite(7,HIGH);

digitalWrite(8,HIGH);

delay(300);

digitalWrite(7,HIGH);

digitalWrite(8,HIGH);

delay(300);

lcd.clear();

lcd.print("***EarthQuake***");

delay (1000);

lcd.clear();}

else{digitalWrite(7,LOW);

digitalWrite(8,LOW);}

Serial.print(" Xnorm = ");

Serial.print(normGyro.XAxis);

Serial.print(" Ynorm = ");

Serial.print(normGyro.YAxis);

Serial.print(" Znorm = ");

Serial.println(normGyro.ZAxis);

delay(10);}

```

# Answer
> 0 votes
As Majenko states, carefully remove all lines with the `lcd` object in them. Due to the extremely poor formatting and indentation of the code, if you aren't careful you could lose some important syntax, such as the `{` and `}`.

Also, there is no need for the `LiquidCrystal` header file.

In addition, there is a typo in the posted code (it is beyond me why the author would post uncompilable (and hence untested) code), in this line:

```
case MPU6050_SCALE_250DPS:         Serial.println("250 dps"); break:}

```

Here is the code with the `lcd` related lines stripped out, correctly formatted and indented, with the typo fixed:

```
#include <Wire.h>
#include <MPU6050.h>

#define minval -5
#define maxval 3

MPU6050 mpu;

void setup()
{
  Serial.begin(115200);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);

  delay (2000);

  // Initialize MPU6050
  Serial.println("Initialize MPU6050");

  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }

  mpu.setThreshold(3);
  // Check settings
  checkSettings();
}

void checkSettings()
{
  Serial.println();
  Serial.print(" * Sleep Mode:        ");
  Serial.println(mpu.getSleepEnabled() ? "Enabled" : "Disabled");
  Serial.print(" * Clock Source:      ");
  switch(mpu.getClockSource())
  {
    case MPU6050_CLOCK_KEEP_RESET:
      Serial.println("Stops the clock and keeps the timing generator in reset");
      break;
    case MPU6050_CLOCK_EXTERNAL_19MHZ:
      Serial.println("PLL with external 19.2MHz reference");
      break;
    case MPU6050_CLOCK_EXTERNAL_32KHZ:
      Serial.println("PLL with external 32.768kHz reference");
      break;
    case MPU6050_CLOCK_PLL_ZGYRO:
      Serial.println("PLL with Z axis gyroscope reference");
      break;
    case MPU6050_CLOCK_PLL_YGYRO:
      Serial.println("PLL with Y axis gyroscope reference");
      break;
    case MPU6050_CLOCK_PLL_XGYRO:
      Serial.println("PLL with X axis gyroscope reference");
      break;
    case MPU6050_CLOCK_INTERNAL_8MHZ:
      Serial.println("Internal 8MHz oscillator");
      break;
  }

  Serial.print(" * Gyroscope:         ");
  switch(mpu.getScale())
  {
    case MPU6050_SCALE_2000DPS:
      Serial.println("2000 dps");
      break;
    case MPU6050_SCALE_1000DPS:
      Serial.println("1000 dps");
      break;
    case MPU6050_SCALE_500DPS:
       Serial.println("500 dps");
       break;
    case MPU6050_SCALE_250DPS:
       Serial.println("250 dps");
       break;
  }

  Serial.print(" * Gyroscope offsets: ");
  Serial.print(mpu.getGyroOffsetX());
  Serial.print(" / ");
  Serial.print(mpu.getGyroOffsetY());
  Serial.print(" / ");
  Serial.println(mpu.getGyroOffsetZ());
  Serial.println();
}

void loop()
{
  Vector rawGyro = mpu.readRawGyro();
  Vector normGyro = mpu.readNormalizeGyro();
  Serial.print(" Xraw = ");
  Serial.print(rawGyro.XAxis);
  Serial.print(" Yraw = ");
  Serial.print(rawGyro.YAxis);
  Serial.print(" Zraw = ");
  Serial.println(rawGyro.ZAxis);

  if (normGyro.XAxis > maxval ||
      normGyro.XAxis < minval &&
      normGyro.YAxis > maxval ||
      normGyro.YAxis < minval &&
      normGyro.ZAxis > maxval ||
      normGyro.ZAxis < minval)
  {
    digitalWrite(7,HIGH);
    digitalWrite(8,HIGH);
    delay(300);
    digitalWrite(7,HIGH);
    digitalWrite(8,HIGH);
    delay(300);
    delay (1000);
  }
  else
  {
    digitalWrite(7,LOW);
    digitalWrite(8,LOW);
  }
  Serial.print(" Xnorm = ");
  Serial.print(normGyro.XAxis);
  Serial.print(" Ynorm = ");
  Serial.print(normGyro.YAxis);
  Serial.print(" Znorm = ");
  Serial.println(normGyro.ZAxis);
  delay(10);
}

```

The page that you got your code from does not specify which MPU6050 library to use. It is not the library by Jeff Rowberg, as linked to from the Arduino Playground, MPU-6050 Accelerometer + Gyro. It is in fact this library, MPU6050 Triple Axis Gyroscope & Accelerometer Arduino Library.

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


# Question
Title: Faster way to parse a HTTP response in Arduino
I send a GET http request to a server and get following data back.

```
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 16 Nov 2018 16:30:05 GMT
Connection: close

35
{
  "uuid" : "13b29524-7e12-48fb-bbf9-4396aefff45d"
}
0

```

with the following code I get the header info and the body.

```
void parseResponse() {
  boolean headerEnd = false;
  byte lineCount = 0;
  String line;
  char endOfLine[] = "\r\n";
  while (1) {
    if (client.available()) {
      char inChar = client.read();
      if (!headerEnd && line.endsWith(endOfLine)) {
        // Just save the first then headers
        if (lineCount == 10) {
          headerEnd = true;
        } else {
          headers[lineCount] = line;
          line = "";
          lineCount++;
        }
      }

      if (line.endsWith("close")) {
        line = "";
        headerEnd = true;
      }

      if (headerEnd && line.endsWith("}")) {
        line.toCharArray(response, sizeof(response));
        client.stop();
        break;
      }

      line += inChar;
    }
  }
}

```

this thakes 60 - 70ms to parse. Is there a faster way to parse? I think that's slow, for so little text, in the world of AVRs.

# Answer
there are nice functions inherited from Stream class

```
int parseResponse(char uuid[], int size) {
  if (!client.find("HTTP/1.1")) // skip HTTP/1.1
    return -1;
  int st = client.parseInt(); // parse status code
  int l = -1;
  if (st == 200 && client.find("\"uuid\" : \"")) {
    int l = client.readBytesUntil('"', uuid, size);
    uuid[l] = 0; // terminate the C string
  }
  return l;
}

```
> 3 votes

---
Tags: http
---


# Question
Title: Arduino Leonardo keyboard.print keeps printing equal sign
I am currently working on a DIY controller for Train Sim World. I am relatively new to the Arduino and the C programming language. My code is structured to look for button presses or PS2 joystick inputs and print a specific character for each button. I have also included a kill switch on pin 3. However when I run the code and open Notepad to see the results, the Arduino keeps printing the `=` character even if pin 3 is not pulled low. After I pull pin 3 low and press a button, there is a delay of about two seconds during which the `=` character keeps being printed over and over again, and after these 2 seconds elapse the Arduino prints the character attributed to the button several times before returning to printing `=` over and over again.

What can I do to fix this?

```
#include <Keyboard.h>

void setup() {
    pinMode(0, INPUT_PULLUP);
    pinMode(1, INPUT_PULLUP);
    pinMode(2, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);
    pinMode(4, INPUT_PULLUP);
    pinMode(5, INPUT_PULLUP);
    pinMode(6, INPUT_PULLUP);
    pinMode(7, INPUT_PULLUP);
    pinMode(8, INPUT_PULLUP);
    pinMode(9, INPUT_PULLUP);
    pinMode(10, INPUT_PULLUP);
    pinMode(11, INPUT_PULLUP);
    pinMode(12, INPUT_PULLUP);
    pinMode(13, INPUT_PULLUP);
}
bool pantograph = 0;
void loop() {
    while (digitalRead(3) == LOW) {
        Keyboard.write("M");
        if (digitalRead(1) == LOW) {
            Keyboard.write("W");
        } else if (digitalRead(2) == LOW) {
            Keyboard.write("S");
        } else if (digitalRead(0) == LOW) {
            Keyboard.write("Q");
        } else if (digitalRead(5) == LOW) {
            Keyboard.write("Y");
        } else if (digitalRead(6) == LOW) {
            Keyboard.write("T");
        } else if (digitalRead(7) == LOW) {
            Keyboard.write("G");
        } else if (digitalRead(8) == LOW) {
            Keyboard.write("K");
        } else if (digitalRead(9) == LOW) {
            Keyboard.write("Z");
        } else if (digitalRead(10) == LOW) {
            if (pantograph == 0) {
                Keyboard.write("P");
            } else {
                Keyboard.write("O");
            }
        } else if (digitalRead(11) == LOW) {
            Keyboard.write(9);
        } else if (digitalRead(12) == LOW) {
            Keyboard.write("N");
        } else if (digitalRead(13) == LOW) {
            Keyboard.write(32);
        } else if (analogRead(A0) > 700) {
            Keyboard.write(93);
        } else if (analogRead(A0) < 200) {
            Keyboard.write(91);
        } else if (analogRead(A1) > 700) {
            Keyboard.print(39);
        } else if (analogRead(A1) < 200) {
            Keyboard.print(59);
        } else if (analogRead(A2) > 700) {
            Keyboard.print("A");
        } else if (analogRead(A2) < 200) {
            Keyboard.print("D");
        }
    }
    delay(1000);
}

```

# Answer
> 1 votes
The method `write` with one parameter takes char not string. Use `write('W')`, not `write("W");`

---
Tags: keyboard
---


# Question
Title: Connect a button to bluetooth board and comunicate with Android
I want to create a small device, just a button that sends its status to an Android application through Bluetooth.

I bought a Bluno Beetle, but the information it exposes to Bluetooth cannot be modified from Arduino code, so I have no way to send the button status to the Android App, rookie mistake I guess.

Could you please tell me which model of arduino+bluetooth should I purchase to do this ?

# Answer
For your project you can buy cheap Arduino Nano, or even Mini(**programmer needed**). For BT module buy HM10. It's cheap and it supports Bluetooth Low Energy.
> -1 votes

---
Tags: bluetooth, android
---


# Question
Title: ESP8266 UDP multicast doesn't receive packets
I am currently working on an ESP8266 with the Arduino IDE. I try to implement an ESP8266 in STA mode as multicast receiver. I was writing my code with the help of this documentation. Especially the following part:

> The WiFiUDP class supports sending and receiving multicast packets on STA interface. When sending a multicast packet, replace udp.beginPacket(addr, port) with udp.beginPacketMulticast(addr, port, WiFi.localIP()). When listening to multicast packets, replace udp.begin(port) with udp.beginMulticast(WiFi.localIP(), multicast\_ip\_addr, port). You can use udp.destinationIP() to tell whether the packet received was sent to the multicast or unicast address.

Sending to the multicast group with `udp.beginPacketMulticast(addr, port, WiFi.localIP())` and `udp.write(message, messageLength)`works flawlessly.

The receiving part of my code is as follows:

```
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

#define BUFFER_LENGTH 256

const char* ssid = "xxxxxx";
const char* password = "xxxxxx";

WiFiUDP Udp;
IPAddress multicastAddress(226,1,1,1);
unsigned int multicastPort = 4096;

char incomingPacket[BUFFER_LENGTH];

void setup(){
    WiFi.mode(WIFI_STA); //station
    WiFi.setOutputPower(0);
    while (WiFi.status() != WL_CONNECTED)
    {
        WiFi.begin(ssid, password);
        delay(500);
    }
    Udp.beginMulticast(WiFi.localIP(), multicastAddress, multicastPort);
}

void loop(){
    int packetLength = Udp.parsePacket();
    if(packetLength){
        int len = Udp.read(incomingPacket, BUFFER_LENGTH);
        if (len > 0){
            incomingPacket[len] = 0;
            Serial.printf("%s\n", incomingPacket);
        }
    }
}

```

When sending a packet with a simple multicast sender (with matching IP and port), my multicast receiver on my linux laptop receives the packet, but the ESP8266 doesn't.

Maybe some of you have experienced a similar behavior and are able to give me some hints, where I might be wrong.

EDIT: Since the time I asked this question I completely ruled out an error of the sender on the linux machine by using a verified, 100% working sender. The ESP8266 still doesn't receive any multicast datagramms.

# Answer
> 5 votes
I recently had the same problem.

The unequivocal answer is that there is a power optimization (internal by Espressif) to save power, I guess, and it really creates havoc in the UDP Multicast receiving. Why? I have no idea. Same problem with the ESP32 and ESP8266.

Solution:

```
#include "user_interface.h"

```

and after:

```
WiFi.mode(WIFI_STA);
// the below instructions and now u will receive.
wifi_set_sleep_type(NONE_SLEEP_T); //LIGHT_SLEEP_T and MODE_SLEEP_T

```

---
Tags: arduino-ide, esp8266, wifi
---


title: Flashing an ATtiny85 with a NodeMCU?

text:
# Question
Title: Flashing an ATtiny85 with a NodeMCU?
I recently purchased a Digispark for some of my smaller electronics projects. After it initially being a great little board, I soon found myself unable to flash the board in the same way I had done before i.e. according to the method described here. I am still unsure as to why the previous flashing method stopped working but have been unable to overcome the issue, nor have I found many other accounts of similar problems online.

After a period of frustration, unable to even find a way to reset the board, it dawned upon me that I may be able to use an Arduino to flash the board as seen here. However, the issue is that all the tutorials I could find online assumed that an Arduino Uno could be easily accessed, which is not the case for me. Despite this, I do have a few NodeMCUs hanging around and would love it if I could use them to flash the Digispark.

My question is: how exactly would I flash the Digispark using a NodeMCU (if it is even possible)?

P.S. Whilst I am aware that the Digispark board has a number of other components aside from the ATtiny85 chip, the pinouts (not the USB) of the board allow for direct interfacing with the chip.

Thank you in advance for any help,

Kind regards, Rocco

# Answer
> 3 votes
It can be done. Your Digispark has SPI pins, which are ISP pins. For the esp8266 there is an ESP8266AVRISP library for OTA upload to AVR. You can use the example of the library.

You must wire the SPI pins and ground together. Wire reset pin of Digispark to io 5 (D1) of NodeMcu. You should use level conversion, but esp8266 tolerates 5 V TTL (not recommended for long term). Do not wire the SS pin.

---
Tags: nodemcu, flash, attiny85, digispark
---


# Question
Title: How can I get my (Arduino) Pro Micro schematic to allow me to program it through GPIO instead of USB
I'm trying this project so far I've got the schematic of a Pro Micro, which is powered through GPIO from a Raspberry Pi Zero, and want to remove the micro usb connection and able to flash it using an avr programer and a few pins.

How do I get to Achieve that? also the Pro Micro is getting D+/D- from the the raspberry's D+/D- pads as well. Schematic below for reference.

# Answer
Welcome to arduino.stackexchange.
You can program your ATmega32U4 on at least two ways:
1. Use Arduino's bootloader and D+/D- pins. This way you won't need an external programmer. Try search for phase "programming ATmega32U4 with bootloader".
2. Use ISP (In-System-Programming) method. In this case you can use your avr programmer. To do so you also need access to PINs named Reset, MISO, MOSI, SCLK. See this link or this one

As always, the important read is ATMega32U4 datasheet.
> 2 votes

# Answer
Why don't you buy a pi zero to USB add-on board? You can stack the pi on top and plug it into a normal female USB port on your computer.

The USB board has some pins that connect to the solder points of the mini USB, so you can delete all the connectors you won't need.

Other option is to solder a wire to the pi and extend the connector with a cable.

I'm not shire, if you can program the pi true its serial pins. USB is a serial connection after all. So I think this should be possible
> 0 votes

# Answer
An avr programmer uses the ISP interface to program a chip. For this you need the pins for MOSI, MISO, SCK and Reset. Of course you have also to provide power to the board through Vcc and ground.

I'm not sure, if it's OK to keep the USB connection while programming via ISP, but since you want to remove that connection either way, this isn't a problem for you. You can remove the USB connection completely (no D+ or D- connection).

Note: when you are programming the Arduino Micro via ISP without also burning the bootloader, you won't be able to use USB for programming anymore, until you burn the bootloader again.
> 0 votes

---
Tags: power, pins, bootloader
---


# Question
Title: GUI interface with microcontroller to control a device through SPI
I am trying to develop a GUI to control a device hooked up on the Arduino. The Arduino communicates with the device through SPI. I have developed a GUI on MATLAB to visualize read by the Arduino. For this, I made Arduino write data from the MISO line to the serial port and MATLAB would read from the same port and do its magic. However, I am trying to come up with a method to write to the MOSI line using the GUI.

Right now I am thinking of making Arduino listen for a particular code (like a character) on the serial port and once it sees it, it will look for an x number of succeeding bytes. The bytes will be formatted in a particular way so that Arduino can then parse it and write to the appropriate registers.

Is there a better way to do this? As a generic question, what's a good way to write to a device hooked onto a microcontroller using I2C or SPI through a GUI?

# Answer
> 1 votes
I grappled with the same question for a while. Here is how I solved the issue.

**1- Find a suitable exchange format and protocol**

Here you need to decide what is the most important thing on the communication. Is it speed? Is it error detection? Is it memory footprint? For my project, for instance, I decided that I need my communication to be as error free as possible, with minimal memory footprint (up to 64 bytes) and I don't really care about speed, so I gone for a JSON messaging protocol where the desktop application send a short (up to 64 characters) JSON message and receives a short answer. This solved **MY** problem, your requirements might be different. If you need speed and don't care for memory, for instance, you can use a binary protocol with a header specifing size, the message and a CRC footer to check vailidity. Or you can use BSON and take this library to avoid the hassle.

**2- Define the Serial Polling Cycle** How will the arduino firmware knows it is time to send or receive messages? It is always talking? Always ready to receive? It looks at the serial port buffer once each few microsseconds to know if there is an incomming message? How that is handled by your device? If you just need to output data without bothering whether there is someone listening or not, like an GPS device, just throw a `Serial.print` now and then, but if you need to wait for data, you will have to compartimentalize the process inside an FSM or using some kind of scheduler. If you are not using a scheduler, I recommend this one.

**3- Define the Communication Cycle** Here you will take the data from serial port and storing it on a buffer for later usage. The trick here is 1- Check the serial FIFO for incomming data. `Serial.available()` does it already. 2- If there is incomming data, copy the data to next available space in the buffer. 3- Check if there is more incomming data after a few millisseconds. 4- If there is no incomming data, mark the buffer as ready to use, and parse it.

The following code is unscheduled for simplicity,and I recommend you to replace the `sleep()` calls to proper scheduling least you want the arduino go unresponsive. It is also waiting text data, so you will need to make changes if you are waiting binary data.

```
  char buffer[64];
  memset(buffer, 0, 64);

  while (!Serial.available())
    delay(50);

  while (Serial.available()){
    Serial.readBytes(buffer + strlen(buffer), Serial.available());
    delay(50);
  }
  parseBuffer(buffer);

```

# Answer
> 0 votes
SPI is a synchronized interface, it has master and slave. Either you need to switch between slave and master, or you need to provide a way to let Arduino start "reading" from the other end, since the one who initiates the communication in SPI or I2C is a master, in your case, Arduino, I suppose. The simplest way to do this is to provide another line via gpio. As for generic question, to do two-way communication properly, you probably want to choose asynchronous protocol like UART.

# Answer
> 0 votes
I had a similar requirement and came up with Wirekite. It is a complete solution based on a Teensy board, some code for it plus libraries for Mac or PC.

With Wirekite, you can hook up digital and analog inputs and outputs, I2C devices and SPI devices (very soon) to the Teensy board and connect the Teensy board via USB to your Mac or PC. You can then control the I/Os, I2C and SPI buses from you Mac or PC. You don't need to adapt the code on the Teensy.

Wirekite uses a custom protocol for the communication. But you don't need to care about that because you can simply use the far more convenient API provided by the Wirekite libraries (.NET for Windows, Objective-C/Swift for MacOS).

# Answer
> 0 votes
If you want to communicate from the computer to the arduino, use USART. Arduino already has this pre-programmed, as well it's own GUI.

---
Tags: matlab
---


# Question
Title: How to convert string to byte array on arduino
Well my title pretty much sums it up , how to convert string to byte array? i cant find any usefull code

# Answer
> 0 votes
Well, the C string is already byte array.

If you mean Arduino's `String` class, then it has `c_str()` method.

Both needs reinterpret cast to const byte pointer:

```
byte const* byteArray = reinterpret_cast<byte const*>(yourString.c_str());

```

---
Tags: arduino-uno
---


# Question
Title: I can't make more than one arduino gas sensor work at the same time
I'm doing a school project in which I need to track different kinds of gases, the problem is I can't read more than one sensor at the same time, I'm using four sensors (mq5, mq7, mq8 and mq135) and the code I'm using was one that I merged using four different codes that I found on github (https://github.com/mdsiraj1992/Gassensors). When I'm only one sensor it works normally, but when I use the code I merged the values are totally off. So basically I'm doing something wrong, but I don't know what. Please help me, I have to deliver the code this week.

```
#include <Adafruit_Sensor.h>

#include <Adafruit_Sensor.h>

#include <DHT.h>
#include <DHT_U.h>

#include <DHT.h>
#include <DHT_U.h>

/***Hardware Related Macros***/

#define         MQ5PIN                       (2)
#define         RL_VALUE_MQ5                 (1)
#define         RO_CLEAN_AIR_FACTOR_MQ5      (6.455)

#define         MQ7PIN                       (3)
#define         RL_VALUE_MQ7                 (1)
#define         RO_CLEAN_AIR_FACTOR_MQ7      (26.09)

#define         MQ8PIN                       (1)
#define         RL_VALUE_MQ8                 (1)
#define         RO_CLEAN_AIR_FACTOR_MQ8      (1)

#define         MQ135PIN                     (5)
#define         RL_VALUE_MQ135               (1)
#define         RO_CLEAN_AIR_FACTOR_MQ135    (3.59)

/***Software Related Macros***/

#define         CALIBARAION_SAMPLE_TIMES     (50)
#define         CALIBRATION_SAMPLE_INTERVAL  (500)
#define         READ_SAMPLE_INTERVAL         (50)
#define         READ_SAMPLE_TIMES            (5)

/***Application Related Macros***/

#define         GAS_LPG                      (1)
#define         accuracy                     (0)
#define         GAS_CARBON_MONOXIDE          (3)
#define         GAS_HYDROGEN                 (0)
#define         GAS_METHANE                  (2)
#define         GAS_CARBON_DIOXIDE           (9)
#define         GAS_AMMONIUM                 (10)

/***Globals***/
float           Ro = 10;

void setup() {
  Serial.begin(9600);
  Serial.print("Calibrating...\n");

  Ro = MQCalibration(MQ5PIN);
  Serial.print("Calibration is done...\n");
  Serial.print("Ro5=");
  Serial.print(Ro);
  Serial.print("kohm");
  Serial.print("\n");

  Ro = MQCalibration(MQ7PIN);
  Serial.print("Calibration is done...\n");
  Serial.print("Ro7=");
  Serial.print(Ro);
  Serial.print("kohm");
  Serial.print("\n");

  Ro = MQCalibration(MQ8PIN);
  Serial.print("Calibration is done...\n");
  Serial.print("Ro8=");
  Serial.print(Ro);
  Serial.print("kohm");
  Serial.print("\n");

  Ro = MQCalibration(MQ135PIN);
  Serial.print("Calibration is done...\n");
  Serial.print("Ro135=");
  Serial.print(Ro);
  Serial.print("kohm");
  Serial.print("\n");
}

void loop() {

  Serial.print("METHANE:");
  Serial.print(MQGetGasPercentage(MQRead(MQ8PIN) / Ro, GAS_METHANE) );
  Serial.print( "ppm" );
  Serial.print("    ");
  Serial.print("HYDROGEN:");
  Serial.print(MQGetGasPercentage(MQRead(MQ8PIN) / Ro, GAS_HYDROGEN) );
  Serial.print( "ppm" );
  Serial.print("    ");
  Serial.print("GLP:");
  Serial.print(MQGetGasPercentage(MQRead(MQ5PIN) / Ro, GAS_LPG) );
  Serial.print( "ppm" );
  Serial.print("    ");
  Serial.print("CARBON_MONOXIDE:");
  Serial.print(MQGetGasPercentage(MQRead(MQ7PIN) / Ro, GAS_CARBON_MONOXIDE)
              );

  Serial.print( "ppm" );
  Serial.print("    ");
  Serial.print("CARBON_DIOXIDE:");
  Serial.print(MQGetGasPercentage(MQRead(MQ135PIN) / Ro, GAS_CARBON_DIOXIDE)
              );
  Serial.print( "ppm" );
  Serial.print("    ");
  Serial.print("AMMONIUM:");
  Serial.print(MQGetGasPercentage(MQRead(MQ135PIN) / Ro, GAS_AMMONIUM) );
  Serial.print( "ppm" );
  Serial.print("\n");
  delay(200);
}

/***MQResistanceCalculation*****************************************
  Input:   raw_adc - raw value read from adc, which represents the
  voltage
  Output:  the calculated sensor resistance
  Remarks: The sensor and the load resistor forms a voltage divider.
  Given the voltage
  across the load resistor and its resistance, the resistance of the
  sensor
  could be derived.

*******************************************************************/
float MQResistanceCalculation(int raw_adc)
{
  return ( ((float)RL_VALUE_MQ5 * (1023 - raw_adc) / raw_adc));
  return ( ((float)RL_VALUE_MQ7 * (1023 - raw_adc) / raw_adc));
  return ( ((float)RL_VALUE_MQ8 * (1023 - raw_adc) / raw_adc));
  return ( ((float)RL_VALUE_MQ135 * (1023 - raw_adc) / raw_adc));
}

/*** MQCalibration*******************************************************
  Input:   mq_pin - analog channel
  Output:  Ro of the sensor
  Remarks: This function assumes that the sensor is in clean air. It use
  MQResistanceCalculation to calculates the sensor resistance in clean
  air
  and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is
  about
  10, which differs slightly between different sensors.
****************************************************************/
float MQCalibration(int mq_pin)
{
  int i;
  float RS_AIR_val = 0, r0;

  for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
    RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
    delay(CALIBRATION_SAMPLE_INTERVAL);
  }
  RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
  r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ5;

  return r0;

  for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
    RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
    delay(CALIBRATION_SAMPLE_INTERVAL);
  }
  RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
  r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ7;

  return r0;

  for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
    RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
    delay(CALIBRATION_SAMPLE_INTERVAL);
  }
  RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
  r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ8;

  return r0;

  for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
    RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
    delay(CALIBRATION_SAMPLE_INTERVAL);
  }
  RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
  r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ135;

  return r0;
}
/*****************  MQRead *********************************
  Input:   mq_pin - analog channel
  Output:  Rs of the sensor
  Remarks: This function use MQResistanceCalculation to caculate the
  sensor resistenc (Rs).
  The Rs changes as the sensor is in the different consentration of the
  target
  gas. The sample times and the time interval between samples could be
  configured
  by changing the definition of the macros.
********************************************************/
float MQRead(int mq_pin)
{
  int i;
  float rs = 0;

  for (i = 0; i < READ_SAMPLE_TIMES; i++) {
    rs += MQResistanceCalculation(analogRead(mq_pin));
    delay(READ_SAMPLE_INTERVAL);
  }

  rs = rs / READ_SAMPLE_TIMES;

  return rs;
}

/***********************  MQGetGasPercentage ****************************
  Input:   rs_ro_ratio - Rs divided by Ro
  gas_id      - target gas type
  Output:  ppm of the target gas
  Remarks: This function uses different equations representing curves of
  each gas to
  calculate the ppm (parts per million) of the target gas.
******************************************************************/
int MQGetGasPercentage(float rs_ro_ratio, int gas_id)
{
  if ( accuracy == 0 ) {

  }
  if ( gas_id == GAS_LPG ) {
    return (pow(10, ((-2.513 * (log10(rs_ro_ratio))) + 1.878)));
  }
  else if ( gas_id == GAS_CARBON_MONOXIDE ) {
    return (pow(10, ((-1.525 * (log10(rs_ro_ratio))) + 1.994)));
  }
  else if ( gas_id == GAS_HYDROGEN ) {
    return (pow(10, ((-2.568 * (log10(rs_ro_ratio))) + 0.360)));
  }
  else if ( gas_id == GAS_METHANE ) {
    return (pow(10, ((-16.16 * (log10(rs_ro_ratio))) + 1.093)));
  }
  else if ( gas_id == GAS_CARBON_DIOXIDE ) {
    return (pow(10, ((-2.890 * (log10(rs_ro_ratio))) + 2.055)));
  }
  else if ( gas_id == GAS_AMMONIUM ) {
    return (pow(10, ((-2.469 * (log10(rs_ro_ratio))) + 2.005)));

  }
  else if ( accuracy == 1 ) {
  }
  else if ( gas_id == GAS_LPG ) {
    return (pow(10, ((-2.513 * (log10(rs_ro_ratio))) + 1.878)));
  }
  else if ( gas_id == GAS_CARBON_MONOXIDE ) {
    return (pow(10, ((-1.525 * (log10(rs_ro_ratio))) + 1.994)));
  }
  else if ( gas_id == GAS_HYDROGEN ) {
    return (pow(10, ((-2.568 * (log10(rs_ro_ratio))) + 0.360)));
  }
  else if ( gas_id == GAS_METHANE ) {
    return (pow(10, (-281.3 * pow((log10(rs_ro_ratio)), 3) - 12.26 *
                     pow((log10(rs_ro_ratio)), 2) - 7.925 * (log10(rs_ro_ratio)) + 1.668)));
  }
  else if ( gas_id == GAS_CARBON_DIOXIDE ) {
    return (pow(10, ((-2.890 * (log10(rs_ro_ratio))) + 2.055)));
  }
  else if ( gas_id == GAS_AMMONIUM ) {
    return (pow(10, ((-2.469 * (log10(rs_ro_ratio))) + 2.005)));
  }
}

```

# Answer
> 1 votes
First of all you only need to include once. Including anything more than once is pointless and could be bad, if the header doesn't have include guards (yours do, but still it just makes the code harder to read).

Let's take a look at the `MQResistanceCalculation` function, well... It's simply broken.

```
float MQResistanceCalculation(int raw_adc)
{
  return ( ((float)RL_VALUE_MQ5 * (1023 - raw_adc) / raw_adc));
  return ( ((float)RL_VALUE_MQ7 * (1023 - raw_adc) / raw_adc));
  return ( ((float)RL_VALUE_MQ8 * (1023 - raw_adc) / raw_adc));
  return ( ((float)RL_VALUE_MQ135 * (1023 - raw_adc) / raw_adc));
}

```

I'm not sure what you expect to happen, but as soon as you reach a return statement that block of code stops and the result is returned, so basically that function executes the first return and then stops. You probably want to pass a sensor type and then use a switch to make it return for either the MQ5, MQ7, MQ8 or MQ135, because right now it only returns the MQ5 value.

Then let's take a look at the `MQCalibration` function. So same thing as above applies, as long as you reach a return the function stops. Your `MQCalibration` function currently only does:

```
float MQCalibration(int mq_pin)
{
  int i;
  float RS_AIR_val = 0, r0;

  for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
    RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
    delay(CALIBRATION_SAMPLE_INTERVAL);
  }
  RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
  r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ5;

  return r0;
}

```

And then the `MQGetGasPercentage` function can be re-written with switch statements to be way easier to read and understand. Oh and also that `accuracy == 0` check is also pointless it has nothing in it.

From reading this I see you've just copied code you don't understand and hoped it'll work, but as expected it didn't. And well copying code without atleast having an idea about what it does is stupid. So just read it, understand it and write it again, but by yourself. Your code has many pointless variable declarations and it just isn't well "written"(or copy-pasted should I say).

Also I've never worked with that sensor myself, so I was looking at the code aspect mostly, just so you know.

---
Tags: sensors, arduino-nano
---


title: MAX6675 gives a climbing reading

text:
# Question
Title: MAX6675 gives a climbing reading
I am using a MAX6675 board and a k-type thermal couple to measure temp. The problem is even when running the example the temp value keeps climbing.

```
MAX6675 test
27.25
C = 27.25
F = 130.10
109.00
C = 218.00
F = 816.80
872.00
C = 1744.00
F = 2624.00
832.00
C = nan
F = nan
512.75
C = nan
F = nan

```

I am using the `max6675.h` library. Is there a way to fix this?

```
#include "max6675.h"

int thermoDO = 4;
int thermoCS = 5;
int thermoCLK = 6;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
int vccPin = 3;
int gndPin = 2;

void setup() {
  Serial.begin(9600);
  // use Arduino pins
  pinMode(vccPin, OUTPUT); digitalWrite(vccPin, HIGH);
  pinMode(gndPin, OUTPUT); digitalWrite(gndPin, LOW);

  Serial.println("MAX6675 test");
  // wait for MAX chip to stabilize
  delay(500);
}

void loop() {
  // basic readout test, just print the current temp

   Serial.print("C = ");
   Serial.println(thermocouple.readCelsius());
   Serial.print("F = ");
   Serial.println(thermocouple.readFahrenheit());

   delay(1000);
}

```

edit: Added code (https://github.com/adafruit/MAX6675-library/blob/master/examples/serialthermocouple/serialthermocouple.pde)

# Answer
After test some other K-type thermal couples on this I am now thinking I just got a bad board. I was able to order a new one and it worked without issue
> 1 votes

---
Tags: sensors, library
---


title: Getting better results from DHT22

text:
# Question
Title: Getting better results from DHT22
I am working on a dew point sensor, and I am using the Arduino Uno board with the DHT22 sensor. I have it taking a reading once ever 2 seconds and I am using the DHT.h library. The problem I am having is when I compare the values to our standard here the Humidity reads high and the Temp reads low. Is there anyway to get the values to read closer to what the standard is?

# Answer
Using a RH and Temp Calibrator I had access to I was able to get better results by all lines to adjust the RH and Temp to a better value. Basically a correction equation.
> 0 votes

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


title: Optocoupler on Tinkercad acting weird

text:
# Question
Title: Optocoupler on Tinkercad acting weird
So, maybe it's my understanding that is at fault or maybe it's tinkercad. It's probably the former. But anyway here's my problem

I've connected it according to picture

https://i.stack.imgur.com/SJ88F.jpg

There is no power going through the anode. The cathode is going to ground. On the upper side 5v is going to base and the emitter sends signals to an input on pin 12.

If i digitalRead pin 12 and Serial.write it. it says 1. which is weird, least for my understanding.

As i understood there needs to be power going through the anode which lights up the diode inside the optocoupler. however there is no power going through the anode yet the emitter gives off a signal.

Anyone mind helping me out in understanding why this is?

Please ignore the resistors on the image

# Answer
> 0 votes
You connected 5V to the base of the transistor inside, so the transistor is turned on all the time.

Move the 5v pin one to the right (middle pin on the 4N35, i.e. the collector), and it should work.

---
Tags: arduino-uno, serial, c
---


# Question
Title: Reading analog value while generating PWM signal
I'm trying to generate dim two LED strips simultaneously by generating two PWM signals based on potentionmeter value. The pot sets how bright each of the LED strips will be. To drive this I'm using Arduino Pro Micro equipped with Atmel 32u4 chip.

I'm using following code:

```
int sensorValue = 0;
int outputValue = 0;

void setup() {
}

void loop() {
  sensorValue = analogRead(A0);

  outputValue = map(sensorValue, 0, 1023, 0, 255);
  analogWrite(5, outputValue);
  analogWrite(6, 255 - outputValue);

  delay(2);
}

```

The problem is, the `analogRead` never returns 1023 when the pot is fully open. The value is always around 980. This itself would not be a big deal.

The main issue is that the `analogRead` is incredibly noisy. The value returned for the maximum position is in range of \[940-1020\].

When I don't use the `analogWrite` to generate PWM, the problem goes away an the input is crystal clear in range \[0-1023\] as expected.

I have tried to turn off the PWM before reading the value in, but this generates flicker, as the LEDs are temporarily off.

Is there any HW or SW solution to this? I don't mind writing some assembly if required.

# Answer
It was an issue with the power source. It's an USB led strip, so I was powering it through Arduino, which was a bad idea as it turns out.

When I have added external power source to the circuit everything started working correctly.
> 1 votes

---
Tags: led, pwm, analogread, arduino-pro-micro, analogwrite
---


title: Can't drive servo

text:
# Question
Title: Can't drive servo
I purchased a 20KG Digital Servo, DS3218MG with a Control Angle of 270°.

I am trying to get it to rotate with the following code:

```
#include <Servo.h>

Servo myservo;  // create servo object to control a servo

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

int restingVal = 0;
int keyDown = 80;

void loop() {
  int minutesDelay = 1;
  Serial.print("Value");
  Serial.println(restingVal);

  delay(10000/2);

  myservo.write(keyDown);
  delay(500);
  myservo.write(restingVal);

}

```

It makes a small "clicking" noise, but it never moves. I have tried:

* powering it from the arduino using a USB cable
* powering it using a power cord plugged into an electrical outlet
* powering it with 4 AA batteries in a battery pack (power from the battery pack to the servo with it's ground to the Arduino's ground and the arduino plugged into an outlet)
* using a 470uF capacitor and then tried a 680uF capacitor.

What am I doing wrong? Is there something else I could look at?

**update:** changed code to:

```
#include <Servo.h>

Servo myservo;  // create servo object to control a servo

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo.write(60);
  delay(2000);
  myservo.write(120);
}

int restingVal = 0;
int keyDown = 80;

void loop() {

}

```

I get the same problem.

The power cord I'm using to connect the arduino is 12V DC 1A.

Here is a photo of the wiring in one configuration (with the battery pack and the wall outlet):

Orange wire goes to GND on arduino, the long green goes to ~9, yellow goes to VCC on battery pack.

# Answer
> 3 votes
The DS3218MG servo motor is a strong servo motor and it requires more current than normal servo motors.

With a normal servo motor the peak current can be 500 mA or even 1 A. This DS3218MG is specified somewhere at 1.8 A stall current (only 80 to 100 mA during normal operation). However this YouTube video measures a stall current of 2.3 A.

During normal operation, the average current will not even be near the stall current. The peak current on the other hand can be close to the stall current. The peak current occurs at the moment that the servo motors starts to move.

You need a 5 V 2.5 A power supply for that servo motor, together with wires and connectors that are suitable for that current.
You could cheat a little by adding a capacitor. I suggest 2200 µF or 4700 µF.

It is a common mistake to underestimate the current of a servo motor. A power supply is often more expensive than the servo motor.
If a lot of torque is required, perhaps a geared motor is easier to use.

# Answer
> 2 votes
My guess is that the servo is drawing too much current from the Arduino 5v pin which can provide up to ~450mA when powered from USB and ~650mA from power jack.

Try providing 5v from an other source to the servo while keeping the GND of that power source and the Arduino common.

---
Tags: servo
---


title: Arduino LCD Brightness

text:
# Question
Title: Arduino LCD Brightness
I've made this small device that uses a ultrasonic sensor to tell how far away an object is and display it on a 16x2 display.

Here's the code:

```
#include <LiquidCrystal.h>

int Contrast=100;
 LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int trigPin = 7;
const int echoPin = 8;
// defining variables
long duration;
int distance;
void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(9600); // Starts the serial communication
  analogWrite(6, Contrast);

  lcd.begin(16, 2);
  lcd.clear();
}
void loop() {

// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance = duration / 29 / 2;
// Prints the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.println(distance);
  lcd.setCursor(0, 0);
  lcd.print("Distance: ");

 lcd.setCursor(0, 1);
  lcd.print(distance);
  delay(100);
  lcd.clear();
}

```

Every thing works fine apart from the fact that the lcd backlight is too dim(barely visible). I tried looking online but is there any way i can get max brightness without a potentiometer? I do have resistors , can i use them somehow?

# Answer
> 1 votes
The back light of the LCD is just an LED connected through a resistors on the A (15) and K (16) pins on the display. The LED doesn't require an external resistor since according to the datasheet there is a build in resistor on the board itself. If you aren't using any external resistors and applying a constant voltage of 5V and the screen is still dim than this means that the led is most likely dead and you would need to replace the back light panel.

If you are talking about the contrasts of the display. Than I would recommend you to hook up the contrast pin to a PWM pin on the Arduino and by using `analogWite` to tune the display in order to get the desired value of contrast.

---
Tags: lcd
---


# Question
Title: How would I go about powering addressable RGB LED light strip? [Arduino Nano]
The addressable RGB LED I have is WS2812B. I plan on controlling the LEDs via an Arduino nano. I have a total of 188 LEDs to supply power to.

Would I require anything between the addressable RGB LED strip and the 12v power supply?

Would I require a 1000uF capacitor?

# Answer
> Would I require anything between the addressable RGB LED strip and the 12v power supply?

A suitable 5V regulator (assuming 5V LED strip)

> Would I require a 1000uF capacitor?

For what? A suitable 5V regulator won't need one. An unsuitable one would be improved by it, but still be unsuitable.
> 0 votes

---
Tags: arduino-nano, power, rgb-led, capacitors
---


title: What is 1.8 to 5.5 VDC?

text:
# Question
Title: What is 1.8 to 5.5 VDC?
I'd like to buy a standalone capacitive touch sensor to create interactive art. It says it is powered by 1.8 to 5.5 VDC. I am new to arduinos - what type of battery can I buy to power this sensor? I'm hoping it's simple, not complicated. Thanks!

# Answer
VDC is an abbreviation for volts DC. DC means Direct Current you can read more a detailed explanation about it here. Basically what `powered by 1.8 to 5.5 VDC` means is that the DC voltage on the input of your sensor can vary from 1.8 volts up to 5.5 volts. So you can use either 3 AAA batteries in series since the sum of their voltage will be: `1.5V * 3 = 4.5V` what is in the range of recommended voltages for your sensor. Also, you can use a Li-ion battery in order to power your sensor since the voltage of this type of battery is 3.7V it is also in the range of recommended voltages for your sensor. However you would need an additional charge/discharge module in order to recharge and keep the battery in a good condition. You can read more about it on the web.
> 2 votes

# Answer
do you have a 5V power supply? If you do I'd suggest connecting your arduino to the power supply and then you can power your sensor with a pin of the arduino.
> 0 votes

---
Tags: battery
---


# Question
Title: ESP8266 ASCII to HEX convertion and checking
I am trying to convert ASCII to hex and check if the hex is equal to that hex that I want.

For example:

`1B 42 05` it means `B` in ASCII, I need to check if that hex is equal to `1B 42 05`.

Here I need to send converted hex code from ASCII code by using `SoftwareSerial`.

Example:

```
02 20 2D 33 30 32 35 30 20 6B 67 0D 0A 03

```

I have to convert to

```
-30250 kg

```

# Answer
> 3 votes
A little explanation about HEX and ASCII:

About HEX
Raw computer data consists of zeros and ones. For humans it is difficult to read a (long) row of zeros and ones. You can represent such a row (of a certain length) by a decimal number, but then the relation with the underlying bits is not directly clear. For this reason the hexadecimal (HEX) representation is used (hexadeca comes from Greek and means 16.
Four bits can represent 16 different situations (= 16 different combinations of zeros and ones). The HEX digit belonging to each combination is:
0000 = 0; 0001 = 1; 0010 = 2; 0011 = 3; 0100 = 4; 0101 = 5; 0110 = 6; 0111 = 7
1000 = 8; 1001 = 9; 1010 = A; 1011 = B; 1100 = C; 1101 = D; 1110 = E; 1111 = F
When you memorize these 16 cases (from which the first 10 are easy because it is juist binary counting), you know immediately which bit-pattern belongs to a hexadecimal number and vice versa. For example: the HEX value 5A = 01011010.

About ASCII
Computer data contain not only numbers, but also text. As the computer can only handle bits (zeros and/or ones) we have to decide how letters (characters) are presented by bit patterns. And preferably in a standardized way, in order that different computers can handle each others text. Unfortunately there is more than one standard, but one that is very much used is the ASCII standard (see: https://en.wikipedia.org/wiki/ASCII).
The ASCII standard uses 7 bits codes and defines not only characters but also 'control codes' e.g. for 'line feed' and 'carriage return'. Often these 7 bits are stored in one byte (with the leftmost 8th bit set to 0) and can than be represented by two HEX digits.

Without further information nobody can tell what a row of bits represents. That's one of the reasons datatypes are used. They tell us what the row of bits represents and how many bits (or bytes) are used for the representation.

So the HEX representation of your row of 3 bytes is "1B 42 05" and, when these are characters, could stand for (look at the ASCII table): "ESCAPE B ENQ". In which 'ESCAPE' and 'ENQ' are control codes which meaning depends on the communication protocol. The second row (of 14 bytes) could stand for: "STX SPACE - 3 0 2 5 0 SPACE k g CR LF ETX". STX and ETX stand for 'START OF TEXT' and 'END OF TEXT'. 'LF' stands for 'LINE FEED' and 'CR'stands for 'CARRIAGE RETURN'.

I hope that with this explanation you have a better idea about HEX and ASCII and that you now will be able to figure out how to handle your data.

# Answer
> 0 votes
Converting an ASCII HEX digit is simple enough. Here's a little function I use all the time:

```
uint8_t h2d(char hex) {
    if(hex > 0x39) hex -= 7; // adjust for hex letters upper or lower case
    return(hex & 0xf);
}

```

Pass it a single HEX digit as a `char` variable and it returns a number between 0 and 15.

To convert a pair of characters into an 8-bit value just call it twice with each character, shift one of them 4 bits to the left, and OR them together. For instance:

```
uint8_t h2d2(char h1, char h2) {
    return (h2d(h1)<<4) | h2d(h2);
}

```

That would give you a number between 0 and 255 (or 016 and FF16, or 08 and 3778...)

How you receive and split up the incoming data properly is a whole other topic, but this and this could probably help you.

---
Tags: esp8266, softwareserial
---