# Question
Title: Integrating an analog signal using Arduino Mega 2560
The sample code is this:

Sample code for Edgar Bonet

I have questions. I need to integrate the analog sine wave of 60 Hz, this signal described in the next picture, adding an offset near 2.5 V, because I can damage the Arduino board with the negative signal cycle. Internally on the Arduino board, I remove this offset, multiplying by 2, and subtracting 1.

```
V1=analogRead(A0)*2/1023.0-1.0;

```

The sampling period must be at least fs=300 Hz, T=1/fs and V1 is the signal I need integrate.

What modifications can I make to Edgar Bonet's code?

# Answer
> `V1=analogRead(A0)*2/1023.0-1.0;`

This will give you the voltage across R1 in units of 2.5 V. I do not know whether you care or not about the units but, if you want the voltage in volts, then:

* the voltage at the Arduino input is `analogRead(A0) * (5.0/1024)`
* to get the voltage across R1, you have to subtract 2.5 V
* to get the voltage at the output of the transformer, you have to multiply by 11.

This could be written as

```
float V = (analogRead(A0) * (5.0/1024) - 2.5) * 11;

```

but, in order to minimize the number of floating point operations, you can simplify it to

```
float V = analogRead(A0) * (55.0/1024) - 27.5;

```

You could then integrate the voltage by running it through a function like this:

```
static float integral(float x)
{
    static float y;                         // last filter output
    static uint32_t last_sample;            // last time sampled
    uint32_t now = micros();
    float dt = (now - last_sample) * 1e-6;  // step time in seconds
    last_sample = now;
    y += x * dt;
    return y;
}

```

Now, there is an issue with this approach: the average voltage at the input of the Arduino is not going to be exactly 2.5 V, because your resistors R3 and R4 will not have identical resistance. Then the output of the integral will slowly drift and eventually become unreasonably large.

One way to mitigate this drift problem is to measure this average using the same Arduino running the same program: disconnect the mains, see how the output of the program drifts, and measure the drift rate. Then you subtract the drift rate from the `27.5` in the code, and fine tune until there is no drift at all. There is, however, the risk that some time later it will drift again, due to components changing behavior as the temperature changes.

A better option would probably be to *not* integrate, but instead use a first-order low-pass filter. Such a filter behaves like an integrator for any signal faster than its cutoff frequency but, unlike a simple integrator, it has a finite gain at zero frequency. You can turn the integrator into a low-pass filter simply by changing the line `y += x * dt;` into

```
y += (x - y/tau) * dt;

```

where `tau` is the time constant of the filter.
> 1 votes

# Answer
**Brief Electrical Comment First**

The circuit as depicted seems sound, but it may be wise to measure the max and min peaks with an oscilloscope or multi-meter to ensure you are within the voltage range of the Atmel chip on the Mega 2560, which is zero Volts to Vcc \[1\] per Atmel processor's spec sheet \[1\].

Since Vcc is 5V per the Mega's schematic \[2\], the safe range you depicted is correct, however you cannot trust the voltage on the mains to stay within IEEE specifications, the p-p secondary Voltage of the adapter to be dead on in proportional relation to the primary, or the resistors to be in the center of their 5% or 10% range of precision. You may wish to add some potentiometers to your circuit to make adjustments.

**Now the Math and Software Implementation**

Continue to take the i,t (integer, time) sample vector as in the example you referenced. I changed the variable names to be more descriptive from a systems engineering point of view.

```
int s_in = analogRead(input_pin);
unsigned long microsecs = micros();

```

The algebraic (not code) relation of the sample to the instantaneous voltage is as follows.

> v\_in = 5V X s\_in / 1024
>
> v\_no\_offset = v\_in - v\_offsreallyreallyet
>
> v\_offset = 2.5
>
> v\_secondary = v\_no\_offset X (110 KOhms / 10KOhms)

Keep in mind here that the sample is not a p-p measurement. It is an integer representing a Voltage measurement over a very small time range relative to the period of an approximate \[3\] 60 Hertz sine wave. There is no reason to multiply samples or corresponding Voltages by two for this circuit.

The period of a 60 Hertz sine wave is 16,667 usec, so the difference between your max value and min value for any given 16,667 usec period's worth of samples is your p-p Voltage for that period. You can average those over time to get a less instantaneous p-p Voltage. Before considering p-p or RMS calculations, you must first computing the secondary Voltage corresponding to the integer sample acquired in the analogRead.

Substitution and calculation in mV instead of Volts yields this.

```
mv_secondary = (5000 X s_in / 1024 - 2500) X (110000 / 10000)

```

Translating into C, which will be interpreted correctly within an Ino sketch, and using a simplified expression and long integers to achieve reasonable computational speed and accuracy \[4\] you get this.

```
int s_in = analogRead(input_pin);
unsigned long microsecs = micros();
unsigned long mv_secondary = 53711L * s_in / 1000 - 27500;

```

The v,t (secondary Voltage, time) vector is now in the variables mv\_secondary and microsecs respectively. Then calculate the delta time and find the product to sum.

```
unsigned long nano_volt_second = mv_secondary * u_sec_delta;

```

**System Design Considerations**

In designing the system, it is often better to delegate the conversion to physical units and the Gaussian approximation of an integral to another part of the system (as in the case of when the embedded program is doing data acquisition but not control) or not do it at all (as in the case when control is in the same board as the data acquisition and the PID parameters superseded the need to translate the integers from readAnalog to physical units altogether).

To achieve the higher loop speed when using USB transfer of the values, one can USB transfer the return values of the analogRead more directly as two byte pairs and perform calculations on the USB peer computer (workstation or other computing hardware). Conversion of integers of any type to strings slows a data acquisition loop down considerably, and should be avoided.

Hardware triggering of the ADC subsystem of the Atmel chip can also increase speed, especially if the analogRead function is bypassed by a lower level implementation of the register reading. At sampling speeds above 200KHz, completely within the capability of the Arduino Due, every usec counts.

**Ambiguous Intent Reference to Integration**

The summing of products isn't actually integration, which is a symbolic operation, not a calculation. The example reference given does a Gaussian discrete approximation of an integral. The reason for seeking that approximation is not given.

The result of such a calculation would be the product of the time over which the approximation is made and the offset, which would naturally be zero except for any calibration error and low frequency noise in the secondary winding's circuit.

If the intention is to calculate Voltage RMS, there is another real time methodology for that. If you want the average p-p Voltage, there's another (partly described above) for that. If you want to track spikes on the line, then you probably want a circuit with over-Voltage protection and a different algorithm.

**Usefulness of Optimized Math**

The use of unsigned long for optimization may not be necessary for low frequency applications \[5\], but any system that needs to meet the Nyquist criterion for audio will require a sample rate where the fixed point simulation may cause a statistically significant number of delays over the time of sampling.

Even if the speed is not needed, exceeding the Niquest criteria permits gaining extra bits of accuracy if windowing is used during data reduction.

**References**

\[1\] Atmel 2560 cpu spec sheet @ http://www.atmel.com/Images/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561\_datasheet.pdf

\[2\] Mega 2560 schematic @ https://www.arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf

\[3\] A Voltage waveform from a power grid is rarely if ever a perfect sine wave.

\[4\] Arduino use of long integer constants as in C/C++ discussion @ https://www.arduino.cc/en/Reference/IntegerConstants

\[5\] The maximum Δt before the unsigned long product overflows is given by \`floor ((2^32 - 1) / (53,711 x 1023 / 1000 - 27,500)) = 156,485 usec, corresponding to a 6.39 Hz sample rate.
> 1 votes

# Answer
The signal will saturate.

You should increase the attenuation if you want to be able to add the full cycle. Or add half cycle and make assumptions about the other half.

As to the code you simply needs to convert the ADC readings to a DC reading and subtract the center offset from it . Much better to do that in the ADC reading domain. Like this

Y = analogread(AIN) - 2.5 * 1023 / Vref;
> -1 votes

---
Tags: arduino-mega
---


# Question
Title: ESP8266 + NeoPixel - Cannot set pixel color, I got "Exception 29: StoreProhibited"
I'm trying to use NeoPixel on the ESP8266. I made simple test put all required code into `setup()` and `loop()` methods. Then, to keep everything in order I create a class `LedModule` which handle the led strip state, changes, etc.

Here some parts of my class

```
LedModule::LedModule(unsigned int numOfPixels, uint8_t dataPin)
{
    // When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
    // Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
    // example for more information on possible values.
    pixels = Adafruit_NeoPixel(numOfPixels, dataPin, NEO_GRB + NEO_KHZ800);

    mState = LED_MODULE_STATE_IDLE;
    mIsLedStripOn = false;
}

...

// The method to set all leds of the strip to the same color
void LedModule::turnAllNeoPixelsTo(uint8_t red, uint8_t green, uint8_t blue)
{
    for (uint16_t i = 0; i < getLedCount(); i++)
    {
        // Avoid to light up the middle leds
        if (i < 5 || i > 9)
        {
            pixels.setPixelColor(i, red, green, blue);
        }
        else{
            pixels.setPixelColor(i, 0,0,0); // off
        }
    }
    pixels.show(); // This sends the updated pixel color to the hardware.
    mIsLedStripOn = true;
}

```

After this changes, when I call the method above, I got the exception:

```
Exception 29: StoreProhibited: A store referenced a page mapped with an attribute that does not permit stores
Decoding 15 results
0x4020ddbd: ieee80211_send_mgmt at ?? line ?
0x4020db5f: ieee80211_send_mgmt at ?? line ?
0x40102864: trc_NeedRTS at ?? line ?
0x4020fe6d: ieee80211_sta_new_state at ?? line ?
0x402101ab: ieee80211_sta_new_state at ?? line ?
0x4021060f: sta_input at ?? line ?
0x402109cb: ieee80211_parse_wmeparams at ?? line ?
0x402103ab: sta_input at ?? line ?
0x40204ce3: pp_tx_idle_timeout at ?? line ?
0x40204607: ppPeocessRxPktHdr at ?? line ?

```

It seems to crash during the `pixels.setPixelColor(i, red, green, blue);` method.

# Answer
Your "constructor" isn't doing what you think.

In the example you point to you have, efectively:

```
Class object = Class(parameters);

```

Whereas in your code you have:

```
Class object;

object = Class(parameters);

```

In the first form it results in a new `object` constructed at declaration time. In the second it first creates a new "empty" object and then at a later date tries to copy a newly constructed object into it - which may be failing if the class doesn't support copying.

Instead you should be working with `new` and pointers.

In your class definition you create a pointer to your Adafruit class:

```
private:
    Adafruit_NeoPixel *pixels;

```

Then you create a `new` object pointing to it:

```
pixels = new Adafruit_NeoPixel(numOfPixels, dataPin, NEO_GRB + NEO_KHZ800);

```

Accessing it is then done with `->` instead of `.`:

```
pixels->setPixelColor(i, red, green, blue);

```
> 2 votes

---
Tags: esp8266, rgb-led, neopixel
---


# Question
Title: Is it possible to use Arduino PWM for audio within a PAM8493 amplifier?
I've seen some projects using PWM for playing audio files, and it seems like it needs an amplifier, otherwise the sound is very low.

I already made a project using a DFPlayer and PAM8403, but now I need more control over the files in the SD Card which is not supported by the DFPlayer library, so it seems like I need to use PWM and a SD Card module, instead of a separate audio module.

My questions are, can I simply connect the PWM output to the amplifier (PAM8403) and I will be able to control volume (using the programming language) and have a good quality sound?

# Answer
Are you using a basic Arduino board (not I2S) and a sampling frequency of 8 kHz or 16 kHz? That could interfere with the default switching frequency of 260 kHz.

My suggestion is to use a low pass RC filter.
You might have to lower the signal level from the Arduino.
The PAM8403 requires a series capacitor and resistor at the input (those are probably already on the amplifier module).
In the end you probably need a voltage divider with a capacitor to ground for each channel.

I don't know if your PWM library has volume control. The TMRh20 has a function to set the volume.

The overall quality will be reasonable, but not very good. There are MP3 shields that can play mp3 files from a SD memory card. Those have better quality.

\[**ADDED**\]
I think I have misunderstood your question. Sorry. I'm still not sure that I understand your question now.

Wiki of DFPlayer Mini: DFRobot:DFPlayer Mini
Code on Github for DFPlayer Mini: Github:DFPlayer Mini
The PAM8403 has no volume control, you need to adjust the audio signal that is going to the PAM8403 module.
The DFPlayer Mini code has functions for volume, volumeUp, volumeDown and readVolume. However, it does not seem to have a function to select a specific file.

The Adafruit Music Maker shield is in two versions, one has an amplifier onboard: Adafruit:Music Maker MP3 Shield for Arduino w/3W Stereo Amp - v1.0. With that shield, you can play a file by its name. It can also set the volume. I suppose that is what you want ?
> -1 votes

---
Tags: pwm, audio
---


# Question
Title: H11L1 opto isolator does not pass signal to Arduino (correctly)
I have made a very basic test circuit for the opto coupler H11L1 ('similar'datasheet: http://www.datasheet4u.com/datasheet/H/1/1/H11L1\_MotorolaInc.pdf.html))

I use the test circuit:

simulate this circuit – Schematic created using CircuitLab

The LED and 470 ohm resistor is only for testing. U1 is the Arduino (software serial pin 9/11) and U2 is the H11L1.

The LED is flashing similar to the RX led on the Arduino.

Also I tested before in an even simpler circuit that the signals from the H11L1 pass through pin 4 (although inverted, which seems to be normal).

However, I don't receive any data in the Arduino (I tried different Arduinos, different speeds, different H11L1).

The data I receive from the (hardware) serial/debug terminal:

```
0
0
0
0

```

etc.

My sketch:

```
#include <SoftwareSerial.h>

SoftwareSerial mySerial(9, 11); // RX, TX

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

void loop()
{
    mySerial.write('A');
    while (mySerial.available())
    {
        Serial.println(mySerial.read());
    }

    delay(100);
}

```

How can I get the correct signal? (meaning 'A' are printed instead of 0's?

# Update

New sketch (not having the duplex problem):

```
#include <SoftwareSerial.h>

SoftwareSerial mySerial(12, 13); // RX, TX

void setup()
{

  Serial.begin(115200);
  mySerial.begin(115200);
}

void loop()
{
  Serial.print("Write: A ");
  mySerial.write('A');

  while (mySerial.available())
  {
    Serial.print((int) mySerial.read());
  }

  Serial.println("");

  delay(100);
}

```

Output:

```
Write: A
Write: A
Write: A
Write: A

```

etc.

# Update

Problem solved: I put it in an answer for clearity.

# Answer
> 3 votes
simulate this circuit – Schematic created using CircuitLab

I'm not sure I can help much with the MIDI problem but I can help with the schematic. I've reorganised it for clarity. Since the opto-isolator has an open-collector output any loads it is driving should be connected to supply + rather than common.

# Answer
> 1 votes
Rule of thumb: never use SoftwareSerial (unless you have to, and even then you should avoid it).

The SoftwareSerial works better with higher baudrates. The lower the baudrate, the more trouble you get. Unless you aim for a high baudrate of 115200, then SoftwareSerial can cause troubles again. Remember that using SoftwareSerial means that there is not much else you can do in your sketch.

When SoftwareSerial is used with a very low baudrate of 300, then it could even disturb the receiving of data of other hardware serial ports. Because SoftwareSerial disables interrupts during transmitting and receiving, the lower the baudrate, the longer the interrupts will be disabled.

**The SoftwareSerial can not transmit and receive at the same time, and that is what you are doing.**

A Arduino Leonardo, Micro, or Arduino Mega 2560 board have unused hardware serial port(s). Use one of those to do tests with a serial port. As soon as you start using SoftwareSerial for a test, you are actually testing the SoftwareSerial itself.

There is an alternative, the AltSoftSerial Library. it can receive and transmit at the same time. Use a baudrate that is not too high, 9600 baud should be fine.

# Answer
> 0 votes
Problem solved:

I created a setup with two Arduino Uno's, one which sends the information by a hardware UART, one that receives it. The reason to do this is not to use a software serial and having no problems with the duplex. I thought I need a Mega, but with two Uno's it is also possible.

However, this did NOT solve the problem.

What solved the problem was to use TWO opto-isolators. The H11L1 inverts the signal, and it seems I had to connect the output of the first H11L1 to the input of a second and now it works.

---
Tags: arduino-uno, serial, opto-isolator
---


# Question
Title: Incorrect data being received on RX of NRF24L01P
I am running a setup of two NRF24L01P's on homemade code where the TX sends an analog signal fed through a standard pot, and the RX simply prints out the signal. But the RX seems to be getting incorrect data, meaning that where the centre value on TX side is 670, the centre value on RX side is 180. Why is this happening? I have auto acknowledgement, and dynamic payload enabled. I also tried setting 250KBPS and 2000KBPS with the max power setting, and still the results dont change. Is this because of loss of power in the wireless communication? Will a voltage follower be needed?

Function definitions in code:

```
/* CONNECTIONS
 * NRF    ARDUINO
 * GND    GND
 * VCC    VCC
 * CE     D7
 * CSN    D8
 * MOSI   D11
 * SCK    D13
 * MISO ``D12
 * IRQ    D2*/

 #include <SPI.h>
 #define CE_PIN 7
 #define CSN_PIN 8
 #define MOSI_PIN 11
 #define SCK_PIN 13
 #define MISO_PIN 12
 #define W_REGISTER B00100000
 #define R_RX_PAYLOAD B01100001
 #define W_TX_PAYLOAD B10100000
 #define FLUSH_TX B11100001
 #define FLUSH_RX B11100010
 #define RF_SETUP 0x06
 #define RF_DR_LOW 5
 #define RF_DR_HIGH 3
 #define RF_CH 0x05
 #define EN_RXADDR 0x02
 #define ERX_P0 0
 #define SETUP_AW 0x03
 #define RX_ADDR_P0 0x0A
 #define FEATURE 0x1D
 #define EN_DPL 2
 #define EN_AA 0x01
 #define CONFIG 0x00
 #define PWR_UP 1
 #define PRIM_RX 0
 #define MASK_RX_DR 6
 #define MASK_TX_DS 5
 #define MASK_MAX_RT 4
 #define EN_CRC 3
 #define CRCO 2
 #define STATUS 0x07
 #define RX_DR 6
 #define TX_DS 5
 #define MAX_RT 4
 #define NOP B11111111
 #define TX_ADDR 0x10
 #define DYNPD 0x1C

 byte data_buff;
 int address = 123;
 byte data_recieve;

//******************************** write a byte to a regster *******************************
void writeRegister(byte reg_address, byte data)
{
  bitClear(PORTB, 0);
  SPI.transfer(W_REGISTER | reg_address);
  SPI.transfer(data);
  bitSet(PORTB, 0);
}

//******************************* set the air data rate *******************************
void setAirDataRate(int air_data_rate)
{
  switch(air_data_rate)
  {

    case 250:
     setRegisterBit(RF_SETUP, RF_DR_LOW, 1);
     setRegisterBit(RF_SETUP, RF_DR_HIGH, 0);
     break;

    case 1000:
     setRegisterBit(RF_SETUP, RF_DR_LOW, 0);
     setRegisterBit(RF_SETUP, RF_DR_HIGH, 0);
     break;

    case 2000:
      setRegisterBit(RF_SETUP, RF_DR_LOW, 0);
      setRegisterBit(RF_SETUP, RF_DR_HIGH, 1);
      break;

    default:
      Serial.println("WRONG AIR DATA RATE ENTERED!");
      break;
  }
}

void setRegisterBit(byte reg_address, byte bit_add, byte bit_val)
{
  getRegisterStat(reg_address);

  if(bit_val == 1)
  {
    bitSet(data_buff, bit_add);
  }

  else
  {
    bitClear(data_buff, bit_add);
  }

  bitClear(PORTB, 0);
  SPI.transfer(W_REGISTER | reg_address);
  SPI.transfer(data_buff);
  bitSet(PORTB, 0);

  Serial.print(bit_add);
  Serial.print(" bit set to ");
  Serial.print(bit_val);
  Serial.print(" in register ");
  Serial.println(reg_address);
}

void getRegisterStat(byte reg_address)
{
  bitClear(PORTB, 0);
  SPI.transfer(reg_address);
  data_buff = SPI.transfer(0);
  bitSet(PORTB, 0);
}

void enableDPL( int pipe_number)
{
  setRegisterBit(FEATURE, EN_DPL, 1); //enable dpl by EN_DPL = 1
  setRegisterBit(DYNPD, pipe_number, 1); //DPL_Px = 1
}

void openReadingPipe()
{
  setRegisterBit(EN_RXADDR, 0, 1); //ERX_P0 = 1
  writeRegister(RX_ADDR_P0, address);//set address for datapipe
  Serial.print("Data Pipe open with address:  ");
  Serial.println(address);
}

void openWritingPipe()
{
  setRegisterBit(EN_RXADDR, 0, 1); //ERX_Px = 1
  writeRegister(TX_ADDR, address);//set address for datapipe
  writeRegister(RX_ADDR_P0, address);
}

//******************************* set the frequency *******************************
void setChannelFreq(int frequency)
{
  int  frequency_val = frequency - 2400;
  if(frequency_val <= 125 && frequency_val > 0)
  {
    writeRegister(RF_CH, frequency_val);
  }

  else
    Serial.println("WRONG FREQUENCY VALUE ENTERED!");
}

//******************************* print the status of the register *******************************
void printRegStatus(byte reg_address)
{
  getRegisterStat(reg_address);

  switch(reg_address)
  {
    case RF_SETUP:
    bitRead(data_buff, 3) ? Serial.println("AIR DATA RATE SET TO 2000KBPS") : bitRead(data_buff, 5) ? Serial.println("AIR DATA RATE SET TO 250KBPS") : Serial.println("AIR DATA RATE SET TO 1000KBPS");
    break;

    case EN_RXADDR:
    bitRead(data_buff, 0) ? Serial.print("Data Pipe 0 open with address:  ") : Serial.print("Data Pipe 0 not open with address:  ");
    Serial.println(address);
    break;

    case RF_CH:
    Serial.print("The set frequency is:");
    Serial.println(2400 + data_buff);
    break;

    case CONFIG:
    bitRead(data_buff, MASK_RX_DR) ? Serial.println("RX_DR interrupt not reflected on IRQ") : Serial.println("RX_DR interrupt is active low on IRQ");
    bitRead(data_buff, MASK_TX_DS) ? Serial.println("TX_DS interrupt not reflected on IRQ") : Serial.println("TX_DS interrupt is active low on IRQ");
    bitRead(data_buff, MASK_MAX_RT) ? Serial.println("MAX_RT interrupt not reflected on IRQ") : Serial.println("MAX_RT interrupt is active low on IRQ");
    bitRead(data_buff, EN_CRC) ? Serial.println("CRC is Enabled!") : Serial.println("CRC is diabled!");
    bitRead(data_buff, CRCO) ? Serial.println("CRC is 2 bytes.") : Serial.println("CRC is 1 byte.");
    break;

     case EN_AA:
    bitRead(data_buff, 0) ? Serial.println("ENABLE AUTO ACK ON PIPE 0") : Serial.println("AUTO ACK NOT ENABLED");
    break;

    case FEATURE:
    bitRead(data_buff, EN_DPL) ? Serial.println("DYNAMIC PAYLOAD LENGTH ENABLED") : Serial.println("DYNAMIC PAYLOAD LENGTH NOT ENABLED!");
    break;

    case DYNPD:
    bitRead(data_buff, 0) ? Serial.println("DYNAMIC PAYLOAD ON DATA PIPE 0 ENABLED!") : Serial.println("DYNAMIC PAYLOAD NOT ENABLED IN DATA PIPE!");
    break;

    case TX_ADDR:
    Serial.print("ADDRESS: ");Serial.println(data_buff);
    break;

    case RX_ADDR_P0:
    Serial.print("ADDRESS: ");Serial.println(data_buff);
    break;

    case SETUP_AW:
    if(bitRead(data_buff, 1) == 0 && bitRead(data_buff, 0 == 1))
    Serial.println("ADDRESS WIDTH 3 BYTES!");
    break;

  }
}

//******************************* set the address width *******************************
void setAddressWidth(byte address_width)
{
  switch(address_width)
  {
    //addres width is 3 bytes
    case 3:
    setRegisterBit(SETUP_AW, 0, 1);
    setRegisterBit(SETUP_AW, 1, 0);
    break;

    //address width is 4 bytes
    case 4:
    setRegisterBit(SETUP_AW, 0, 0);
    setRegisterBit(SETUP_AW, 1, 1);
    break;

    //address width is 5 bytes
    case 5:
    setRegisterBit(SETUP_AW, 0, 1);
    setRegisterBit(SETUP_AW, 1, 1);
    break;

    default:
    Serial.println("WRONG ADDRESS WIDTH ENTERED!");
    break;
  }
}

//******************************** enable auto acknowledgment *******************************
void enableAutoACK()
{
  setRegisterBit(EN_AA, 0, 1);
}

//******************************** enable auto acknowledgment *******************************
void clearInterrupts()
{
  setRegisterBit(STATUS, RX_DR, 1);
  setRegisterBit(STATUS, TX_DS, 1);
  setRegisterBit(STATUS, MAX_RT, 1);
}

void confirmTransmit()
{
  Serial.print("PACKET SENT SUCCESSFULLY!!");
  setRegisterBit(STATUS, TX_DS, 1);

}

void setupRadio(int air_data_rate, int frequency, byte address_width)  //air data rate in kbps, frequency in MHz, address width in bytes
{

  DDRB = B00101001;
  DDRD = B10000000;
  Serial.begin(115200);
  SPI.begin();
  //set air data rate
  setAirDataRate(air_data_rate);

  //set frequency
  setChannelFreq(frequency);

  //set address width
  setAddressWidth(address_width);

  //flush the rx and tx fifo
  bitClear(PORTB, 0);
  SPI.transfer(FLUSH_RX);
  bitSet(PORTB, 0);

  bitClear(PORTB, 0);
  SPI.transfer(FLUSH_TX);
  bitSet(PORTB, 0);

  //enable dpl
  enableDPL(0);

  //enable CRC
  setRegisterBit(CONFIG, EN_CRC, 1);
  setRegisterBit(CONFIG, CRCO, 0);

  bitClear(PORTD, 7); //set CE low
  bitSet(PORTB, 0);// keep CSN high
}

//******************************** setup the RX *******************************
void setupRX()
{
    //open up the pipe for transmission
    openReadingPipe();

    //mask tx and max rt IRQ
    setRegisterBit(CONFIG, MASK_MAX_RT, 1);
    setRegisterBit(CONFIG, MASK_TX_DS, 1);

    //power up module
    setRegisterBit(CONFIG, PWR_UP, 1);

    //Tpd2stby delay
    delay(5);

    attachInterrupt(digitalPinToInterrupt(2), recieveData, FALLING);

    //clear any interrupt flag
    clearInterrupts();

    //set PRIM_RX bit
    setRegisterBit(CONFIG, PRIM_RX, 1);
    bitSet(PORTD, 7); //set CE high
    delay(1);
}

//******************************** setup the TX *******************************
void setupTX()
{
  openWritingPipe();
  setRegisterBit(CONFIG, PRIM_RX, 0);

  //mask rx and max rt interrupt
  setRegisterBit(CONFIG, MASK_RX_DR, 1);
  setRegisterBit(CONFIG, MASK_MAX_RT, 1);

  //enable autoACK
  enableAutoACK();

  setRegisterBit(RF_SETUP, 2, 1);
  setRegisterBit(RF_SETUP, 1, 1);
  setRegisterBit(CONFIG, PWR_UP, 1);

  delay(5);

  attachInterrupt(digitalPinToInterrupt(3), confirmTransmit, FALLING);

  clearInterrupts();
  delay(1);
}

//******************************** read data from RX FIFO *******************************
void recieveData()
{
  Serial.println("RECIEVE ISR BEGUN");

  bitClear(PORTD, 7); //set CE_PIN low
  delayMicroseconds(100);

  bitClear(PORTB, 0);
  SPI.transfer(R_RX_PAYLOAD);
  data_recieve = SPI.transfer(NOP);
  bitSet(PORTB, 0);

  bitClear(PORTB, 0);
  SPI.transfer(RPD);
  data_buff = SPI.transfer(NOP);
  delay(1);
  bitSet(PORTB, 1);

  bitRead(data_buff, 0) ? Serial.println("THERE IS ENOUGH POWER!") :
  Serial.println("THERE IS NOT ENOUGH POWER!");

  delayMicroseconds(15000);
  setRegisterBit(STATUS, RX_DR, 1);

  bitSet(PORTD, 7);
  delayMicroseconds(100);

  Serial.print("THROTTLE :");
  Serial.println(data_recieve);
 }
//******************************** write data to be transmitted *******************************
void transmitData(byte data)
{
  bitClear(PORTB, 0);
  SPI.transfer(FLUSH_TX);
  bitSet(PORTB, 0);

  bitClear(PORTB, 0);
  SPI.transfer(W_TX_PAYLOAD);
  SPI.transfer(data);
  bitSet(PORTB, 0);

  bitSet(PORTD, 7);
  delayMicroseconds(1000);
  bitClear(PORTD, 7);

  delayMicroseconds(130);

  /*bitClear(PORTB, 0);
  SPI.transfer(0x17);
  data_buff = SPI.transfer(NOP);
  bitSet(PORTB, 0);
  bitRead(data_buff, 4) ? Serial.println("TX FIFO EMPTY!") :
  Serial.println("DATA IN TX FIFO");*/
}

```

The RX code (all function definitions are same obviously):

```
void setup(){
  setupRadio(1000, 2515, 3);
  setupRX();
 /*printRegStatus(CONFIG);
 printRegStatus(TX_ADDR);
 printRegStatus(RX_ADDR_P0);
 printRegStatus(EN_AA);
 printRegStatus(RF_CH);
 printRegStatus(FEATURE);
 printRegStatus(RF_SETUP);
 printRegStatus(SETUP_AW);*/

}

void loop(){

 delay(1000);
}

```

The TX code (all function definitions are same obviously):

```
void setup(){
      setupRadio(1000, 2515, 3);
      setupTX();
     /*printRegStatus(CONFIG);
     printRegStatus(TX_ADDR);
     printRegStatus(RX_ADDR_P0);
     printRegStatus(EN_AA);
     printRegStatus(RF_CH);
     printRegStatus(FEATURE);
     printRegStatus(RF_SETUP);
     printRegStatus(SETUP_AW);
     printRegStatus(DYNPD);*/

    }

    void loop(){
     int throttle_raw = sqrt(pow(analogRead(A2), 2) + pow(analogRead(A3), 2));
      transmitData(throttle_raw);
      Serial.println(throttle_raw);
      delay(1000);
    }

```

# Answer
> 0 votes
Your new TX function:

```
void transmitData(byte * data, byte len)
{
  bitClear(PORTB, 0);
  SPI.transfer(FLUSH_TX);
  bitSet(PORTB, 0);

  bitClear(PORTB, 0);
  SPI.transfer(W_TX_PAYLOAD);

  len = min(len, 32); // since 32 is max size
  for (int i = 0; i < len; i++)
    SPI.transfer(*data++);
  bitSet(PORTB, 0);

  bitSet(PORTD, 7);
  delayMicroseconds(1000);
  bitClear(PORTD, 7);

  delayMicroseconds(130);

  /*bitClear(PORTB, 0);
  SPI.transfer(0x17);
  data_buff = SPI.transfer(NOP);
  bitSet(PORTB, 0);
  bitRead(data_buff, 4) ? Serial.println("TX FIFO EMPTY!") :
  Serial.println("DATA IN TX FIFO");*/
}

```

To receive data with dynamic payloads enabled, you need to know the size of the incoming payload before you read. Study `getDynamicPayloadSize()` in the RF24 library and pass the value returned as the second argument to the RX function below. Your new RX function should look like this:

```
void recieveData(byte * data, byte len)
{
  Serial.println("RECIEVE ISR BEGUN");

  bitClear(PORTD, 7); //set CE_PIN low
  delayMicroseconds(100);

  bitClear(PORTB, 0);
  SPI.transfer(R_RX_PAYLOAD);
  for (int i = 0; i < len; i++){
    *data = SPI.transfer(0xff); data++;
  }
  bitSet(PORTB, 0);

  bitClear(PORTB, 0);
  SPI.transfer(RPD);
  data_buff = SPI.transfer(NOP);
  delay(1);
  bitSet(PORTB, 1);

  bitRead(data_buff, 0) ? Serial.println("THERE IS ENOUGH POWER!") :
  Serial.println("THERE IS NOT ENOUGH POWER!");

  delayMicroseconds(15000);
  setRegisterBit(STATUS, RX_DR, 1);

  bitSet(PORTD, 7);
  delayMicroseconds(100);
 }

```

In both functions, you pass in buffers to hold the data you want to send or receive. In your case, since you're sending `int`s, a call like this `transmitData(&throttle, 2)` should do. Since you already know the size of what you're sending, you can simply pass 2 as length to `receiveData()` and skip querying the payload size like this `receiveData(&throttle, 2)`. Casting will be done implicitly.

If, in fact, `receiveData` is an ISR like your comments say (maybe you're using some IRQ pin), you'll have to split it in two; one part to handle the interrupt quickly by setting an `available` flag or something (obviously taking no arguments) to be polled in `loop()` and another to actually `read` the data. Or you can just setup the buffer as a global thing and hard-code a 2-byte read in the ISR. Though I have to say your maybe-ISR is terrible, what with huge delays and prints everywhere and I don't know how it manages to work at all.

Basically, if you want to understand the chip, it doesn't hurt to look at existing code to understand the 'right' way to do stuff.

---
Tags: arduino-uno, programming, spi, nrf24l01+, wireless
---


title: timer0_millis always returns 0

text:
# Question
Title: timer0_millis always returns 0
I am trying to make a simple debounce function as explained here but the condition `if((millis()-timeCheck)>reboundDelay)` is never met.

As you can see in my code below, I am trying to control a PWM with two push buttons. I am currently sending it on a LED.

With AS7 and vMicro I put some breakpoints and realized that `timeCheck` was stuck at 0 and was an `unsigned int` instead of the `unsigned long` I declared. With the debugger I looked inside of the `millis()` function and saw that `timer0_millis` wasn't increasing neither, stuck at 0.

Here is my short code (it's a sketch, it can surely be rewritten in a more efficient way) :

```
int PWM=9;
int dutyP=2;
int dutyM=3;
int duty=123;
bool stateP=0;
bool stateM=0;
bool prevStateP=0;
bool prevStateM=0;
unsigned long reboundDelay=500;
unsigned long timeCheck=millis();

void setup() {
  pinMode(PWM,OUTPUT);
  pinMode(dutyP,INPUT);
  pinMode(dutyM,INPUT);
}

void loop() {
  stateP=digitalRead(dutyP);
  stateM=digitalRead(dutyM);
  if(stateP != prevStateP || stateM != prevStateM) {
    timeCheck=millis();
  }
  if((millis() -  timeCheck) > reboundDelay) {
    if(stateP==1) {
      duty=duty+25;
    } else if(stateM==1) {
      duty=duty-25;
    }
    analogWrite(PWM,duty);
    prevStateP=stateP;
    prevStateM=stateM;
  }
}

```

And finally, the strange part. When I upload it on my Genuino Uno for like 30 seconds, the pushbuttons do nothing (it may be that the `if` works) and afterwards I can increase and decrease the duty cycle but without the delay that the condition should bring (the LED flashes really fast due to an overflow in analogWrite).

Any help is welcomed, the strange part is secondary to me but I would really like to make `millis()` work properly.

# Answer
I think there is just a logic error that doesn't immediately jump out: When the button state is changed, it will always set timeCheck equal to millis(). For instance, as long as you are pressing "P", stateP will not be equal to prevStateP and so "timeCheck=millis()" will executed everytime thru the loop, so the difference will never reach 500.

```
if(stateP != prevStateP || stateM != prevStateM){
    timeCheck=millis();
}

```

Should be something like:

```
if(stateP == prevStateP && stateM == prevStateM){
    timeCheck = millis();
}

```

This will continually keep timeCheck = millis() until either button is pressed. Once the button is pressed, timeCheck will remain at the value of millis() read just before the press, until the debounce value is reached (unless noise/bounce and not a real press, or button is released early as 500ms is a relatively long time).

This is probably the simplest modification to the code I can come up with. Hope it helps.
> 2 votes

# Answer
I would suggest a few things:

1) comment on your code -\> lay out the basic logic so that you and others can help you debug it;

2) use brackets liberally -\> don't rely on memory (=faulty) on the order of operations. instead, define it explicitly;

3) check your logic -\> make sure that your code does what you want it to do;

4) pay attention to data type: 8-bit vs. 16-bit, etc.

5) modularize your code -\> this allows more efficient debugging and code reusing.

for example, your code can be simply described as

```
  button_state = read_button(); //read button state, with debouncing
  if (button_state = BUTTON_UP) pwminc_dc(pwm_dc); //increase duty cycle, with boundary checking
  if (button_state = BUTTON_DOWN) pwmdec_dc(pwm_dc); //decrement duty cycle, with boundary checking

```

with the code modularized, you just need to worry about getting individual pieces right.
> 1 votes

---
Tags: arduino-uno, pwm, millis
---


# Question
Title: Servo only going one direction till it reach limit
I have a ATTiny85 with a standard servo motor attached to it. I would expect the following sketch to make the servo to oscillate between position 60 and 100 but instead it just to to it's limit (180) and grinds there...

Any ideas ?

```
#include <avr/power.h>
#include <Adafruit_SoftServo.h>

Adafruit_SoftServo servo;

#define MOTOR_PIN 0

bool flip = true;

void setup() {
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  // Set up the interrupt that will refresh the servo for us automagically
  OCR0A = 0xAF;            // any number is OK
  TIMSK |= _BV(OCIE0A);    // Turn on the compare interrupt (below!)

  servo.attach(MOTOR_PIN);
  servo.write(90);           // Tell servo to go to position per quirk
  delay(15);
}

void loop() {
  if(flip) {
    servo.write(60);
    delay(150);
    !flip;
  }
  else {
    servo.write(100);
    delay(150);
    !flip;
  }

  delay(500);

}

// We'll take advantage of the built in millis() timer that goes off
// to keep track of time, and refresh the servo every 20 milliseconds
volatile uint8_t counter = 0;
SIGNAL(TIMER0_COMPA_vect) {
  // this gets called every 2 milliseconds
  counter += 2;
  // every 20 milliseconds, refresh the servos!
  if (counter >= 20) {
    counter = 0;
    servo.refresh();
  }
}

```

Thanks.

# Answer
`!flip` doesn't really do anything and will probably be optimized out by the compiler. You need to save the result: `flip = !flip;`

You can simplify the code a bit:

```
void loop() {
    if(flip) {
        servo.write(60);
    }
    else {
        servo.write(100);
    }
    flip = !flip;
    delay(650);
}

```

Or, get rid of the `delay` altogether:

```
uint32_t last_millis = 0;
void loop() {
    if (millis() - last_millis >= 650) {
        servo.write(flip ? 60 : 100);
        flip = !flip;
        last_millis = millis();
    }
}

```
> 4 votes

---
Tags: servo, attiny85
---


# Question
Title: error: espcomm_upload_mem failed ESP8266
So, I downloaded tools for my ESP8266 using this link: http://arduino.esp8266.com/stable/package\_esp8266com\_index.json

I installed the last version in my motherboard manager (2.3.0) and tried to execute my first example ("Blink"), but here is what I get :

What can I do to prevent this?

P.S My ESP8266 is connected to an Arduino Mega

# Answer
The reason why this error comes up is because the programmer cannot communicate with the bootloader of the ESP. The link you mentioned in the comments misses a very important step, which is to remove the ATmega chip already on the Uno board. Otherwise the programmer will see corrupt data due to 2 bootloaders on the same UART lines. Remember that only one device can communicate on the UART lines. The Mega board has the ATmega chip soldered to the board, so you don't have much hopes of isolating the UART lines. Another thing to remember is to always reset the ESP into flash mode (reset the ESP with GPIO\_0 pulled low).

If you still want to use the ESP with the Mega board, go through the Multi Serial examples given in the IDE. The concept requires making two GPIO lines communicate with the ESP, while the original Serial lines to the programmer (the computer). All data sent via ESP is routed to Mega's serial lines and vice versa.
> 1 votes

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


# Question
Title: Passing serial data to Processing using something other than ln to trigger Processing
I have a Uno program and I can transfer data to Processing using println. In Processing bufferUntil('\n') interprets the ln as \n, stops buffering, and reads the string until the next '\n'. I would like to use something other than ln to trigger Processing. That way I can use Serial Monitor in the Uno to see serial data when Processing is not running at the same time.

I have searched the net but have not found the technique to use something other than ln. Thanks.

# Answer
If I understand your question (which is not certain):

* Pick a different "trigger" byte that you won't be sending in your messages. Maybe *TAB*?
* In your "Processing" program, use: `port.bufferUntil(TRIGGER);`
* In your Arduino sketch, rather than *println*, use *print* to send both your data and the trigger byte: `Serial.print(your_message); Serial.print(TRIGGER);`

Note that sending binary data will cause this to fail when the data uses the trigger byte.

*From: https://www.arduino.cc/en/Serial/Println The **println()** method sends your output then a CR and NL. And it seems **bufferUntil()** takes a character on which to trigger: https://processing.org/reference/libraries/serial/Serial\_bufferUntil\_.html*
> 2 votes

---
Tags: arduino-uno, serial, processing-lang, data
---


title: Neopixels with I/O expander

text:
# Question
Title: Neopixels with I/O expander
Because I have no pins available on my Wemos D1 mini, I want to drive my Neopixel ring from a MCP23008 I/O expander.

I'm trying to run the 'simple' example from the Adafruit\_neopixel library. How do I declare the Neopixel pin number when using say pin 0 on the MCP23008 - or is this impossible?

# Answer
> 4 votes
I don't think that will be an option. The NeoPixel parts need very tight control of the timing in order to work, if the pin timing is wrong by 100 us the wrong data will get latched in.

Can you move some other functions / pins onto the IO expander and then drive the neopixels directly from the processor?

# Answer
> 0 votes
I think you will need to write your own library. This isn't as bad as it seems. If the library uses analog write then it won't work, because I don't think you can do PWM with that expander.

The library writes directly to pins. You need to intercept this behaviour and tell the library to tell the MCP230008 to write to the pin. I haven't seen the library I question, but this should be straight forward.

If you take the existing Adafruit library and find where it writes to a pin. Rather than calling `digitalWrite` it needs to call `expanderWrite(pin, state)`. Every instance of `pinMode()` needs replacing with `explanderPinMode(pin, mode)` Then write yourself those two functions that use I2C/SPI to set the IOX's registers to implement what you need.

The IO Expander is not going to be a good idea if the library requires critical accurate timing, because of the lag of telling the IOX to do things. An alternative is to use another D1 as the IO expander.

---
Tags: esp8266, neopixel
---


# Question
Title: What could I use to vary the temperature of a Heating Pad?
Could I get something like this, a 12v silicone heating pad, and vary its temperature with an arduino somehow?

http://www.banggood.com/Waterproof-Silicone-Flexible-Heating-Pad-6060MM-DC-12V-10W-p-972464.html

My grand plan is to put temperature sensors on it and make it hit a certain temperature, and make it hotter/cooler to try and reach a target temperature.

# Answer
In principle, I don't see any problems. Your heating pad uses 12V and 10W, which means it would be consuming slightly less than one amp of current. The MOSFET you linked can go up to 5A (needing a heat sink with over 1A).

You could use PWM (there are 6 pins on a Uno that can do that) to provide pulse-width modulation to control the amount of output you give to the heater.

You would, of course, need to measure the heat of the device to work out when to adjust the PWM output. You might look up using a PID algorithm to adjust the PWM output depending on the sensed heat input.

---

## References:
> 4 votes

# Answer
If you want to control the temperature very accurately, try connecting a shunt resistor (value: \<0.1 ohm) in series with the heater. Use an op-amp to amplify the voltage difference on its two terminals and read with Arduino the resulting value. You can calculate with it the actual current and therefore the actual resistance of the heating pad.

The value changes with temperature, you can use the resistance value to measure the surface temperature of the heating pad.
> 0 votes

---
Tags: temperature-sensor, mosfet
---


title: Unable to upload code to Leonardo

text:
# Question
Title: Unable to upload code to Leonardo
I was using Arduino-Makefile to upload code to a Leonardo via its standard `make upload`. However, it became "stuck" and unresponsive, as Leonardo's sometimes do. I tried power cycling it, and unplugging the USB cable, but nothing worked. So I tried re-burning the bootloader via an AVRISP MkII programmer and the Arduino 1.8.2 IDE, but that only made things worse.

It somehow uploaded a simple "blink" program, but now the it's completely unable to be programmed via USB. When I run `make upload`, or use the Arduino IDE's "upload" button, the Leonoardo's status LED begins blinking rapidly and its `/dev/ttyACM0` device disappears permanently. I have to power-cycle it to make the device reappear, but the upload still fails, with the error:

```
/usr/share/arduino/bin/ard-reset-arduino --caterina  /dev/ttyACM0
make[1]: Leaving directory '/usr/local/myproject/main'
make do_upload
make[1]: Entering directory '/usr/local/myproject/main'
/usr/share/arduino/hardware/tools/avr/bin/avrdude -v -p atmega32u4 -C /usr/share/arduino/hardware/tools/avr/etc/avrdude.conf -D -c avr109 -b 57600 -P /dev/ttyACM0 \
        -U flash:w:build-leonardo/main.hex:i

avrdude: Version 6.3, compiled on Jan 17 2017 at 11:00:16
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/usr/share/arduino/hardware/tools/avr/etc/avrdude.conf"
         User configuration file is "/home/chris/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

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

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

         Programmer Type : butterfly
         Description     : Atmel AppNote AVR109 Boot Loader

Connecting to programmer: .avrdude: butterfly_recv(): programmer is not responding

avrdude: butterfly_recv(): programmer is not responding
avrdude: butterfly_recv(): programmer is not responding
avrdude: butterfly_recv(): programmer is not responding
avrdude: butterfly_recv(): programmer is not responding
avrdude: butterfly_recv(): programmer is not responding
Found programmer: Id = ""; type =
    Software Version = .; Hardware Version = �.
avrdude: butterfly_recv(): programmer is not responding
avrdude: butterfly_recv(): programmer is not responding
avrdude: error: buffered memory access not supported. Maybe it isn't
a butterfly/AVR109 but a AVR910 device?
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

avrdude: butterfly_recv(): programmer is not responding
avrdude: error: programmer did not respond to command: leave prog mode
avrdude: butterfly_recv(): programmer is not responding
avrdude: error: programmer did not respond to command: exit bootloader

```

If I manually run:

```
/usr/share/arduino/bin/ard-reset-arduino --caterina  /dev/ttyACM0

```

or upload via the Arduino IDE, it makes the Leonardo disappear from USB, and blink rapidly. Pressing the reset button does nothing. I have to manually unplug its USB cable to fix it.

I can program it still using the AVRISP MkII programmer...but obviously that's a huge inconvenience since it takes about 5 minutes just to upload the sample blink sketch, and even then it requires that I first power off the Leonardo, disconnect the programmer, and then power on. For development, where I might need to make dozens of revisions, this turnout is far too slow.

Why am I unable to program the Leonardo via avrdude and USB?

# Answer
> 1 votes
Using some examples and similar questions, such as this one and this one, I fixed udev rules for the AVRISP MkII programmer, then I manually reflashed the Leonardo's bootloader with with the MkII by running:

```
avrdude -c avrispmkii -p m32u4 -P usb -B 8 -u -e -U lock:w:0x3F:m -v
avrdude -c avrispmkii -p m32u4 -P usb -v
avrdude -c avrispmkii -p m32u4 -P usb -u -U efuse:w:0xcb:m -v
avrdude -c avrispmkii -p m32u4 -P usb -u -U hfuse:w:0xd8:m -v
avrdude -c avrispmkii -p m32u4 -P usb -u -U lfuse:w:0xFF:m -v
avrdude -c avrispmkii -p m32u4 -P usb -U flash:w:/usr/share/arduino/hardware/arduino/avr/bootloaders/caterina/Leonardo-prod-firmware-2012-12-10.hex -v
avrdude -c avrispmkii -p m32u4 -P usb -U lock:w:0x0F:m -v

```

I'm not sure if the first and last command to write the lock bytes were necessary, since they returned the `verification error; content mismatch` error, but they didn't seem to break anything either.

Oddly, this ran in seconds, whereas the Arduino IDE took almost 5 minutes to burn the bootloader. So I suspect there's a bug in the Arduino IDE that burns an **incorrect or corrupted bootloader**.

After running this, `ard-reset-arduino` works correctly, and `make upload` can successfully upload a sketch again.

On a side note, I'm not 100% sure if `Leonardo-prod-firmware-2012-12-10.hex` was the correct bootloader to use. Again, I just made an educated guess based on naming. I'd read that the Leonardo uses the "caterina" bootloader, and the directory `/usr/share/arduino/hardware/arduino/avr/bootloaders/caterina` contained several .hex files, only three of which contained "Leonardo" in the name:

```
Caterina-Leonardo.hex
Leonardo-prod-firmware-2012-04-26.hex
Leonardo-prod-firmware-2012-12-10.hex

```

It seemed logical to not use `Leonardo-prod-firmware-2012-04-26.hex`, since that was likely an old and obsolete bootloader based on the date. That left `Caterina-Leonardo.hex` or `Leonardo-prod-firmware-2012-12-10.hex`. Unfortunately, checking the commit logs shows they're exactly the same age. In my experience, `prod` tends to mean the final or production product, so I decided to try that one first and it worked. If anyone knows what `Caterina-Leonardo.hex` is for and how it differs from the others, please tell me. I don't want to risk breaking my Leonardo again experimenting with this.

The only issue I'm having now is that after I upload my sketch, with uses ROS and about 49% of the Arduino's memory, I again can no longer upload new sketches to it. I'm assuming the sketch's use of the Serial port is somehow stopping `ard-reset-arduino` from properly resetting it\`. However, I the Arduino IDE is still able to upload sketches, so as a clumsy workaround, I can use that to upload the "blink" sketch, afterwhich then I can upload my own revised sketch.

---
Tags: usb, arduino-leonardo, uploading, isp
---


title: Which Arduinos have a true serial port?

text:
# Question
Title: Which Arduinos have a true serial port?
After driving myself insane with an unreliable Leonardo, I narrowed down the problem to its serial port. Namely, it's not a true serial port, but some sort of simulated monstrosity that can't be reliably reset. This makes uploading sketches immensely difficult. I found that neither Arduino-Makefile nor the Arduino IDE can reliably upload sketches to a Leonardo, and succeed only 10% of the time.

It took me awhile to accept just how terrible the Leonardo was, because before this, I had only used the Uno and Mega, which are extremely reliable. They've always "just worked" for me, so I couldn't understand why Arduino would release a board as unusable as the Leonardo. I've since realized the Uno is so reliable, in part because it has a more complete serial port, and don't use the dreaded 32u4 chip and its fake serial port that doesn't support the DTR or RST pins.

That said, which Arduino's have a real serial port? Is it only the Uno and Mega? After months of banging my head against a Leonardo, I want to avoid anything else that uses the Atmega32u4 chip. Unfortunately, looking at all the various boards, it looks like many, especially most of the newer ones, use the 32u4.

Am I missing something here? Everything I Google an error uploading with avrdude or the IDE, the results always mention problems with boards like the Leonardo and their unstable serial ports. Why does Arduino keep using the 32u4 chip if it's that unreliable?

# Answer
There seems to be quite a few Arduinos without a 32U4, like:

* Uno (you mentioned it already)
* Mega (same)
* Lilypad Snap
* MKR1000
* Pro
* Pro Mini
* Zero
* Due
* Ethernet
* Mini
* Nano
* MKR Zero

See the list at Comparison table.
> 5 votes

---
Tags: serial, usb, arduino-leonardo
---


# Question
Title: Why is 8x8 matrix pins do not correspond to rows and columns order?
It would be easier to program led matrix if 1-8 pins corresponded to 1-8 rows and 9-16 pins corresponded to 1-8 columns. Instead there is the following arrangement:

Why is it made like this?

# Answer
It's probably easier to manufacture, other than that, I don't see why. If this is a serious issue, you can contact your manufacturer, since he is most likely to know why.

You can:

1. Work around the issue, by wiring pin 1 to input 9, pin 2 to input 14 etc.
2. Make a software solution like:

#define ROW1 9

#define ROW2 14
3. Buy an LED-matrix that has the pins in the correct order (check the datasheet before purchase).
> 0 votes

---
Tags: led
---


# Question
Title: Measuring time between two photoresistors and printing time on lcd
I am working on a project that is supposed to record the time difference between two photoresistors that are 4in apart. The photoresistors are sensing the passing of water or other liquids on a chute/ramp.

The liquids range from water to milkshakes so the time difference shouldn't be more than 2 or 3 seconds at most (I would think). I'm okay with the accuracy being off by a a few tenths of a second.

I am using Photo cell (CdS photoresistor) for my project.

I have looked online and haven't seen a similar project. I want to be able to display the time difference on a lcd.

I have my lcd up and running but I'm not sure how to code the time difference. My photoresistors are connected to A0 and A1 and I am using digital pins 7-12 for the lcd. If anyone has any advice that would be very appreciated!

I'm sure I missed something so ask any clarifying questions

# Answer
> 1 votes
You are asking about

> the time difference between two photoresistors

This, to start with, makes little sense. Photoresistors are analog devices. Their resistance, and thus the voltage you measure, is a continuously varying quantity. The first thing you have to do is to turn them into logic (i.e. either “off” or “on”) devices. The simplest approach is to compare your analog reading to a threshold:

* if the reading is above the threshold, you will say LDR is in the `HIGH` state
* if it is below the threshold, the LDR is in the `LOW` state.

There is a problem with this simple approach though: when the reading is close to the threshold, the ambient noise can make many spurious transitions between `LOW` and `HIGH`. The simplest solution is to have not one, but *two* thresholds. This is called “hysteresis” and is something you definitely should have whenever you are using thresholds against analog readings. This can be coded as follows:

```
const int THRESHOLD_LOW  = 400;  // dummy value
const int THRESHOLD_HIGH = 600;  // dummy value

int HystereticRead(uint8_t pin, int previousState)
{
    int reading = analogRead(pin);
    if (previousState == LOW && reading >= THRESHOLD_HIGH) {
        return HIGH;
    } else if (previousState == HIGH && reading < THRESHOLD_LOW) {
        return LOW;
    } else {
        return previousState;
    }
}

```

Obviously, the thresholds you will use will not be these dummy values: you will determine them from experiment.

Next thing is to record transitions. You do not want to look for a particular state of the LDR, but for the moment it moves from one state (say `LOW`) to the other. This is done by comparing the new state you read to the previous one, as in:

```
static int state0;  // state of the LDR 0
int new_state = HystereticRead(A0, state0);
if (state0 == LOW && new_state == HIGH) {
    // LDR 0 went from LOW to HIGH.
}
state0 = new_state;  // save for next time

```

Last thing, and really the simplest, is to record times. You just have to call `millis()` to get a timestamp, and compute a difference between timestamps to get a duration in milliseconds. Here is how you could write it:

```
void loop()
{
    static int state0, state1;  // states of the LDRs
    static uint32_t time0;      // last time LDR 0 went HIGH

    // Check for LDR 0 going HIGH.
    int new_state = HystereticRead(A0, state0);
    if (state0 == LOW && new_state == HIGH) {
        time0 = millis();
    }
    state0 = new_state;

    // Check for LDR 1 going HIGH.
    new_state = HystereticRead(A1, state1);
    if (state1 == LOW && new_state == HIGH) {
        uint32_t time1 = millis();
        Serial.print(time1 - time0);
        Serial.println(" ms");
    }
    state1 = new_state;
}

```

# Answer
> 1 votes
The most accurate approach is via In out capture on your timer.

Alternatively you can use an interrupt to start and stop the timer.

The worst approach is to poll

However, phtoresistors are slow and generally inconsistent. This can lead to errors in reading. S phototransistor or diode works better.

Edit: it is crazy to try to read the signal in analog. Instead design the circuitry so that it breaches the digital low or high thresholds so you can use digitalRead instead.

You can simply use millis or micros to time stamp the events and calculate the difference.

If you want more precise timing measurements, Google ticks implementation.

edit 2:

here is what I tried:

```
if (dtime_running==0) {             //event 1 has not arrived
    if (EVENT_ON(EVENT1_PIN)) {     //event 1 has arrived
        dtime = time_now();         //time stamp the event
        dtime_available = 0;        //data not yet available
        dtime_running = 1;          //time measurement running
    }
} else {                            //event 1 has arrived and now wait for event 2
    if (EVENT_ON(EVENT2_PIN)) {     //and event 2 has arrived
        dtime = time_now() - dtime; //calculate the timing difference
        dtime_available = 1;        //data now available
        dtime_running = 0;          //stop taking measurement
    }
}

```

On two pulses that are 500ms apart, here is the measurement:

Notice that in the box on the upper right, dtime has a value of 500, just as we expected.

the risk with this approach is that if the loop has other tasks, jitters to the measurement will show up. but for slow events, or long time measurements, it may not matter that much.

# Answer
> 0 votes
I assume you want to measure the difference in time between drops or a change in the resistance of the photo resistors?

Measure every x ms the values of the photo resistors. You can use a sleep for this (or maybe you can just continuously measure).

You have to store the measurements probably, to calculate, when a signal is changing. Also you have to store the times.

E.g.

```
      Resistor 1    Resistor 2
 0 ms          10            20
10 ms          10            20
20 ms          30           600     Drop at resistor 2
30 ms          30           620     Drop at resistor 2
40 ms          45            20     Drop passed resistor 2
50 ms         400            20     Drop arrived at resistor 1

```

So you know that the drop (delay) is 50 - 20 = 30 ms

You have to make an algorithm that will see this change, and also you might have to take into account multiple drops (so counting of drops/signal changes).

---
Tags: arduino-uno, photoresistor
---


title: Echo from device not matching input

text:
# Question
Title: Echo from device not matching input
I'm writing a char array to a device with an arduino mega that should be giving me an echo back, instead, I'm getting an array back with different chars that correspond to my sent function, but not in a way I can figure out. for example `{1,6,250,0,91,233,252}` returns the array `{127,62,1,146,90,0,0}` As 1 is always returning 127, I'm guessing it has something to to with how I'm casting my received data, but after messing with it for a few hours, I can't seem to get it to cast correctly.

# Main Function

gets destination address and data, echos back if requested

calls **CRC**(this works fine) and **SkRead**(the problem area)

```
void Create_Message(int Address, int Data, bool echo)
{
  lcd.setCursor(0,1);
  lcd.print(Address);
  lcd.print(" ");
  lcd.print(Data);
  Address--;
  byte SvAdd = 1;
  byte FuCode = 6;
  byte AddHi = Address>>8;
  byte AddLo = Address;
  byte DatHi = Data>>8;
  byte DatLo = Data;
  byte AdDa[] = {SvAdd,FuCode,AddHi,AddLo,DatHi,DatLo};
  uint16_t crc=CRC(AdDa,sizeof(AdDa)/sizeof(AdDa[0]));
  byte CrcHi = crc >> 8;
  byte CrcLo = crc & 0xFF;
  /*U8 Slave Address, U8, Function Code, U16 Address, U16 Data, U16 CRC
  * to
  *[U8 Address Split High, U8 Address Split Low, U8 Data Split High, U8 Data Split Low, U8 Function Code]
  */
  unsigned char cmd[8]={SvAdd,FuCode,AddHi,AddLo,DatHi,DatLo,CrcLo,CrcHi};
  for (int i=0; i< 8; i++)
  {
  Serial1.write(cmd[i]);   // Send string
  if(echo){Serial.print(cmd[i]);Serial.print('.');}
  }
  if(echo){Serial.println();}
  if (SkRead(echo) == cmd)
  {
  Serial.print(Address);
  Serial.print('\t');
  Serial.println(Data);
  }
  //clear line
}

```

---

# CRC

(works fine, just wanted to show full code)

```
/*---Create CRC Function---*/
uint16_t CRC(byte AdDa[], int Size )
{
  uint16_t crc16 = 0xFFFF;
  int pos = 0;
  int i = 0;
  /*Write CRC*/
  for (pos = 0; pos < Size; pos++)
  {
    crc16 ^= AdDa[pos];          // XOR byte into least sig. byte of crc
    for (i = 8; i!= 0; i--) // Loop over each bit
    {
      if ((crc16 & 0x0001) != 0)        // If the LSB is set
      {
        crc16 >>= 1;                      // Shift right and XOR 0xA001
        crc16 ^= 0xA001;
      }
      else
      {
        crc16 >>= 1;                      // Shift right
      }
    }
  }
  /*Note, this number has low and high bytes swapped,
  so use it accordingly (or swap bytes)*/
  return crc16;
}

```

---

# SkRead

This is my problem area, I'm sure the data is being sent and read correctly, but one of my assignments is throwing it off so the received echo is not received in a way that matches what is sent.

```
unsigned char SkRead(bool echo)
{
  digitalWrite(Pin13LED, HIGH);  // Show activity
  outputstring = "";
  unsigned long bide=millis()+2000;
  byte inChar;
  while(Serial1.available()<8 && bide>millis()){}
  while(Serial1.available())
  {
    inChar = (byte)Serial1.read();
    outputstring += (char)inChar;
  }
  //Serial.println(outputstring);
  digitalWrite(Pin13LED, LOW);  // Show activity
  int charl = outputstring.length() + 1;
  unsigned char outputschar[charl];
  outputstring.toCharArray(outputschar,charl);
  if (echo)
  {
    for (int i=0; i< charl; i++)
    {
     Serial.print(outputschar[i]);
     Serial.print('.');
    }
    Serial.println();
  }
  return outputschar;
}

```

# Answer
I don't know where to start.

* You did not provide a full sketch. There is, for example, no Serial.begin1() in sight.
* You did not provide enough information about the device. If you don't want to tell us what it is, then give an indication of its age. In the 1980's it was common to have 7E1 format (7 data bits, even parity, 1 stop bit).
* You have to be sure what the baudrate is. To detect a wrong baudrate, you need a oscilloscope or logic analyzer. When the device has a processor and the baudrate is derived from it's clock, the baudrate could be different from the specified baudrate by a few percentage. That is already a problem with the Arduino.
* It could be a problem with inverse voltage levels. What does the device use as idle and as active level ? The Arduino Mega uses +5V at the TX pin when idle, and low is active. That means that the TX pin is normally high, and the first low pulse is the start bit.
* The device could return an error code instead of an echo.
* Your SkRead function can be improved:
* Using a String object to collect the incoming data and after that converting the String object to a unsigned char array to use it, is not the most elegant solution. You could just use a unsigned char array to read the incoming data.
* It is not okay to add something to the millis value. That is a problem when millis does a rollover (after 50 days or so).
* Normally a character is read as soon as it is available. You wait until 8 characters are in a buffer. No one else does that.

To solve this puzzle you need more information. Try to capture the RX and TX signals with a oscilloscope or logic analyzer. Or else try to write a very small sketch that creates the problem.

My best guess is that it is not your sketch, but perhaps a combination of inverse levels, parity and baudrate.

\[**ADDED**\]
After writing down the bits over the serial bus, it might indeed be inverse voltage levels and maybe something with 7 bits or parity. That would also explain the last bytes to be 255. Those 255 are not valid data.
> 1 votes

---
Tags: serial, programming, communication
---


title: Powering my Arduino Mega project

text:
# Question
Title: Powering my Arduino Mega project
What power source should I use for my Arduino Mega project (involves 2 steppers, 2 servos and 2 dc motors)?

I tried to run two stepper motors with 9V battery. But the battery dried out. I am thinking of 8 AAA batteries. Is there a better option? How about powering through Arduino with the help of a DC adapter?

# Answer
To properly answer this, you first have to determine how long you want your application to be able to run on a full charge. Clearly, it'll run on a 9V battery, but not for very long.

To determine the appropriate power supply, you need to calculate the overall voltage and current requirements for the various components.

The Mega needs a pretty minimal power supply, just 5V @ 200mA.

You don't specify the ratings for your motors. Servos are typically 5-6V @ 500mA, but I'm only guessing. Steppers and DC motors vary quite a lot.

The first step would be to find the specifications for all your motors, and find the maximum values, specifically the operating voltage and stall current. Hypothetically, say the maximum voltage for all the motors is 5V, and the stall currents for the steppers, servos and DC motors are 1A, 1A, 500mA, 500mA, 3A, and 3A respectfully. (Again, this is just an example. Find the true values yourself). That means you'll need a supply that can safely deliver 1+1+0.5+0.5+3+3+0.1 = 9.1A @ 5V or 45.5 watts.

If you want to use a battery (instead of a stationary supply like a DC adapter), you'll need to chose a battery with adequate mAh rating, which is the total number of amps it can deliver in 1 hour.

Perfectly predicting battery life greatly depends on the battery chemistry and your application's average current draw, both of which great very complicated, so I won't go into that here. A battery is considered effectively "dead" when it's depleted to around 80% of it's fully charged voltage. You can lookup the formulas and do the math yourself, or you can use some online calculators to help you estimate discharge times for different battery and load configurations.

However, as a general rule of thumb, you want to select a battery with a voltage greater than the minimum voltage required by any of your components. For your application to run for 1 hour, it's mAh rating should also be greater than your application's total current consumption. To run longer, you'll need to find a battery with a higher mAh rating, or higher voltage that a switching regulator can use to convert that extra voltage into current.

The other important factor, which complicates these calculations, is the type of voltage regulators you use. If you want to power everything from a single battery, you'll definitely need some voltage regulators. Preferably, you should use high-efficiency switching regulators. For this purpose, you can find cheap UBECs used for RC applications on Amazon or Ebay. You should have one for the Arduino and each motor (or pair of motors if you want to save on cost or complexity). Just make sure the regulator's voltage and current requirements are greater than what's consumed by your components.

I find using 2 or 3 Lipo batteries in series, especially 18650 cells, are the cheapest and easiest way to provide power for mobile applications that have high spikes due to motors. For stationary applications, a 12V DC wall adapter with a high current rating would be simpler.

If you want to use akalines, I'd recommend using separate batteries for the Arduino and motors. Akalines aren't well known for being able to deliver high current. Motors can demand a lot of current, and if the battery can't deliver enough, it'll cause the voltage to drop, resulting in the Arduino browning-out. However, lipo batteries, or non-rechargeable lithium batteries are better suited for this.
> 0 votes

---
Tags: arduino-mega, power
---


# Question
Title: Do all arducam need the "Arducam-F Shield"?
*The information on this is so greatly lacking to the extent that no related youtube videos could be found, no internet material and the seller seems to be very important and not answer to my questions as he is supposed to. Also he appears to be the only seller to offer such a variety of arduino cameras.*

---

I want to choose colored arduino camera for my project, but I am unable to receive enough information so that I can choose the appropriate arduino camera.

The most important for me to know is does all arduino cameras need the arducam-f shield board in order to work properly (i.e be programmable, colored, with "decent" quality and be able to capture photos in less than 1~2 seconds)

---

1. This is "5MP Mega pixel OV5642 Sensor Camera Module w CS mount Lens" It costs US $29.99. The description doesn't mention the need of any other 3rd party hadware in order to work.

2. This bellow is "Arducam-F Shield V2 Camera module shield /w OV2640 for Arduino UNO MEGA2560 DUE" it costs US $29.99 and is a camera that evidently comes with this magical shield. We can see that the version is slightly older than that on the other cameras.

3. This is "2 Mega pixel Camera Module MT9D111 JPEG Out + HQ lens" for US $21.99 and also, like in any other description, the need of shields is not mentioned

4. And this is "2Megapixel MT9D111 Auto Focus lens camera flex module with Adpater board" that has autofocus, is 2MP like the one above, comes with .... ?Adapter board"? (nothing like that is shown in the pictures or described in the description) and costs only US $9.99. It looks ugly compared to other cameras.

---

These was the 4 example arduino cameras I would choose from and do all of them need arduino shields in order to do what a camera should do? (Explaining differences, pros and cons will be very useful to everyone who are in the same boat as I am)

# Answer
> 3 votes
You have three requirements:

* Good quality (colour)
* High resolution
* Fast operation

Those three requirements together mean you cannot use a normal Arduino.

1. The Arduino has nether the memory nor processing power to directly communicate with a camera module.
2. The ones you can communicate with have internal buffer memory and use a slow UART interface to transfer a frame. That is not fast.
3. The Arduino cannot deal with a large picture regardless of speed. All you can do is pass the image through to somewhere else for processing. Slowly.

So you can either have very low resolution or slow speed.

So use a Raspberry Pi or something similar which is more capable of using a camera (indeed, the Pi has a dedicated camera connection).

---
Tags: arduino-uno, shields
---


# Question
Title: Can I run arduino on Windows Embedded Compact 2013?
I'm actually working on a robotic project for which I'm planning to use arduino to drive the wheels.For this, I want to send signals from my Onboard embedded computer (which has Windows Embedded Compact 2013 OS) to arduino. Is this possible? If not possible, what are the other alternatives?

# Answer
> 1 votes
What OS is running on two different devices exchanging messages/signals, does not matter. What matters is the protocol.

You can use a lot of different ones:

* Wireless:
    + IR (infrared)
    + RF (radio), like 433 MHz, 2.4 GHz
    + WIFI (internet)
    + Bluetooth
* Wired
    + SPI
    + 'simple wires' / Wire library
    + Serial
    + USB (not on most Arduinos)

This list is not complete, just some examples.

Arduino supports all above (except USB fully), I don't know what Windows Embedded Compact OS supports.

---
Tags: arduino-uno, programming, robotics, software, windows
---


title: Using PBC library on Arduino

text:
# Question
Title: Using PBC library on Arduino
I want to know if there is a way to install/use the PBC library on Arduino UNO. I want to implement some cryptographic primitives using PBC library.

Thank you.

# Answer
You could use the RELIC toolkit. It has PCB and they have scripts to compile for Due and Mega. I'm not sure if you could use this with Uno. But this library targets resource-constrained devices.
> 1 votes

---
Tags: arduino-uno, library, c
---


title: Understanding bitwise operations

text:
# Question
Title: Understanding bitwise operations
I am wondering what the second line of code does:

```
int16_t GyX;
GyX=Wire.read()<<8|Wire.read();

```

Also, how can I write the GyX value to EEPROM?

From what I understand, int16\_t is a two-bytes value. The Wire.read() returns a single byte. The \<\<8 shifts the bits by one byte to the left in order to read the higher order bits, and the last part writes the next wire read (lower order bits). Basically, reads wire twice and stores those values in the int. Is that correct?

For the writing, would

```
EEPROM.write(addr, GyX >> 8);
EEPROM.write(addr, GyX & 0xff);

```

do the trick? (First line records the higher order bits, while second records the lower order ones)

# Answer
@PetioPetrov, Arduino has macros to make it easier: highByte, lowByte, and word.

You don't have to split and combine bytes and words. The EEPROM.put and EEPROM.get can write and read two bytes if you want to. It's all documented in the reference of EEPROM.

There is a lot going on in this piece of code:

```
int16_t GyX;
GyX=Wire.read()<<8|Wire.read();

```

Shifting a single byte 8 bits to the left would be wrong. However, the Wire.read returns an integer and the GyX is an integer. Therefor the compiler uses integers for everything and shifting 8 bits to the left is valid.
At this moment with the current Arduino and avr-gcc compiler version, it will call the Wire.read for the high byte first and then the Wire.read for the low byte. That is **pure luck** as @EdgarBonet has corrected me below. In the c++ language there is no specified order of calling functions.
The bitwise 'OR' with the '|' could be a problem when there was no data and -1 was returned by Wire.read.
> 0 votes

# Answer
> `GyX=Wire.read()<<8|Wire.read();`

This is a bug. It reads two bytes from the I2C bus and builds a 16-bit number from them. One of the bytes (we don't know which one) will be the most significant byte of the result. The other byte will be the least significant byte.

This instruction is likely to work just fine on some particular version of some particular compiler with some particular compiler options. Presumably it did work for the author. But you should not expect it to work consistently across compilers, or even across different versions of the same compiler.

The proper way to do this is to perform the two reads in different instructions:

```
GyX = (uint16_t) Wire.read() << 8;
GyX |= Wire.read();

```

assuming the bytes come most-significant first.

**Edit**: added `(uint16_t)` cast. C.f. this answer.
> 2 votes

---
Tags: eeprom, bit
---


# Question
Title: Is the ShiftOut tutorial on the official Arduino website really wrong regarding the capacitor?
I'm talking about this tutorial "Serial to Parallel Shifting-Out with a 74HC595" from the official Arduino website. It provides the following schematic:

I've read a couple of times now, that the placement of the capacitor is wrong:

> This is a well known shit tutorial which for some unknown reason they refuse to fix. That capacitor should be connected between the Vcc pin and ground, NOT the latch pin.

Source: forum.arduino cc/index.php?topic=408135.0

They recommend this placement:

Who's right? Please explain where to place the capacitor. Can the arduino even be damaged?

# Answer
> 2 votes
That tutorial, as with a number on the Arduino site, is wrong.

Yes, the capacitor should be across Vcc/GND - it is a decoupling capacitor used to absorb the current surges when you turn LEDs on and off.

Not to mention that with that circuit if you turn on all the LEDs you are overloading the 74HC595. That has a maximum 70mA through Vcc/GND pins. Each LED there (assuming red LEDs at 2V forward voltage) will be drawing about 13.6mA. 8 LEDs would be 8\*13.6 = 109mA.

Ouch.

The problem with many of the Arduino tutorials is they were written in the early days of Arduino when they didn't have much knowledge and experience. Since then the arduinosphere has grown and there are people now with far more knowledge and experience than Arduino had at the time the tutorials were written. We come here.

# Answer
> 1 votes
You can figure out the impedance of that capacitor for high frequency signal....

What they have there is really a low pass filter.

Terrible ideal to out that big of a capacitor there.

# Answer
> 1 votes
You do not need a capacitor to use the 74HC595 in conjunction with `shiftOut()`. I found this YouTube video to be very useful in explaining how to wire up and code the shift-register for a 7-segment display.

# Answer
> 1 votes
Indeed, it seems like the Arduino tutorial is wrong. I just found the following schematic in Datasheet SN74HC595 - Texas Instruments from `10.2 Typical Application`, `Figure 5`:

The capacitor connects VCC to GND. Nothing to do with the latch pin.

---
Tags: shift-register, capacitors
---


# Question
Title: Are the output pins on the 74HC595 shift register protected against shorting?
In the following schematic you can see that `Q1` and `Q4` both are connected to a Arduino's Digital Input Pin. So if `Q1` is high and `Q4` is low, would there be current flowing from `Q1` through `Q4` (and through the chip) to Ground - or is there already some protection inside?

Are the output pins on the 74HC595 shift register protected from connected voltages in the realms of their own VCC? Or do you need to put a diode in?

I feel like this is a very basic question, which makes it very weird that I didn't find an answer to this, already... :-( Am I looking into the wrong resources? I had a look into the provided datasheet, but couldn't find any information. Didn't get any results from searching for existing posts on Stack Exchange or other sites.

# Answer
In this data sheet it says:

> When the output-enable (OE) input is high,the outputs are in the high-impedance state.

However on page 3 you will notice that the \*OE pin controls all outputs at the same time. So if you connect 2 output pins and one is high and the other is low and you hold \*OE low ... you will likely burn out the driver for one of the 2 output pins if not the chip its self.

If you add diodes to BOTH outputs you are essentially creating a wired or gate. (You should add a resistor. See the examples in the provided link.) This is fine as long as you understand how a wired or gate works.
> 4 votes

---
Tags: shift-register, voltage-protection
---


# Question
Title: I want to control a single DC motor with an Arduino. Why would I use an Arduino motor shield as opposed to an H-circuit and a MOSFET?
I'm new to electronics. I'm trying to build something that will involve controlling the direction of rotation of a DC motor. A lot of online resources seem to recommend using an Arduino motor shield. But why shouldn't I just use some combination of an H-circuit (to control the direction of rotation) and a MOSFET (to switch power to the motor on and off)?

# Answer
> 3 votes
The major benefit to using a shield vs building the same circuit yourself is convenience. Assuming that your circuit is identical to the circuit on the shield then they should both work in an identical manner (barring any minor variations due to the quality of solder joints or circuit paths). The nice thing about the shield is it is almost plug and play. It has the same footprint as the Arduino and you don't have to design and assemble the circuit on a perf board. Generally, you will end up with fewer wire leads running around making for a cleaner assembly and easier prototyping.

# Answer
> 1 votes
A Arduino motor shield **is** just a H-bridge (plus some other bits), but it's a H-bridge that works.

Drawing a H-bridge and a MOSFET is easy. Building one that works is much harder. Online resources recommend the shield because trying to walk someone through the development of a functional equivalent is complex.

---
Tags: mosfet, motor
---


title: Convert Bitstring to Textstring

text:
# Question
Title: Convert Bitstring to Textstring
I have an Arduino Uno which is going to receive a long binary string. I know that this string will correspond to English when decoded. How can I convert the incoming binary string to text, so that I can read it in the Serial Monitor?

Bonus Points: This string will almost definitely have random noise digits. How would I noise-proof the string, or how could I have the code detect and ignore noise?

UPDATE: It might help if I mention my end goal. So I have this contained clean space that is locked up to avoid contamination. It is quite small, and used for growing silicon crystals. I want to be able to take a greyscale image every hour, and transmit it to a receiver on the other end of the room, through a window. The window is two half inch panes of glass with an inch of space between them. I have on hand 2x Arduino Uno, 1x Arduino Beetle, and 1x Raspberry Pi. The whole text string thing is just for testing purposes so that I can understand what I'm doing. From what I've read on the subject previously, I need to take the image, convert it to Hex, convert that to binary, transmit it, receive it, convert back to Hex, convert back to an image. I have 0 experience with Arduino or Raspberry, have a limited idea of how to execute this, and appreciate all the help I can get!

# Answer
> 1 votes
Perhaps you have asked the wrong question. Because there is a library for those cheap 433MHz modules: RadioHead.
Use the RH\_ASK mode, and try the 'ask' examples

You might see VirtualWire used a lot with those 433MHz modules. That is the same as RadioHead. The RadioHead is newer and has a few bugs fixed, but it uses also more memory.

The RadioHead library uses a far more superior protocol than anything else, that makes the range better than with other libraries. It also has a (simple) CRC checksum in the protocol. That means that when you receive something, you can be (almost 100%) sure that the data is correct.

Other protocols require that a message is transmitted 10 times, to be sure that it will be received. With the RadioHead library, sending a message just once is good enough.

Those cheap 433MHz modules have a disadvantage: they can only be turned on and off (ASK modulation) en you need a library for the protocol. That means that if the Arduino is doing more things that uses interrupts or code that disables interrupts, then the protocol is disturbed and it will not work very well.
The RF transceiver modules have a chip on the module itself that takes care of the protocol, that is so much better. Sparkfun has a Wireless Buying Guide and Adafruit uses the RFM69 a lot.

Those cheap modules require an antenna, or else the range could be less than the size of the table they are on. Solder a 16cm piece of wire to the antenna pin. Any piece of wire of any length is better than no antenna.

# Answer
> 0 votes
A string is also a 8-bit 'binary' string ... so I don't think you need to do anything special... if you can read byte by byte, you might have to construct a string adding the characters, or print it directly to the serial monitor (last is even better because you don't have to think about memory).

If the 8-bit binary string does not contain ASCII data (which I doubt), print out the byte values as number and see how it should be converted to a textual character.

Noise is a bit more tricky .. afaik it is possible with some libraries (for the RF) to automatically resend. If that is not good enough, you have to make your own CRC ... calculate a CRC, send it (maybe a few times to be sure there is no noise in the CRC) and check it against the received string; if not received correctly, send it again.

If you have only 1 directional transmitting, than it is more tricky. You can add extra bits to 'fix' noise, or using special schemes for it.

See for more info wikipedia

---
Tags: arduino-uno, programming, string
---


# Question
Title: Arduino Ethernet shield cannot establish connection
I bought a Chipdot Ethernet shield from Amazon. It does not have any MAC address on it. I connected this shield to an Arduino Uno. I tried to run the `DHCPAdressPrinter` code from Ethernet library on it, using the default MAC address of this code. And Serial monitor shows

> Failed to configure Ethernet using DHCP

I have tried all the MAC IDs one by one as suggested on reviews but nothing worked. Is there any way to configure or assign a MAC ID to the Ethernet shield? Or is there are any way to know the Ethernet shield's MAC address?

Thanks in advance.

# Answer
The W5100 chip doesn't have a mac address by itself. You can assign any mac address to it that you want. With `Ethernet.begin(mac);` you assign the mac address to the W5100 chip.
The official Arduino Ethernet shield comes with a paper with a unique mac address. That is a nice service, but that is just a number, the Ethernet shield hardware is without any mac address.

There has been complaints about wrong resistor values near the ethernet connector. Can you read the numbers on those resistors ? They should be labeled as "510" and not as "511" : Arduino forum about ethernet resistors.

The Ethernet Shield uses more power than most other shields, and the W5100 can get pretty hot. Do you have enough power ? Is the 5V pin still above 4.5V ?

It is possible that your router does not accept the old W5100.

If the resistors are okay, I suggest to try an example with both mac and ip: `Ethernet.begin(mac, ip);`
> 1 votes

---
Tags: arduino-uno, ethernet, ethernet-shield
---


# Question
Title: Problems with ACS758 Hall Effect Current Sensors - Calibration and no Signal
I purchased 3 ACS758 Hall Effect Current Sensors datasheet on ebay. A 50,100 and 200A, all three are bi-directional. They look like this.

With **no** current the 50A outputs 477 on the analogue input (2.33v), the 100A outputs 509 (2.48v) and the 200A outputs 512 (2.50v). At no current they should all be at exactly mid range i.e. 512 (2.50v). The datasheet says they're factory calibrated as such. I've tested them one after the other, both with 5v from the Audrino and with a separate 5v supply. As I've tested one after the other it's not likely to be stray magnetism or VCC.

I've then put them in a circuit drawing about 9amps. Accounting for the offset of zero amps the 50A and 100A measured the increased voltage correctly. The 200A doesn't change.

Is there any other tests I can do to see if I'm doing something dumb or are they all damaged?

# Answer
> 0 votes
I contacted Allegro they were really helpful which was pleasantly surprising.

The 200A has almost certainly failed. The 2.48v is within tolerance and the 2.33v is probably out.

I've been able to better understand the datasheet sections on 0A calibration. "VIOUT(Q) may drift over the lifetime of the device by as much as ±25 mV." and there is an electrical offset voltage noted. @25C it's +/-5mv. It's +/-20mv between 0c and 50c. So still only 45mv. Even allowing for noise it's only 55mv.

About 2.445V at zero amps would be the limit.

---
Tags: analogread, voltage-level, current, calibration
---


title: Reading force from an FSR in Newtons

text:
# Question
Title: Reading force from an FSR in Newtons
I hope I'm in the right place to ask, I couldn't find anything so I ask here, please tell me if I missed some relative topic.

I was following this tutorial : https://learn.adafruit.com/force-sensitive-resistor-fsr/using-an-fsr#in-depth-code-for-analog-fsr-measurements and the only difference is that I have a potentiometer instead of a 900K resistor. I put it to 14350 Ohms because it fits the tutorial just above the last one, on top of the same page. So here is the thing : I want to know the force in Newtons but the values I end up with are clearly wrong. A medium touch on the FSR is already \> 3 Newtons, and it changes a lot when I turn the potentiometer to a higher resistance (and changing the value of that pota in the code too) : same force applied, different value of that force on the screen.

I know nothing about elecs so I would also like to know more about this part :

```
// Use the two FSR guide graphs to approximate the force
if (fsrConductance <= 1000) {
  fsrForce = fsrConductance / 80;
  Serial.print("Force in Newtons: ");
  Serial.println(fsrForce);
} else {
  fsrForce = fsrConductance - 1000;
  fsrForce /= 30;
  Serial.print("Force in Newtons: ");
  Serial.println(fsrForce);
}

```

Where does the /80 and -1000 then /30 come from ? Why is it a different operation and not just only different values ? I'm using the same FSR but with 3.3V. I have the same graph as this one : https://learn.adafruit.com/force-sensitive-resistor-fsr/overview#how-to-measure-force-slash-pressure-with-an-fsr

I would really appreciate clear and simple explanations. Thank you by advance !

# Answer
Sparkfun also sells FSR's and they explain it better: "Use them to sense if it’s being squeezed, but you may not want to use it as a scale".

On that Sparkfun page is also a datasheet. It's inaccuracy is 25%, and that is only when the force is applied evenly. When someone presses it with a finger, the inaccuracy is 50% or more.

The quick-and-dirty calculation in the Adafruit example is just for fun, it is not serious measuring the force in Newton.
There are two different calculations, for 'fsrConductance' above and below 1000. When it is above 1000, the 1000 offset is substracted to start the calculation at zero. The difference in calculation is that for one the value is divided by 80 and in the other divided by 30. It's just a rough calculation to get some kind of force value.

To measure weight or force, you need a **load cell**.
> 2 votes

---
Tags: sensors
---


# Question
Title: Not able to get response from esp using Arduino uno
I am new to Arduino & ESP modules, here am trying to communicate with ESP-01 via Arduino UNO. I have gone through multiple websites for initial setup. But when i upload my code to UNO, ESP is not responding back.Below is the code i have used.

```
#include<SoftwareSerial.h>
SoftwareSerial ESP(0,1); // RX, TX
//ESP RX-->1(UNO) TX-->0(UNO)

void setup() {
// Open serial communications and wait for port to open:

    Serial.begin(9600);
    while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
    }

   // Serial.println("Goodnight moon!");

    // set the data rate for the SoftwareSerial port
    ESP.begin(9600);

}

void loop() {
      ESP.write("AT\r\n"); //Normally ESP responds to AT command with "OK"
    while (ESP.available()) {
        char inData = ESP.read();
        Serial.println("Got reponse from ESP8266: ");
        Serial.write(inData);
    }

}

```

Source: Link of the url

My observation on this is

1. ESP is blinking blue light when i reset UNO
2. UNO TX onboard LED is blinking
3. when i am trying to do `Serial.println("Goodnight moon!");` it is printing
4. `Serial.println("Got reponse from ESP8266: "); Serial.write(inData);` is not printing

My questions are:

1. Is there any need to flash ESP with Firmware or is it default enabled.(i have 3 esp's with me all of them not responding with above code)
2. If no need then what is the possible mistake i am doing.

Here is the screenshot https://i.stack.imgur.com/mOklg.png

Note: I haven't used breadboard for connection, directly connected UNO-TX -\> ESP RX and UNO-RX -\> ESP TX, 3.3v VCC and ground.In the above screenshot on upload nothing prints, only when i type something "Got reponse from ESP8266: " is printing

# Answer
Hi all i found out the solution after a long struggle. issue was with the ch\_pd as per the ESP documentation ch\_pd has to be active high that means it has to get 3.3v, only then it will communicate.

soon after that all my problems got cleared.thank you
> 1 votes

# Answer
There's a good chance your ESP and SoftwareSerial baud rates are not matched. The last handful of ESP-01s I bought came with default baud rates 115200. You may need to change yours to 9600 baud to use with SoftwareSerial. See my answer to a similar question.

Update:

> tried all the available baud rates....!!Still the same issue..

Three possible issues come to mind:

1. Your terminal program must be at the same baud rate you set the ESP to.
2. SoftwareSerial is pretty much limited to a max of 9600 baud, although it can usually transmit successfully at 115200.
3. The serial connections must be cross-wired - Rx-\>Tx and Tx-\>Rx.

I think you had addressed 3) when you were trying to use pins 0 & 1, at least, as I read your comments. Together, 1) and 2) mean you'll need to use SS at 115200 to change the ESP's baud rate to 9600, then change SS to 9600 to carry on any further.

Also try moving the `ESP.write("AT\r\n");` command to the setup() function. As your code is written, anytime the while loop finds no character waiting, the while loop will end and the loop() function will exit and restart, sending a new command to the ESP. Your code might never get a chance to print anything at all.
> 0 votes

# Answer
```
SoftwareSerial ESP(0,1); // RX, TX

```

Pins 0 and 1 are hardware serial on the Uno, used with the Serial object, these pins are used to communicate with your computer (e.g. Serial Monitor) via the USB-serial chip on the Uno.

There is absolutely no reason you should ever use SoftwareSerial with pins 0 and 1. If you want to use software serial then connect the ESP8266 to pins other than 0 and 1. Otherwise don't use SoftwareSerial at all, but be aware that using Serial to communicate with the ESP8266 and with the computer is problematic and can also cause issues when you try to upload to your Uno.
> 0 votes

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