body:
I would like to use 652 unsigned long values on an Arduino Uno, but it doesn't look like there's enough memory. I thought about the splitting unsigned long values to 3 unsigned chars to store in PROGMEM which I can letter recall and join as unsigned long as needed.

I'm not super experienced with byte manipulations and I got myself stuck when trying to merge the data. When I try with one variable at a time, I get the expected output. The part I'm confused about is why do I get different values when using a variable as an array index for each value ? How can I fix this ?

Here's my test code so far:

    #include <avr/pgmspace.h>
    #include "flashData.h"

    void setup() {
      Serial.begin(115200);
      unsigned long fromPROGMEM = (onsets1[0] << 16) | (onsets2[0] << 8) | onsets3[0];
      Serial.println(fromPROGMEM);

      unsigned long fromValues = (0x00 << 16) | (0x01 << 8) | 0xF3;
      Serial.println(fromValues);

      byte b1 = 0x00;
      byte b2 = 0x01;
      byte b3 = 0xF3;

      unsigned long fromBytes = (b1 << 16) | (b2 << 8) | b3;

      Serial.println(fromBytes);
      delay(2000);

      unsigned char c1,c2,c3;
      unsigned long value;

      Serial.println("data using same index:");
      for(int i = 0 ; i < 10; i++){
        c1 = onsets1[3];
        c2 = onsets2[3];
        c3 = onsets3[3];
        value = (c1 << 16) | (c2 << 8) | c3;
        Serial.print("index: ");
        Serial.print(i);
        Serial.print("\tvalue:");
        Serial.println (value);
        delay(10);
      }

      Serial.println("data using counter:");
      for(int i = 0 ; i < 10; i++){
        c1 = onsets1[i];
        c2 = onsets2[i];
        c3 = onsets3[i];
        value = (c1 << 16) | (c2 << 8) | c3;
        Serial.print("index: ");
        Serial.print(i);
        Serial.print("\tvalue:");
        Serial.println (value);
        delay(10);
      }
    }

    void loop() {

    }

and flashData.h:

    #ifndef _flashData_h_
    #define _flashData_h_

    static PROGMEM const unsigned char onsets1[652] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03};
    static PROGMEM const unsigned char onsets2[652] = {0x01,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x25,0x26,0x28,0x29,0x2A,0x2B,0x2C,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,0x38,0x39,0x3A,0x3B,0x3C,0x3F,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x48,0x49,0x4A,0x4C,0x4D,0x4E,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x59,0x5A,0x5B,0x5C,0x5E,0x5F,0x61,0x63,0x64,0x65,0x67,0x6A,0x6B,0x6C,0x6D,0x6E,0x70,0x71,0x73,0x75,0x76,0x77,0x79,0x7C,0x7E,0x7F,0x80,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9E,0x9F,0xA0,0xA1,0xA2,0xA3,0xA4,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xC0,0xC2,0xC4,0xC6,0xC9,0xCB,0xCD,0xCF,0xD2,0xD4,0xD6,0xD8,0xDA,0xDB,0xDD,0xDF,0xE0,0xE2,0xE4,0xE6,0xE7,0xE8,0xE9,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF4,0xF6,0xF7,0xF8,0xF9,0xFA,0xFD,0xFE,0xFF,0x00,0x01,0x02,0x03,0x06,0x07,0x08,0x0A,0x0D,0x0F,0x10,0x11,0x12,0x13,0x14,0x16,0x18,0x19,0x1A,0x1C,0x1D,0x1F,0x21,0x22,0x23,0x25,0x28,0x2A,0x2B,0x2C,0x2E,0x30,0x31,0x33,0x34,0x35,0x38,0x3C,0x3D,0x3E,0x41,0x42,0x44,0x45,0x46,0x47,0x48,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x53,0x54,0x56,0x57,0x58,0x59,0x5B,0x5C,0x5D,0x5E,0x5F,0x60,0x61,0x63,0x65,0x66,0x67,0x69,0x6A,0x6D,0x6E,0x6F,0x70,0x71,0x72,0x73,0x75,0x77,0x78,0x79,0x7A,0x7B,0x7D,0x7E,0x7F,0x80,0x82,0x84,0x87,0x89,0x8B,0x8E,0x90,0x92,0x94,0x97,0x99,0x9B,0x9D,0xA0,0xA2,0xA4,0xA5,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB9,0xBA,0xBB,0xBD,0xBF,0xC0,0xC2,0xC4,0xC6,0xC7,0xC8,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,0xE2,0xE4,0xE6,0xE8,0xEA,0xEB,0xED,0xEF,0xF1,0xF2,0xF3,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFF,0x01,0x03,0x04,0x05,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x13,0x15,0x16,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x20,0x21,0x23,0x24,0x25,0x27,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x30,0x32,0x33,0x35,0x36,0x37,0x3A,0x3B,0x3C,0x3E,0x40,0x43,0x44,0x45,0x47,0x48,0x49,0x4A,0x4C,0x4D,0x4E,0x50,0x55,0x56,0x57,0x59,0x5A,0x5B,0x5E,0x5F,0x60,0x61,0x62,0x63,0x65,0x66,0x67,0x68,0x69,0x6B,0x6C,0x6F,0x70,0x71,0x72,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B,0x7D,0x7F,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x99,0x9B,0x9D,0x9F,0xA2,0xA4,0xA6,0xA8,0xAB,0xAD,0xAF,0xB1,0xB4,0xB6,0xB7,0xB8,0xBB,0xBD,0xBE,0xBF,0xC0,0xC1,0xC2,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCC,0xCD,0xCE,0xCF,0xD1,0xD3,0xD6,0xD8,0xDA,0xDC,0xDE,0xDF,0xE0,0xE1,0xE3,0xE4,0xE5,0xE7,0xE8,0xE9,0xEA,0xEC,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFE,0x01,0x03,0x04,0x05,0x07,0x09,0x0A,0x0B,0x0C,0x0E,0x10,0x12,0x13,0x14,0x15,0x17,0x18,0x1A,0x1C,0x1E,0x1F,0x20,0x21,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x34,0x35,0x37,0x39,0x3C,0x3E,0x40,0x42,0x43,0x45,0x47,0x49,0x4A,0x4B,0x4C,0x4E,0x50,0x52,0x53,0x54,0x56,0x57,0x58,0x59,0x5B,0x5C,0x5D,0x5F,0x60,0x61,0x62,0x64,0x66,0x68,0x69,0x6B,0x6C,0x6D,0x6E,0x70,0x71,0x72,0x74,0x75,0x76,0x78,0x79,0x7B,0x7C,0x7D,0x7F,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x8A,0x8B,0x8C,0x8D,0x8F,0x90,0x91,0x93,0x94,0x95,0x96,0x97,0x98,0x9B,0x9D,0x9F,0xA1};
    static PROGMEM const unsigned char onsets3[652] = {0xF3,0x31,0x59,0x76,0x98,0xBA,0xDD,0xFF,0x43,0x66,0x88,0xAA,0xC7,0xEF,0x0B,0x2D,0x50,0x72,0x8E,0xB1,0xD3,0xF5,0x17,0x3A,0x5C,0x7E,0xA0,0xC8,0xE5,0x0D,0x29,0x6E,0x90,0xAC,0xD5,0xF7,0x13,0x35,0x58,0x7A,0x9C,0xB9,0xE1,0xFD,0x42,0x6A,0x86,0xA8,0xC5,0x0F,0x31,0x54,0x7C,0x92,0xB5,0xCB,0xF9,0x1B,0x43,0x60,0xA4,0xC1,0xE3,0x28,0x4A,0x72,0x8E,0xB1,0xD3,0xF5,0x17,0x34,0x5C,0x78,0xBD,0xDF,0x01,0x46,0x62,0x84,0xCF,0x0D,0x30,0x52,0x7A,0x91,0xD5,0xF7,0x1A,0x5E,0x86,0xA3,0xE7,0x26,0x5F,0x92,0xAF,0xF3,0x1B,0x32,0x5A,0x7C,0x9F,0xBB,0xE3,0x00,0x28,0x4A,0x66,0x89,0xAB,0xC7,0x0C,0x34,0x4A,0x72,0x95,0xB7,0xD9,0xFB,0x1E,0x3A,0x62,0x7F,0x9B,0xC3,0xE0,0x2A,0x52,0x69,0x91,0xB3,0xD5,0xF7,0x1F,0x36,0x58,0x80,0x9D,0xB9,0xE1,0xF8,0x42,0x65,0x81,0xA9,0xCB,0xE8,0x10,0x54,0x93,0xD2,0x16,0x60,0x9F,0xE4,0x28,0x6D,0xAB,0xF0,0x12,0x34,0x79,0xB2,0xDA,0x02,0x46,0x85,0xAD,0xCF,0xF2,0x0E,0x30,0x4D,0x75,0x97,0xB9,0xD0,0xFE,0x1A,0x65,0x87,0xA3,0xC5,0xE2,0x2C,0x4E,0x6B,0x8D,0xAF,0xD7,0xEE,0x38,0x5B,0x77,0xC1,0x00,0x45,0x67,0x89,0xAB,0xCE,0xF0,0x01,0x57,0x7F,0x95,0xDA,0xFC,0x1E,0x5D,0x7F,0x9C,0xE0,0x25,0x6F,0x91,0xAE,0xF2,0x14,0x3C,0x7B,0x98,0xBA,0x04,0x82,0xAF,0xCC,0x16,0x33,0x77,0x94,0xBC,0xD2,0xFA,0x1D,0x3F,0x61,0x7D,0xA6,0xC8,0xE4,0x29,0x51,0x8F,0xAC,0xCE,0xF0,0x13,0x35,0x57,0x79,0x9C,0xBE,0xE0,0x02,0x47,0x69,0x8B,0xCA,0xF2,0x31,0x53,0x75,0x98,0xBA,0xD6,0xF9,0x15,0x5F,0x82,0xA4,0xC6,0xE8,0x05,0x33,0x60,0x7D,0xBC,0xFA,0x3F,0x83,0xC2,0x0C,0x51,0x95,0xD4,0x18,0x5D,0xA1,0xE0,0x25,0x69,0xA8,0xD0,0xE7,0x0F,0x31,0x53,0x75,0x98,0xB4,0xDC,0xF9,0x1B,0x3D,0x5F,0x7C,0xA4,0xC0,0x05,0x21,0x49,0x88,0xD2,0xF4,0x11,0x55,0x94,0xBC,0xDE,0x1D,0x4B,0x62,0x8F,0xAC,0xF0,0x2F,0x57,0x74,0x96,0xB2,0xD5,0xF7,0x1F,0x3B,0x63,0x86,0xAE,0xC4,0xEC,0x09,0x47,0x8C,0xD0,0xF3,0x15,0x54,0x98,0xC0,0xE2,0x05,0x21,0x66,0x88,0xA4,0xD2,0xEF,0x39,0x72,0xBC,0xD9,0xFB,0x23,0x3F,0x62,0x84,0xA0,0xC3,0xF0,0x07,0x2F,0x4C,0x74,0x90,0xCF,0xF7,0x13,0x3B,0x58,0x74,0x9C,0xB9,0xDB,0x03,0x1F,0x6A,0x86,0xA3,0xED,0x0F,0x31,0x4E,0x76,0x92,0xB5,0xF9,0x27,0x38,0x7C,0xA4,0xC1,0x05,0x28,0x4A,0x8E,0xCD,0x11,0x3A,0x50,0x9B,0xBD,0xDF,0x93,0x24,0x40,0x68,0xA7,0x2A,0x58,0x74,0xB9,0xDB,0xF7,0x3C,0x5E,0x80,0xA3,0xC5,0xE7,0x09,0x2C,0x48,0x70,0x8D,0xD1,0xF9,0x38,0x54,0x77,0x9F,0xBB,0xDD,0x00,0x22,0x60,0x83,0x9F,0xE9,0x11,0x2E,0x50,0x72,0x95,0xB7,0xDF,0xFB,0x18,0x40,0x5C,0x7F,0xA1,0xB8,0x08,0x2A,0x46,0x6E,0x8B,0xAD,0xD5,0xFD,0x14,0x58,0x97,0xDC,0x20,0x59,0xA9,0xEE,0x32,0x71,0xB5,0xF4,0x38,0x77,0x99,0xC1,0x06,0x4A,0x6D,0x8F,0xAB,0xCE,0xF0,0x0C,0x34,0x57,0x79,0x95,0xBD,0xDA,0x02,0x1E,0x46,0x5D,0xA7,0xE6,0x25,0x6F,0xAE,0xF2,0x14,0x37,0x5F,0x7B,0xC0,0xE8,0xFE,0x21,0x43,0x6B,0x8D,0xC6,0x10,0x33,0x55,0x77,0x99,0xBC,0xD8,0x00,0x1D,0x45,0x5B,0x83,0xA0,0xE4,0x29,0x67,0x8F,0xAC,0xF0,0x18,0x35,0x63,0x79,0xB8,0xFD,0xC1,0x4D,0x6F,0x86,0xCA,0xF2,0x09,0x4D,0x92,0xBA,0xD6,0xF9,0x15,0x37,0x59,0x82,0xA4,0xBA,0xE8,0x05,0x27,0x49,0x6B,0x8E,0xAA,0xCC,0xEF,0x17,0x33,0x78,0xB6,0x01,0x3F,0x7E,0xC3,0xEB,0x07,0x4C,0x90,0xB2,0xD5,0xFD,0x19,0x5E,0xA2,0xBE,0xE1,0x03,0x25,0x47,0x64,0xAE,0xD6,0xED,0x15,0x31,0x59,0x76,0xB5,0xF9,0x1B,0x3E,0x7C,0xA4,0xC7,0xE9,0x0B,0x33,0x50,0x8E,0xB6,0xD9,0x01,0x11,0x56,0x7E,0x95,0xDF,0x9F,0x13,0x29,0x46,0x68,0x8A,0xAC,0xC9,0xEB,0x0D,0x2A,0x52,0x6E,0xAD,0xCF,0xF7,0x25,0x30,0x64,0x7B,0xA3,0xBF,0x09,0x42,0x8D,0xCB};

    #endif

And here's what I see from Serial:

    499
    499
    499
    data using same index:
    index: 0 value:1654
    index: 1 value:1654
    index: 2 value:1654
    index: 3 value:1654
    index: 4 value:1654
    index: 5 value:1654
    index: 6 value:1654
    index: 7 value:1654
    index: 8 value:1654
    index: 9 value:1654
    data using counter:
    index: 0 value:4294945024
    index: 1 value:4294962688
    index: 2 value:12806
    index: 3 value:28928
    index: 4 value:4294948096
    index: 5 value:4294964224
    index: 6 value:14337
    index: 7 value:30464
    index: 8 value:4294940928
    index: 9 value:4294951174

I see what I expect for first 3 values and also for data using same index, but no when using a variable as an index for the PROGMEM arrays.

What is going on and how can I fix this ?

**Update**
Mikael's answer is the solution, but I will post a working snippet here for reference:

    #include <avr/pgmspace.h>
    #include "flashData.h"

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

      unsigned char c1,c2,c3;
      unsigned long value;

      Serial.println("data using counter:");
      for(int i = 0 ; i < 652; i++){
        c1 = (unsigned char) pgm_read_byte(&onsets1[i]);
        c2 = (unsigned char) pgm_read_byte(&onsets2[i]);
        c3 = (unsigned char) pgm_read_byte(&onsets3[i]);
        value = (((unsigned long) c1) << 16) | ((unsigned long)c2 << 8) | (unsigned long)c3;
        Serial.print("index: ");
        Serial.print(i);
        Serial.print("\tvalue:");
        Serial.println (value);
        delay(10);
      }

    }

    void loop() {

    }
The key is not only explicitly casting the data read, but also correctly reading the the PROGMEM data.

title: How to correctly pack an unsigned long from 3 unsigned chars?

Answers: 2

body:
You can try (explict unsigned long values):

    unsigned long fromValues = (0x00UL << 16) | (0x01 << 8) | 0xF3;
    Serial.println(fromValues);

or:

    value = (((unsigned long) c1) << 16) | (c2 << 8) | c3;

The issue is that the expression is implicit int and not long (as you are assuming). You need to tell the compiler about this.

An extra bonus comment: There is actually a 24 bit integer definition in AVR GCC according to the [wiki, see Extensions, Types][1].

Cheers!

  [1]: https://gcc.gnu.org/wiki/avr-gcc

body:
I got it to work by typecasting firmly and using multiplications:

      Serial.println("data using counter:");
      for (int i = 0 ; i < 10; i++) {
        c1 = onsets1[i];
        c2 = onsets2[i];
        c3 = onsets3[i];
        value = (uint8_t)c3 + (uint16_t)((uint8_t)c2*256)+(uint32_t)(c1*65536);
        Serial.print("index: ");
        Serial.print(i);
        Serial.print("\t");
        Serial.print(c1, HEX);
        Serial.print(", ");
        Serial.print(c2, HEX);
        Serial.print(", ");
        Serial.print(c3, HEX);
        Serial.print(" ");
        Serial.print("\tvalue:");
        Serial.println (value, HEX);
      }

The result:

>     data using counter:
    index: 0 A1, F6, 0  value:A1F600
    index: 1 FC, A7, 0  value:FCA700
    index: 2 B5, 7A, B8  value:B57AB8
    index: 3 EF, DB, 0  value:EFDB00
    index: 4 14, F9, 0  value:14F900
    index: 5 D7, 7F, 0  value:D77F00
    index: 6 F2, 72, 1  value:F27201
    index: 7 6F, DB, 0  value:6FDB00
    index: 8 5E, 5E, 0  value:5E5E00
    index: 9 F0, E7, B8  value:F0E7B8


body:
I'm still very new to arduino and coding and having some difficulties trying to figure out what I am doing wrong here.

This program is to have control over 2 relays, using a combination of an      IR receiver and a ir_remotecontrol with pre-programmed buttons (ir_remote buttons 1 = relay 1 toggle, button 2 = relay 2 toggle).
A master momentary hard wired switch to override changes to the relays and toggle their states i.e if both relays are on via ir remote - toggle them off, or if only 1 relay is on toggle it off with
first click of button then toggle both back on after second click of button.
The Bluetooth module and android app is to also control relays the same as the ir_remote via integers sent through the serial port.

It all sort of works at the moment...

If I just work the relays using the ir remote and the momentary switch it all works perfectly.

if I make sure the relays are in the off position using the remote switch and then use the Bluetooth it also works perfectly.

The problem only is when I use a combination of the ir remote or switch and the Bluetooth - things get weird - the Bluetooth commands seem to reverse and the relays start making a buzzing noise and the momentary switch muddles things up so basically it's all bad news! I've stared at this code for hours and tried a few different things but I just can't see what's wrong.

Let me know if I need to give a more detailed example of the errors I am having. Just thinking it is probably obvious for you pro's out there when you see my noob code!.

Any help would be greatly appreciated!

    /*This program is to have control over 2 relays, using a cobination of   an IR reciever and remote control with pre programmed buttons    (ir_remote buttons 1 = relay 1 toggle, 2 = relay 2 toggle).
    A master momentery hard wired switch to overide changes to the relays and toggle their states i.e if both relays are on via ir remote - toggle them off, or if 1 only relay is on toggle it off with first click of button then toggle both back on after sencond click of button.
    Bluetooth module and andoid app to also control relays the same as the ir_remote.
     */
    //include libaries, and initialise variables
    #include <SoftwareSerial.h>
    #include <IRremote.h>
    #define irPin 8
    #define RxD 7
    #define TxD 6
    #define relay1 13
    #define relay2 12
    #define buttonPin 2
    SoftwareSerial blueTooth(RxD, TxD);
    IRrecv irrecv(irPin);
    decode_results results;
    int comdata;
    const int wait = 30;
    int sensorValue = 0;
    int sensorOut = 0;
    int relay1State = 0;
    int relay2State = 0;
    int masterState = 0;
    int buttonState = 0;
    int lastButtonState = 0;
    long lastDebounceTime = 0;
    long debounceDelay = 50;

    void setup()
    {
      blueTooth.begin(38400);                     //set bluetooth baud rate
      delay(500);
      irrecv.enableIRIn();                        //enable infrared recieve
      pinMode(relay1, OUTPUT);                    //setting relays 1 & 2 to output
      pinMode(relay2, OUTPUT);
      pinMode(buttonPin, INPUT);                  //setting momentery swith (overide) to inpt
      digitalWrite(relay1, relay1State);          //putting current status of relays into a variable
      digitalWrite(relay2, relay2State);

    }

    void loop()
    {
      if (blueTooth.available())                  //setting a variable for bluetooth recieved serial commands
      comdata = blueTooth.read();

      if(comdata == '1'){

      digitalWrite(relay1, relay1State);          //if bluetooth receivs "1" toggle relay1state -- essentially relay 1 ON
      }
      if(comdata == '0'){
      digitalWrite(relay1, !relay1State);         //if bluetooth receivs "0" toggle relay1state -- essentially relay 1 OFF

      }
      if(comdata == '2'){
      digitalWrite(relay2, relay2State);          //if bluetooth receivs "2" toggle relay2state -- essentially relay 2 ON

      }
      if(comdata == '3'){
      digitalWrite(relay2, !relay2State);         //if bluetooth receivs "3" toggle relay2state -- essentially relay 2 OFF
      }

      if (irrecv.decode(&results)){                     //Start listing for ir commands, if set remote button code is recvived toggle the variable relay1State or relay2state
      switch (results.value){
          case 0xFF30CF:
            relay1State = !relay1State;
            digitalWrite(relay1, relay1State);
            delay(250);
            break;
          case 0xFF18E7:
            relay2State = !relay2State;
            digitalWrite(relay2, relay2State);
            delay(250);
            break;
        }
        irrecv.resume();
        }

      int reading = digitalRead(buttonPin);          //debounce used to help with faulse readings from momentery switch
      if (reading != lastButtonState) {
       lastDebounceTime = millis();
      }
      if ((millis() - lastDebounceTime) > debounceDelay) {

      if (reading != buttonState) {
          buttonState = reading;

      if (buttonState == HIGH) {                      //if the momentery switch is pressed toggle masterstate which is both relay 1 and relay 2 state
         masterState = !masterState;
         relay1State = masterState;
         relay2State = masterState;
          }
          }
        }

      digitalWrite(relay1, relay1State);
      digitalWrite(relay2, relay2State);
      lastButtonState = reading;

    }

title: Controlling 2 relays with IR remote, push button and bluetooth - sort of works, need help!

Answers: 2

body:
Only the button changes `relay1State` and `relay2State`. The IR and BT only change the pin using digitalWrite. But then in the last 3 lines, the pin is changed back to the value of `relay1State` and `relay2State`.

I think for the IR and BT you need to change e.g. `digitalWrite(relay2, !relay2State);` to `relay2State=false;` etc.

PS It there a pull-up/pull-down resistor on the button pin?

body:
Looks like it could be reusing the old comdata values in the first part of loop().  Maybe make the first chunk:

       if (blueTooth.available()) {
          comdata = blueTooth.read();
          switch (comdata) {  // set state variables based on bluetooth
          case  '0':  // if bluetooth receivs "0" clear 1
              relay1State = 0;
              break;
          case  '1':  // if bluetooth receivs "1" set 1
              relay1State = 1;
              break;
          case  '2':  // if bluetooth receivs "2" set 2
              relay2State = 1;
              break;
          case  '3':  // if bluetooth receivs "1" clear2
              relay2State = 0;
              break;

          case  '4':  // if bluetooth receivs "4" toggle 1
              relay1State = !relay1State;
              break;
          case  '5':  // if bluetooth receivs "5" toggle 2
              relay2State = !relay2State;
              break;
          case  '6':  // if bluetooth receivs "6" toggle master/both
              masterState = relay1State = relay2State = !masterState;
              break;
          }  // end of switch
          // apply state variables to outputs
          // (could be left to the end of the loop() code)
          digitalWrite(relay1, relay1State);
          digitalWrite(relay2, relay2State);
       } // end of bluetooth processing

       ... /// IR processing code

       // debounce button and toggle masterstate & set state vars accordingly
       // see http://arduino.stackexchange.com/questions/17443/how-to-simulate-delay-to-debounce-mechanical-button-using-millis
       //

    // re-ensure output state matches the state variables.
    digitalWrite(relay1, relay1State);
    digitalWrite(relay2, relay2State);
    }

As it is, the if() statements trigger on the state of the last read comdata, not on the whether a new command was read.

Also, maybe check whether the toggling comments match the code or the code matches the intention properly.


body:
I made modifications on the original code of DMP6 MPU6050 to make it as I want. I took the standard libraries with it and they are `helper_3dmath.h`, `MPU6050.cpp`, `MPU6050.h`, `MPU6050_6Axis_MotionApps20.h`, `I2C.cpp` and finally `I2c.cpp`.

I made a main.ino and `get_angles.cpp`, which contains the code that has the function that calculates the angles out of the MPU6050. And a header file `get_angles.h`. I am getting an error that I can't figure out.

My main.ino is:

<!-- language: lang-C -->

    #include <Wire.h>
    #include "get_angles.h"
    angles imu ;
    MPU6050 mpu;
    void setup() {
        Wire.begin();
      TWBR = 24;
      Serial.begin(115200);
      mpu.initialize();
      mpu.setDMPEnabled(true);
         packetSize = mpu.dmpGetFIFOPacketSize();
    }

    void loop() {
      int yaw,pitch,roll;
      yaw =imu.get_yaw();
      pitch=imu.get_pitch();
      roll=imu.get_roll();
    }

`get_angles.cpp`

<!-- language: lang-C -->

    #include "get_angles.h"
    int angles::get_yaw() {
      MPU6050 mpu;
      mpuIntStatus = mpu.getIntStatus();
      fifoCount = mpu.getFIFOCount();
      // check for overflow (this should never happen unless our code is too inefficient)
      if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
        // reset so we can continue cleanly
        mpu.resetFIFO();
        Serial.println(F("FIFO overflow!"));
        // otherwise, check for DMP data ready interrupt (this should happen frequently)
      } else if (mpuIntStatus & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
        // read a packet from FIFO
        mpu.getFIFOBytes(fifoBuffer, packetSize);
        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
        int yaw;
        yaw=ypr[0] * 180/M_PI;
        return(yaw);
      }
    }

    int angles::get_pitch() {
      MPU6050 mpu;
      mpuIntStatus = mpu.getIntStatus();
      fifoCount = mpu.getFIFOCount();
      // check for overflow (this should never happen unless our code is too inefficient)
      if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
        // reset so we can continue cleanly
        mpu.resetFIFO();
        Serial.println(F("FIFO overflow!"));
        // otherwise, check for DMP data ready interrupt (this should happen frequently)
      } else if (mpuIntStatus & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
        // read a packet from FIFO
        mpu.getFIFOBytes(fifoBuffer, packetSize);
        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
        int pitch;
        pitch=ypr[1] * 180/M_PI;
        return(pitch);
      }
    }

    int angles::get_roll() {
      MPU6050 mpu;
      mpuIntStatus = mpu.getIntStatus();
      fifoCount = mpu.getFIFOCount();
      // check for overflow (this should never happen unless our code is too inefficient)
      if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
        // reset so we can continue cleanly
        mpu.resetFIFO();
        Serial.println(F("FIFO overflow!"));
        // otherwise, check for DMP data ready interrupt (this should happen frequently)
      } else if (mpuIntStatus & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
        // read a packet from FIFO
        mpu.getFIFOBytes(fifoBuffer, packetSize);
        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
        int roll;
        roll=ypr[2] * 180/M_PI;
        return(roll);
      }
    }

`get_angles.h`

<!-- language: lang-C -->

    #ifndef get_angles_H
    #define get_angles_H

    #include "I2Cdev.h"
    #include "MPU6050_6Axis_MotionApps20.h"
    static   uint16_t packetSize;
    class angles {
      public:
        int get_yaw();
     int get_pitch();
     int get_roll();
      private:
        uint8_t mpuIntStatus;
     uint16_t fifoCount;     // count of all bytes currently in FIFO
     uint8_t fifoBuffer[64]; // FIFO storage buffer
     Quaternion q;           // [w, x, y, z] quaternion container
     VectorFloat gravity;    // [x, y, z] gravity vector
     float ypr[3];           // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
    };
    #endif

The error I am facing:

    Arduino: 1.6.5 (Windows 8.1), Board: "Arduino/Genuino Uno"

    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpInitialize()'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpPacketAvailable()'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetAccel(long*, unsigned char const*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetAccel(int*, unsigned char const*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetAccel(VectorInt16*, unsigned char const*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetQuaternion(long*, unsigned char const*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetQuaternion(int*, unsigned char const*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetQuaternion(Quaternion*, unsigned char const*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetGyro(long*, unsigned char const*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetGyro(int*, unsigned char const*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetGyro(VectorInt16*, unsigned char const*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetLinearAccel(VectorInt16*, VectorInt16*, VectorFloat*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetLinearAccelInWorld(VectorInt16*, VectorInt16*, Quaternion*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetGravity(VectorFloat*, Quaternion*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetEuler(float*, Quaternion*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetYawPitchRoll(float*, Quaternion*, VectorFloat*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpProcessFIFOPacket(unsigned char const*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpReadAndProcessFIFOPacket(unsigned char, unsigned char*)'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    third_iteration.cpp.o: In function `MPU6050::dmpInitialize()':
    C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpGetFIFOPacketSize()'
    get_angles.cpp.o:C:\Users\MOHAME~1\AppData\Local\Temp\build384877420483334776.tmp/helper_3dmath.h:56: first defined here
    collect2.exe: error: ld returned 1 exit status
    Error compiling.

      This report would have more information with
      "Show verbose output during compilation"
      enabled in File > Preferences.

title: Error in modification on MPU6050_DMP6

Answers: 0


body:
Is there a variable data type available for Arduino? I have a class that should have a member that will differ in data type, in the past I have used the "variable" keyword in c++ but when I tried to use it the compiler yelled at me. I searched online and found a couple of articles that mentioned that if you are using an alternate GUI (I am using eclipse mars) that you can enable the feature but I can not find the correct settings as the examples I had found were for Juno and below.

Here is an example of what I am trying to accomplish

    class DisplayItem{

       public:
       variant *displayVar;

       void Display(){
          Serial.println(displayVar);
       }
    }

    int intDisplay;
    String strDisplay;

    DisplayItem item();
    item.displayVar = &intDisplay;
    item.Display();
    item.displayVar = &strDisplay;
    item.Display();

I realize I could create a overloaded function to display different data types but it would be allot easier if I could simply assign a reference to a variant datatype and reuse the variable.

----------

**Edit**

So after looking through the answers I think I have this figured out. I needed to keep track of which variable was being set, I put together a quick example in hopes it will help someone else out with the same question.

    class DisplayItem{

       private:
       int iVarType;

       union{
          int *i;
          float *f;
       } displayVar;

       public:
       void SetVar(int *var){
          displayVar.i = var;
          iVarType = 0;
       }

       void SetVar(float *var){
          displayVar.f = var;
          iVarType = 1;
       }

       void Display(){
          if (iVarType == 0){
             Serial.println(displayVar.i);
          }else if (iVarType == 1){
             Serial.println(displayVar.f);
          }
       }
    }

    int intDisplay = 1;
    float floatDisplay = 0.123;

    DisplayItem item();
    item.SetVar(&intDisplay);
    item.Display();
    item.SetVar(&floatDisplay);
    item.Display();

Will Display:

    1
    0.123

title: Arduino Variable Data Type?

Answers: 2

body:
No, there is no such thing.  The whole concept of "type" only exists during compilation, not at run-time.

However, you can "emulate" it using "setters" and keeping your own internal state information:

    class Thing {
        private:
            String *strvar;
            int intvar;
            int type;

        public:
            void set(int val) {
                intvar = val;
                type = 1;
            }
            void set(String &str) {
                strval = &str;
                type = 2;
            }
            void Display() {
                if (type == 1) {
                    Serial.print("Value: ");
                    Serial.println(intval);
                } else if (type == 2) {
                    Serial.print("String: ");
                    Serial.println(strval);
                } else {
                    Serial.println("Something went wrong");
                }
            }
    };

    Thing t;
    String s = "This is a string";
    int i = 23;
    t.set(s);
    t.Display();
    t.set(i);
    t.Display();

The multiple functions named the same but with different parameters are *overloaded*. The best match is picked at compile time.

body:
For the situation illustrated in the question – displaying data – polymorphic functions already exist, and might as well be used in this case.  Specifically, use the `Streaming.h` [contributed library](https://www.arduino.cc/en/Reference/Libraries).  It adds some “syntactic sugar” to Arduino C.  At compile time it converts C++-like `<<` Serial stream operators to `Serial.print` statements, without increasing code size.  You can install it via [`Streaming5.zip`](http://arduiniana.org/Streaming/Streaming5.zip) from [arduiniana.org](http://arduiniana.org/libraries/streaming/) .

In other cases, a `union` data structure allows treating an area of memory different ways.  Wikipedia's *[Union type](https://en.wikipedia.org/wiki/Union_type)* article explains the general idea.  See eg [tutorialspoint.com/cprogramming](http://www.tutorialspoint.com/cprogramming/c_unions.htm) for `union` syntax and usage.  For some reason, arduino.cc's [Language Reference](https://www.arduino.cc/en/Reference/HomePage) page hasn't got `union` on its list of language features.  However, mcgurrin.com has a page called *[There is Power in a Union](http://www.mcgurrin.com/robots/?p=127)* that codes a simple Arduino C example two ways (where `bearing` is an `int`):

    higherByte = compass.read();
    lowerByte = compass.read();
    bearing = ((higherByte<<8)+lowerByte)/10

-vs-

    union Data {
      byte b[2];
      int value;
    };
    ...
    union Data data;
    data.b[0] = compass.read();
    data.b[1] = compass.read();
    bearing = data.value/10;


body:
I'm taking my first wobbly steps outside the Arduino IDE and I'm not having much success with timers / interrupts. I can set a pin to output and light an LED with registers fine but I cannot for the life of me get it to blink using a timer. I have tried numerous tutorials and followed the Atmel ATmega328 datasheet very closely.

Using an Arduino Uno R3 & Atmel ICE (ISP.) My dev system is Raspbian (Debian) with the GNU AVR toolchain (avr-gcc, avr-objcopy, avrdude.) Apart from not having a bootloader it's a bog standard board (including fuses.)

Here's my current code:

    #include <avr/io.h>
    #include <avr/interrupt.h>

    ISR(TIMER0_COMPA_vect)
    {
     PORTB ^= (1 << PB5); // Toggle Arduino Pin #13
    }

    int main (void)
    {
     DDRB = (1 << DDB5); // Arduino Pin #13 is Output

     cli(); // Clear Interrupts

     OCR0A = (unsigned char)0xFF; // Compare Register A = 255
     TIMSK0 = (1 << OCIE0A); // Enable Interrupt for Comp. Reg. A
     TCCR0A = (1 << WGM01); // CTC Mode

     sei(); // Set Interrupts
     TCCR0B = (1 << CS02) | (1 << CS00); // Divide by 1024 Prescaler (GO!)

     return 0;
    }

I don't know if I'm just not seeing something or if I've set registers in the wrong order but it's driving me crazy.

title: Trouble with Timer 0

Answers: 2

body: `return 0` resets the device. Use `while(1);` instead, to make it wait indefinitely.

body:
Returning from `main` does not reset the device (it would start up again and do it all over in that case). It calls `exit` which turns interrupts off and loops indefinitely.

    00000068 <__ctors_end>:
      68: 11 24        eor r1, r1
      6a: 1f be        out 0x3f, r1 ; 63
      6c: cf ef        ldi r28, 0xFF ; 255
      6e: d8 e0        ldi r29, 0x08 ; 8
      70: de bf        out 0x3e, r29 ; 62
      72: cd bf        out 0x3d, r28 ; 61
      74: 0e 94 52 00  call 0xa4 ; 0xa4 <main>
      78: 0c 94 61 00  jmp 0xc2 ; 0xc2 <_exit>

    ...

    000000a4 <main>:
      a4: 80 e2        ldi r24, 0x20 ; 32
      a6: 84 b9        out 0x04, r24 ; 4
      a8: f8 94        cli
      aa: 8f ef        ldi r24, 0xFF ; 255
      ac: 87 bd        out 0x27, r24 ; 39
      ae: 82 e0        ldi r24, 0x02 ; 2
      b0: 80 93 6e 00  sts 0x006E, r24
      b4: 84 bd        out 0x24, r24 ; 36
      b6: 78 94        sei
      b8: 85 e0        ldi r24, 0x05 ; 5
      ba: 85 bd        out 0x25, r24 ; 37
      bc: 80 e0        ldi r24, 0x00 ; 0
      be: 90 e0        ldi r25, 0x00 ; 0
      c0: 08 95        ret

    000000c2 <_exit>:
      c2: f8 94        cli

    000000c4 <__stop_program>:
      c4: ff cf        rjmp .-2       ; 0xc4 <__stop_program>

You can see at address 0x74 it calls main, and then jumps to exit. `exit` turns off interrupts.

With interrupts off your ISR will not toggle pin 13.


body:
I am trying to update the Arduino library via the library manager and I tried to download it from the link given in the firmata_test program:

> WARNING: Category '' in library ArduinoUnit is not valid. Setting to
> 'Uncategorized'
> C:\Users\SAURAB~1\AppData\Local\Temp\arduino_c8217a5b56c170d64dfe4c80a1a205dc\firmata_test.ino:
> In member function 'virtual void test_beginPrintsVersion::once()':
>
> C:\Users\SAURAB~1\AppData\Local\Temp\arduino_c8217a5b56c170d64dfe4c80a1a205dc\firmata_test.ino:32:3:
> warning: narrowing conversion of '249' from 'int' to 'char' inside { }
> [-Wnarrowing]
>
>    };
>
>    ^
>
> Multiple libraries were found for "Firmata.h"  Used:
> C:\Users\saurabh2836\Documents\Arduino\libraries\Firmata  Not used:
> C:\Program Files (x86)\Arduino\libraries\Firmata

I'm getting this error. I searched but found no conclusive answer. I'm using Windows 8 64bit and Firmata downloaded from http://www.firmata.org/.

Am I doing something wrong?

title: Issue in installing Arduino unit library and running with Firmata test application

Answers: 1

body:
The compiler is giving a lot of information. The warnings can be ignored but the "multiple libraries" indicates that there is at least two copies of Firmata installed. Check (search) that you have not got several downloads of Firmata. Worst case reinstall to clean up that.

Cheers!


body:
I am trying to learn and understand the [COSA Library][1] using a 12864ZW (ST7920) 128X64 LCD Display. Right now I am able to use the LCD using the u8glib but also found that COSA has a library for the [ST7920 Display][2], I originally used [this tutorial][3] to get things working.

The main problem that I have now is in the [ST7920 Documentation][4] there is a schematic that shows how to hook up a ST7920 Compatible LCD. The first [tutorial][3] only uses 3 lines from the Mega and the Cosa is using what looks like 6 lines.

Looking at the header file, it looks like it is derived from the HD44780 Class and what I can gather is pins 16 and 4 are hard coded for something? I am not quite clear on how to use the Cosa version of the library. Can someone please give me a explanation and perhaps a explanation on how to get this working using Cosa?

  [1]: https://github.com/mikaelpatel/Cosa
  [2]: https://dl.dropboxusercontent.com/u/993383/Cosa/doc/html/dir_6c9b05e5d5923c236f9de149d085166d.html
  [3]: http://overskill.alexshu.com/128x64-12864-lcd-w-arduino-serial/
  [4]: https://github.com/mikaelpatel/Cosa/blob/master/libraries/ST7920/ST7920.hh

title: Arduino Mega, ST7920 using COSA

Answers: 1

body:
The Cosa ST7920 library uses text mode only (16X4). The ST7920 class is controlled though an adapter. There are several adapters available depending on how you wish to connect to the Arduino. They range from parallel 4-bit to SPI with shift register. The adapters implement the interface [HD44780::IO][1]. There are several LCD examples. The [CosaLCDbench][2] shows the possible configurations with LCD and Adapters. Please see the file for further details.

  [1]: https://github.com/mikaelpatel/Cosa/blob/master/libraries/HD44780/HD44780.hh#L44
  [2]: https://github.com/mikaelpatel/Cosa/blob/master/libraries/LCD/CosaLCDbench/CosaLCDbench.ino


body: I am using an Arduino to control some mechanical components in a project I have. It controls a motor, two servos, a valve, and a compressor. When plugged into the computer, everything works fine and perfectly. However, when I power it through the barrel jack using our power supply, some weird things happen. First of all, our servos, which are powered through the Arduino, stop working. All the other components work except for them. Secondly, at the end of the code we have a 5 second delay. Using the computer it works fine. When powered with our supply the delay doesn't seem to happen at all. Any ideas?

title: Arduino Not Working as Intended when using barrel jack

Answers: 3

body: I believe that the problem that you are facing is lack of power. It is likely that your power source cannot supply enough current or voltage to power the equipment AND the arduino. Try to get a power supply that has more amps.

body:
i agree with majenko, maybe you know how to fix it but if you do not know here is a site with good information to make you're own  5 volt Regulated source.

http://www.rakeshmondal.info/IC-7805-Voltage-Regulator

sorry for my bad english and good luck. :D

body:
I had a similar problem recently while powering a servo with a Arduino.
It did turn out to be power, our Arduino could only supply about 500ma and with sufficient speed or torque on the servo (a lot of times just the boot sequence) we would it the 500ma at peak, the effect however was baffling at first because when we hit the peak current the Arduino would reboot, this could account for you extra delay at the end.

For us the solution was simple bypass the Arduino when supplying current to the servos, in our case it as a 5v battery, you would probably need to drop the 12v to 6v in your case.


body:
I am completely lost here, I have no idea what I am doing wrong. I am using Eclipse Mars using the Eclipse C++ Arduino extension. I am also using the COSA library, this is where the problem comes in. I can use all of the core COSA libraries but I can not figure out how to include the other libraries that are supplied with COSA specifically the ST7920.h file that is located in the libraries folder. Does anyone have any experience with this?

I have tried setting the path using the Project->C/C++ General->Preprocessor include paths and setting it there to no avail.

One thing that I am concerned about is in these separate libraries they are including files that are in other libs using only the header file, for example in the ST7920.hh file it has:

    #include "Cosa/LCD.hh"
    #include <HD44780.h>

I need to configure things so that the HD44780.h file needs to be found also. That file is located at "../HD44780/HD44780.h". How do I tell the compiler to search the "libraries" folder for files?

Also I tried to simply add the libraries folder as a linked folder in my project, that also did not work.

the only code I have is the #include <ST7920.hh> and the compiler come back with that it can't find the file.

title: Eclipse add library

Answers: 2

body:
If you are using Linux I would recommend looking at the makefile based build script for Cosa (See [Cosa/build][1]). After configuration building from any IDE is more or less a simple command. No Makefile is required. The script cosa will do all the work.

    $ cosa BOARD ACTION

such as

    $ cosa uno avanti

which will build a sketch for Arduino Uno, upload and start a serial monitor. This can be used from any IDE. I use GNU Emacs, M-X compile (F2), with the command.

The way the Arduino pre-processor works each referenced library needs to be included in the sketch. For a sketch that uses ST7920:

    #include <HD44780.h>
    #include <ST7920.h>

  [1]: https://github.com/mikaelpatel/Cosa/tree/master/build

body:
I would advice to use the arduino eclipse plugin and not use the eclipse C++ arduino extension.

The eclipse C++ arduino extension is still very much in development.

The Arduino eclipse plugin has been around for years and contains far more features.

If you use V3 (that is still the nightly at the time of writing) you can use the boards manager and the cosa json file to import the cosa boards.

Importing a lib is a matter of typing

    #include "libname"

and saving.


body:
I have `TM1812` addressable `LED` strip (1meter long 96 LED). I am looking a way to `program` it and i found this [http://www.deskontrol.net/blog/arduino-based-artnet-node-for-led-pixels/][1]
and its mentioned in article that it doens't work with `current version` of Arduino `IDE`.

Is there some other lib/api available to program it or another method?

**UPDATE**
As mentioned by @dlu FastLED support wide variety of `LEDs`. I contacted developers of `FastLED` on google + and they have updated there documentation for support of `TM1812` its similar to `TM1809`

  [1]: http://www.deskontrol.net/blog/arduino-based-artnet-node-for-led-pixels/

title: Programming addressable LED

Answers: 2

body:
There is a very nice library called [FastLED][1], it is also on [GitHub as FastLED/FastLED][2]. It is quite flexible and supports a huge range of addressable LEDs. I'm currently using it with 1.6.6.

The code that you linked to was developed with an older version of the Arduino IDE, so you might want to see if you can find an older version and try building with that.

[1]: http://fastled.io
[2]: https://github.com/fastled/fastled

body:
All TM chip Family is supported by Fastled Libs if you use a TM1811 just put TM1809.

It should work, I have tried and it succeeded.


body:
I got this program. It controls a refrigeration room using a ds1280 temperature probe.

The thing is, sometimes the probe reach 7.00°C then the refrigerattion cycle start (refrigeration cycle is on a switch case statment) and then the probe read 6.75. So the refrigeration don't complete its start and leaves part of the system in wrong mode.

How can I add some guard to ... once the switch case statment don't being interrupted by anything unless complete the on in this case or the off in other case.

Here are the most resembling parts of the code.

    void turnOnCompressor(){

    /*
    This subrutine is intended to stop the refrigeration cycle
    in the most ordered way, and keeping the refrigerant on
    the high side of the system.
    */

    // boolean refrigerattion = false; // var to handle ref status only once
    // byte compOn = 0;
    // byte pascomOn = 0; //to chek if the variable has updated.
    // unsigned long  comOnTime  = 0;
    // unsigend long  comOnDelay = 1500;
    // unsigend long  comOnCT    = 0;     //the current time of the compressor.

    //------for debug only
    //Serial.print("comOnCT  =             "); Serial.println(comOnCT);
    //Serial.print("comOnCT - millis()  =  "); Serial.println(millis() - comOnTime );

    // Serial.println("INICIANDO REFRIGERACION");

    if(refrigerationBegin == true )
    {

    if(refrigerattion == true && millis()- comOnTime  >= comOnDelay ){
       compOn ++;
       comOnTime = millis();
     /*
     //--------for debug only
     Serial.println("---------------------");
     Serial.print("Var compOn "); Serial.println(compOn);
     Serial.print("comoON  "); Serial.println(compOn);
     Serial.print("pascomON"); Serial.println(pascomOn);
     Serial.println("---------------------");
    */
    }

    if(compOn > pascomOn ){

      switch(compOn){

      case(1):
      lcd.setCursor(0,0);  lcd.print(F("      CICLO DE      "));
      lcd.setCursor(0,1);  lcd.print(F("    REFRIGERACION   "));
      lcd.setCursor(0,2);  lcd.print(F("                    "));
      break;

      case(2):
      lcd.setCursor(0,0);  lcd.print(F("    REFRIGERACION   "));
      lcd.setCursor(0,1);  lcd.print(F("     ENCENDIENDO    "));
      lcd.setCursor(0,2);  lcd.print(F("       VENT 1       "));
      digitalWrite(dif1, LOW);
      break;

      case(3):
      lcd.setCursor(0,0);  lcd.print(F("    REFRIGERACION   "));
      lcd.setCursor(0,1);  lcd.print(F("     ENCENDIENDO    "));
      lcd.setCursor(0,2);  lcd.print(F("       VENT 2       "));
      digitalWrite(dif2, LOW);
      break;

      case(4):
      lcd.setCursor(0,0);  lcd.print(F("    REFRIGERACION   "));
      lcd.setCursor(0,1);  lcd.print(F("     ENCENDIENDO    "));
      lcd.setCursor(0,2);  lcd.print(F("      SOLENOIDE     "));
      digitalWrite(solenoid, LOW);
      break;

      case(5):
      lcd.setCursor(0,0);  lcd.print(F("    REFRIGERACION   "));
      lcd.setCursor(0,1);  lcd.print(F("     ENCENDIENDO    "));
      lcd.setCursor(0,2);  lcd.print(F("      COMPRESOR     "));
      digitalWrite(compressor, LOW);
      break;

      case(6):
      lcd.setCursor(0,1);  lcd.print(F("                    "));
      lcd.setCursor(0,2);  lcd.print(F("                    "));
      refrigerattion = false;
      refOff = true     ;       // to cycle only once the set of the instructions per cycle.
      compOn = 0;
      cycleFansvar = false;        //bool to chek the refrigerattion has stop
      //--------------------------------
      //refrigerattion = true; add this variable at the end of the off routine to cycle the
      //operation otherwise will just start once
    }
    }
    }

    refrigerationBegin = false;
    }

    void turnOnCompressor(){

    /*
    This subrutine is intended to stop the refrigeration cycle
    in the most ordered way, and keeping the refrigerant on
    the high side of the system.
    */

    // boolean refrigerattion = false; // var to handle ref status only once
    // byte compOn = 0;
    // byte pascomOn = 0; //to chek if the variable has updated.
    // unsigned long  comOnTime  = 0;
    // unsigend long  comOnDelay = 1500;
    // unsigend long  comOnCT    = 0;     //the current time of the compressor.

    //------for debug only
    //Serial.print("comOnCT  =             "); Serial.println(comOnCT);
    //Serial.print("comOnCT - millis()  =  "); Serial.println(millis() - comOnTime );

    // Serial.println("INICIANDO REFRIGERACION");

    if(refrigerationBegin == true )
    {

    if(refrigerattion == true && millis()- comOnTime  >= comOnDelay ){
       compOn ++;
       comOnTime = millis();
     /*
     //--------for debug only
     Serial.println("---------------------");
     Serial.print("Var compOn "); Serial.println(compOn);
     Serial.print("comoON  "); Serial.println(compOn);
     Serial.print("pascomON"); Serial.println(pascomOn);
     Serial.println("---------------------");
    */
    }

    if(compOn > pascomOn ){

      switch(compOn){

      case(1):
      lcd.setCursor(0,0);  lcd.print(F("      CICLO DE      "));
      lcd.setCursor(0,1);  lcd.print(F("    REFRIGERACION   "));
      lcd.setCursor(0,2);  lcd.print(F("                    "));
      break;

      case(2):
      lcd.setCursor(0,0);  lcd.print(F("    REFRIGERACION   "));
      lcd.setCursor(0,1);  lcd.print(F("     ENCENDIENDO    "));
      lcd.setCursor(0,2);  lcd.print(F("       VENT 1       "));
      digitalWrite(dif1, LOW);
      break;

      case(3):
      lcd.setCursor(0,0);  lcd.print(F("    REFRIGERACION   "));
      lcd.setCursor(0,1);  lcd.print(F("     ENCENDIENDO    "));
      lcd.setCursor(0,2);  lcd.print(F("       VENT 2       "));
      digitalWrite(dif2, LOW);
      break;

      case(4):
      lcd.setCursor(0,0);  lcd.print(F("    REFRIGERACION   "));
      lcd.setCursor(0,1);  lcd.print(F("     ENCENDIENDO    "));
      lcd.setCursor(0,2);  lcd.print(F("      SOLENOIDE     "));
      digitalWrite(solenoid, LOW);
      break;

      case(5):
      lcd.setCursor(0,0);  lcd.print(F("    REFRIGERACION   "));
      lcd.setCursor(0,1);  lcd.print(F("     ENCENDIENDO    "));
      lcd.setCursor(0,2);  lcd.print(F("      COMPRESOR     "));
      digitalWrite(compressor, LOW);
      break;

      case(6):
      lcd.setCursor(0,1);  lcd.print(F("                    "));
      lcd.setCursor(0,2);  lcd.print(F("                    "));
      refrigerattion = false;
      refOff = true     ;       // to cycle only once the set of the instructions per cycle.
      compOn = 0;
      cycleFansvar = false;        //bool to chek the refrigerattion has stop
      //--------------------------------
      //refrigerattion = true; add this variable at the end of the off routine to cycle the
      //operation otherwise will just start once
    }
    }
    }

    refrigerationBegin = false;
    }

title: Prevent Switch case from not being complete

Answers: 1

body:
Are you trying to control by temperature or by time?

(I'm finding the code hard to follow. There seem to be 2 copies of it, and the comments in turnOnCompressor() seem to contradict the function name. I also don't see any code that mentions temperature.)

If this is temperature controlled, you need a dead-band - a temperature range bounded by a high- and a low setpoint. If you have a single setpoint, the system will jitter as air-circulation and electrical noise make the temperature appear to alternate above and below setpoint. The turn-on setpoint needs to be higher than the turn-off setpoint. You'll need to experiment to find out how far apart they need to be for the system to be stable.


body:
I have an Uno that loops processing serial commands and reading from a DHT11 sensor. For whatever reason, the device often stops responding. I put an LED on a pin and gave it a blink to see whether the loop is running, and sure enough the loop() stops running (the LED stays ON or OFF, depending on when it froze). I enabled the watchdog at 2 seconds, but it does not reset the device [it still stays frozen, even though wdt_reset() is called at basically the same time as the blinking LED is toggled].

I then tried various combinations of BaudRate=1200 (or 9600), Open(), Close(), DtrEnable=true [on both the Uno and the Mega], yet none of the combinations would make the device reset. The device *will* reset, however, if I re-upload the sketch using the Arduino IDE. I would like to emulate this resetting functionality from my own program's code. Reading on the official site, it sounds like the Baud=1200 reset feature is available only on certain models (not the Uno or Mega).

My code is by no means simple as I am no beginner when it comes to programming. This is the first time, however, that I have had a finicky unit that freezes all the time (say between 10 minutes and 2 hours into running). I merely want to reset the unit from the PC using code, like the Arduino IDE does. On the other hand, if the watchdog worked correctly, that would be fine as well. At the same time, I am not that experienced with electronic circuits, so making a circuit that would "press" the "reset" pin when the LED stops blinking is not something I am quite ready to do. Plus, I do not want to add a bunch more components if the job can be done through code.

On a side note, the Serial connection appears to be fully functional the whole time. The LED on the unit that indicates receiving from the PC continues to function whenever I send data to the device. I can connect and reconnect without any apparent issues. Plus, the Arduino IDE has no problem uploading new sketches and resetting the device. Naturally, no data is received from the device after it freezes (until it gets reset, of course).

**Update 1**: I made a simple sketch (see below) that would run for about 20 seconds and then let the WDT watchdog timeout do its thing. Result:
(a) Running the code on an Arduino-brand Mega 2560, the device simply resets every 20 seconds and keeps blinking;
(b) Running the code on a generic (made in China) Uno R3, at timeout the L light turns on and the device becomes completely unresponsive (not even the reset button or the Arduino IDE can save it); It must be unplugged to reset it.
(c) Running the code on an Arduino-brand Uno R3 works as expected, just like on the Mega 2560.

    #include <avr/wdt.h>
    void setup() {
      wdt_reset();
      wdt_enable(WDTO_2S);
      wdt_reset();
      pinMode(A5, OUTPUT);
      delay(1);
      Serial.begin(125000);
    }
    unsigned int LoopCount = 0;
    bool TestLED = false;
    void loop() {
      if(LoopCount % 300 == 0){
        TestLED = !TestLED;
        digitalWrite(A5, TestLED ? HIGH:LOW);
        if(LoopCount < 20000)
          wdt_reset();
      }
      delayMicroseconds(1000);
      LoopCount++;
    }

Nevertheless, I still would like if someone could provide a solution in terms of resetting a frozen generic Uno from Serial in .NET code -- not the WDT frozen, but the normal frozen (of unknown origin). I may be the one coding, but I'm unfortunately not the one deciding which units are put into production.

**Update 2**: I switched the EasyDriver to its own power source, where the only things in common with the stepper and the Arduino were the ground and the two signal wires. The generic Uno board ended up being even more problematic, going into a new freeze mode (after just a minute or two, pretty reliably) where the L light would blink very quickly. I'm not sure whether it had anything to do with toggling of the DtrEnable property, but I decided to stop messing with the generic board for the time being. The name-brand Uno appeared to freeze occasionally or malfunction as well with the original wiring, but the Watchdog did its thing and reset it straight away every time. Also, I tried toggling the RtsEnable property with the generic board, but it didn't seem to make a difference. The board would become unresponsive and unrevivable, even from the Arduino IDE.

Some more background: The reliability problem only really started to surface when I hooked up the DHT11 temperature sensor, *even though* the freezing would tend to happen only when the stepper motor was running. I have the DHT11 hooked up exactly as advocated by Adafruit, and it tends to read correctly most of the time.

**Update 3**: I was thinking maybe the SainSmart Mega2560 would be different from the no-name generic I was using. After getting one and hooking it up, I have found it to have the exact same problem. The SainSmart CPU crashes between 5 and 15 minutes into running. The serial chip (or module) keeps going as you can still see the serial lights change when you send to it. However, the on-board reset button does nothing, and the Arduino IDE cannot upload to the device or reset it. Only a power cycle can save it.

title: Reset Arduino Uno R3 from Serial when it freezes (stops looping)?

Answers: 2

body:
You can reset the Uno over the serial link by toggling the DTR line. How you do that depends on what platform and language you are using. There is a capacitor between the line and the reset pin, so the toggle must last a minimum ammount of time. 0.5 seconds works.

This is ok for just a quick fix hack, but probably better in the long run to (1) figure out why the code is crashing, and/or (2) figure out why WDT is not working.

body:
Since we don't know the nature of the freeze-up, and the clone-board behaves differently than an Arduino-brand board but we don't know how or why, there's not much more we can offer beyond suggesting you recommend a higher quality board to your management. You surely have reason enough to do so.

The last remaining thing I can think of, and it's kludgey work-around (shame on me) is:

You know the board will come back after a power-cycle. Kludge up a 555 timer circuit that powers-down the board for a second or two, and trigger it from the DTR line. This is really a broken fix for a broken board!

If my management or a client was intent on shipping a product built with these, I'd have to speak up about potential damage to the company's reputation - and possible liability, if a failure could have real consequences someone - and if necessary, write my objections to the next three levels above me. This board should not be shipped in a product.


body:
I have two Adapters, one is rated as Output 12V 500mA (used to power an old modem) and another one is rated as 5V 1A (old mobile phone charger).

My question is can use any of these to power my Arduino UNO with a barrel connector?

What does it mean when any adapter is rated as Output DC 5V 1A, Does it mean maximum we can draw 1A of current through it? What will happen if I draw more current than that.

title: Can I use 5V 1A Adapter to power Arduino UNO?

Answers: 1

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

If we look at [technical specifications][2], it is recommended to supply voltage from 7-12V so use your adapter 12V/500mA (**never go above 20V**). 5V/1A adapter is not enough when connecting via DC barrel jack according to technical specifications.

  [1]: https://i.stack.imgur.com/Ep3D4.jpg
  [2]: https://www.arduino.cc/en/Main/ArduinoBoardUno


body:
Trying to shift out from ATtiny85 to a shift register using the USI in SPI mode. I have Timer 0 running as slowly as possible (checked it was running by temporarily changing it to toggle a pin with an LED attached.) I have LEDs hooked up to USCK and DO so by rights I should be able to see them blinking as it sends.

What else do I need to do in order to get it shifting out in sync with Timer 0? All the examples I've looked at so far strobe the USI clock manually.

    #include <avr/io.h>

    int main(void){
     DDRB = (1 << DDB2) | (1 << DDB1); // USCK & DO Output
     DDRB &= ~(1 << DDB0); // DI Input
     PORTB |= (1 << DDB0); // Pullup Resistor for DI

     TCCR0A = (1 << WGM01); // Timer 0 in CTC Mode
     OCR0A = 0xFF; // Timer 0 Compare A
     TCCR0B = (1 << CS02) | (1 << CS00); // Prescaler / 1024

     USICR = (1 << USIWM0); // USI 3 Wire Mode
     USICR |= (1 << USICS0); // Timer 0 for USI 4-bit Clock Source

     USIDR = 0x7F; // Why you no go? :c

        USISR |= 0x08; // Set Counter to 8
        USISR = (1 << USIOIF); // Clear Counter Overflow

     while(1);
     return 0;
    }

title: ATtiny85 SPI with Timer 0

Answers: 1

body: Did you forget to load the counter and clear flags in USISR?


body:
I am using adxl335 accelerometer with Arduino uno r3 to measure acceleration due to gravity along x axis. I am using 50 ms delay and printing to serial.
I have two questions, which are;

 - Can I measure fractional values, like .8 in acceleration due to gravity?
 - when I shake the accelerometer up down along x axis, I don't see any variations in 'g'?

I am using analog pins and 3.3V power supply from Arduino to power the sensor.

title: Measuring acceleration in g's

Answers: 1

body:
If you read the [datasheet](http://www.analog.com/media/en/technical-documentation/data-sheets/ADXL335.pdf) you can quickly find that the output of the device is 300mV per *g*.  That means:

1. Read the analog value
2. Convert it to millivolts
3. Divide it by 300

The result is the *g* value.  If you do it using floating point then yes, you get fractions of a *g* resolution.

For instance:

    float mv = analogRead(0) / 1023.0 * 5000.0;
    float g = mv / 300.0;

If the analog channel has 1024 steps, that's 5/1024 = 0.0048828V per step, or 4.8828mV per step.  Divide that by 300 and you get a resolution of 0.01628g

As for not seeing variations in X when you shake up and down, maybe that is because you really want to look at the Z axis, not the X. X is left/right, Y is forward/backward and Z is up/down.  It's all in the [datasheet](http://www.analog.com/media/en/technical-documentation/data-sheets/ADXL335.pdf) - it makes for good reading, I suggest you take a look.


body:
I want to use LDR to control a light bulb (12W) which runs on AC supply using Arduino.

Is it possible to do this?

If yes, how?

title: How can I use arduino board for AC mains?

Answers: 4

body:
The quick and dirty answer is that you need something that will safely handle the mains voltage that you can control with the Arduino (which is running at 5 (or 3.3) volts). There are two issues you need to consider:

1. Safety – keeping the mains voltage separate from the Arduino and the other low voltage components so that nobody gets hurt.

1. Capability of components – avoiding damage to the Arduino and related components due to the mains voltage.

A common way of achieving the second goal is with either a relay or a solid-state component like a triac.

The first goal is often accomplished by using an optocoupler – a device that isolates the low-voltage circuitry from the higher mains voltage by means of an LED and a photo transistor in a common housing.

The circuitry around the relay and optocoupler aren't all that complicated but it isn't trivial either. You might look on e-bay – a search for "arduino relay" will find you lots of modules that will do the job for you.

body:
You can use a relay shield like these:
[Relay Boards - eBay][1]

Be sure to check the amp draw of the relays. Sometimes you need a transistor, but I don't think you should for these shields. Just be careful working with mains voltage.

  [1]: http://www.ebay.com/bhp/arduino-relay-shield

body:
Try the [PowerSwitch Tail II][1].

This is suitable if you are living in the USA (120VAC power).
You will find 240VAC versions as a kit on that web page as well.

  [1]: http://www.powerswitchtail.com/Pages/default.aspx

body:
If you want to switch it on/off, there is a simple solution using a relay and an optocupler (safer option) or transistor. Here is a [schematic][1]:

[![Schematic][2]][2]

but if you want to control intensity of light, then you have to use triac control, which you have explained here: [AC Phase Control][3].

  [1]: http://yourduino.com/p/OptoRelayChannelData-575.jpg
  [2]: https://i.stack.imgur.com/9NFDA.jpg
  [3]: http://playground.arduino.cc/Main/ACPhaseControl


body:
 - Suggest Hardwares to use and also suggest some place to learn about
   IoT, video tutorials, websites, blogs, books etc.

 - Currently I am using Xbees to communicate between LabVIEW and Arduino Mega.

 - Most of the websites that I checked are using ESP8266 but I am not
   sure how to use them to receive and transmit simultaneously.
[![enter image description here][1]][1][![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/az5Or.jpg
  [2]: https://i.stack.imgur.com/EheAs.jpg

title: Suggest some ways to communicate (Rx and Tx) between Arduino and LabVIEW through Internet

Answers: 0


body:
I have an [Arducam][1] hooked up to an Arduino UNO.  The code I am running looks like this:

    #include <Wire.h>
    #include <ArduCAM.h>
    #include <SPI.h>
    #include "memorysaver.h"

    const int CS = 10;

    ArduCAM myCAM(OV5642, CS);

    void setup() {
      uint8_t vid, pid;

      Wire.begin();
      Serial.begin(115200);
      pinMode(CS, OUTPUT);

      SPI.begin();

      //Check if the camera module type is OV5642
      myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
      myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);

      if ((vid != 0x56) || (pid != 0x42))
        Serial.println("Can't find OV5642 module!");
      else
        Serial.println("OV5642 detected.");

    ...

and the rdSensorReg16_8 function from the library:

    //I2C Write 8bit address, 16bit data
    byte ArduCAM::wrSensorReg8_16(int regID, int regDat)
    {
     Wire.beginTransmission(sensor_addr >> 1);
     Wire.write(regID & 0x00FF);

     Wire.write(regDat >> 8);            // sends data byte, MSB first
       Wire.write(regDat & 0x00FF);

     if(Wire.endTransmission())
     {
      return 0;
     }

     delay(1);
       return(1);
    }

The problem I am experiencing is that sometimes I will receive the "Can't find OV5642 module!" message, and other times everything is fine and I receive "OV5642 detected" (I have the OV5642 module hooked up, so it should always be returning detected).

I have tried using different cables to connect the camera to my UNO.  I have tried swapping out my USB cable.  I have tried using a 12v wall adapter to power the UNO. None of these options permanently solved my problem - I still receive both messages interchangeably.

One thing that *seems* like it is adding consistency is when I change which USB port on my computer the cable is plugged into.  Every time I switch the USB port I am using, it seems like for the first run I'll receive the successful "OV5642 detected" message, but after reseting the Arduino or re-uploading my sketch, I go back to the "Can't find OV5642 module!" message.

Can anyone help me troubleshoot why I am getting inconsistent readings?  Thank you.

  [1]: https://github.com/ArduCAM/Arduino/tree/master/ArduCAM

title: Arduino UNO inconsistent I2C register reading from ArduCam

Answers: 1

body:
I would start by adding a short delay before SPI.begin() and verifying that the power drawn does not exceed 500 mA.

The product description describes the power on sequence. [OV5642][1]

  [1]: http://www.uctronics.com/download/cam_module/OV5642DS.pdf


body:
What is the simplest (from a user/install standpoint) 2a stepper motor driver for an Arduino Uno?

I would like something simple and easy to stack like the [Adafruit Motor/Stepper/Servo Shield for Arduino v2 Kit][1]  but unfortunately it only handles 1.2a. I can do basic soldering but I would like to keep things simple and physically stacked or connected if possible. I don't want to use jumpers or a breadboard.

I am trying to run this stepper to simply open and close a door every few hours:
[14:1 Planetary Gearbox High Torque Nema 17 Stepper][2]

Using this battery from Amazon:
ExpertPower EXP1250 12V 5Ah

If I'm missing anything please let me know. Your feedback is appreciated.

  [1]: https://www.adafruit.com/products/1438
  [2]: http://www.amazon.com/gp/product/B00QA8XUGC/ref=pd_lpo_sbs_dp_ss_1/188-2257396-2936322?pf_rd_m=ATVPDKIKX0DER&pf_rd_s=lpo-top-stripe-1&pf_rd_r=1T8J28MT87X6WFXKM0B0&pf_rd_t=201&pf_rd_p=1944687742&pf_rd_i=B00PNER7JA

title: Best 2a stepper motor driver for Arduino Uno

Answers: 0


body:
Hi me and a friend is making a computer shelf with leds in the woodwork, were using a special glue for the plexiglass in the shelf which means we're using individual rgb leds, four leds for each window (3 windows) and what I need help with is, amount of voltage, ampere, code and how to connect all this up. I've used 123d.io to sketch something up but I'm struggling with getting proper strength in the leds.

![Sketch](https://puu.sh/lI6IU/0aca425cce.png)

(code https://puu.sh/lI6PC/e214028b07.txt)

Aswell as some of them change colors as the picture here shows:
![On](https://puu.sh/lI7h4/980d8e7a00.png)

I'm very new at these things so I really appreciate all help and advice (and from an earlier post, reason for not using strips is purely based on the method of build, the shelf will not sit correct if the strips were in use)

title: Multiple rgb control plus calculation help

Answers: 2

body:
It's not advised to connect leds in parallel, with only one common resistor. Slight difference in forward voltage of the leds will create big current differences. This will make some leds appear brighter that neighboring leds. It can also damage the brighter led since too much current can flow through them. So you need to add a resistor to each led, and common the other side of these resistors to the transistor.

Second bigger error is that there isn't any resistor between the arduino pin and the base of the transistor. Without it there is nothing limiting the current going into the base, which could fry the arduino pin.

body:
There's a lot to unpack here, this is actually several questions.

First of all, the way your circuit is designed currently, your data pins are connected via the transistors to ground. This means if you set a pin high, or use analogWrite(), the Arduino will pump as much current as it can get, directly into the ground. This can damage the Arduino. Put a resistor between the pin, and the transistor.

The first point is that you are using several LEDs. If you want to control them separately, you will need 3 pins per colour. AnalogWrite() only works on PWM pins - if you look at your Uno, you can see that some of the pins are marked with a ~ (pin 3,45,6,9,10,11) - these are the only ones you can (easily) use. Since there are 6 of them, you could only run 2 LEDs this way. You could either run the project on multiple arduinos (1 Arduino per 2 "windows"), or you can get a chip to do the heavy lifting for you. I am working on a similar project, and am using a TLC5940 - there is a thorough tutorial at http://playground.arduino.cc/Learning/TLC5940 - they also save you from having all the resistors and transistors, and each TLC5940 will run up to 16 LED-pins (3 per LED, so you can run up to 5 "windows"). They are also designed to daisy chain, so if you need more, you can just add another chip; no extra Arduino pins to worry about. 3 of them can run all 12 of your LEDs independently.

The next item to be aware of is that there is a limit to how much power (in Amps, or milliAmps) you can draw from a given power source. Each part will use a certain number of millAmps. The spec sheet for your parts should tell you how many. LEDs are generally around 20mA (per colour), but this varies - check the datasheet. An Arduino uses about 50mA. This means that if all 12 of your LEDs are bright white, you will be drawing 50mA+(20mA * 12 * 3) = 770mA.

How does this affect you? Well, if your project draws less than the power source can provide, you're golden! You can't provide "too much current" to a component - it will draw what it needs. When you draw more than the supply can supply, you get one of two results. If it runs on the mains, it will overheat, and eventually either burn out, or catch fire (there are exceptions to this, but you'd better be sure of your facts before risking it!). How long this takes, depends on how much current you are drawing, and how much margin there is on the power supply. In the case of a battery, the battery will drop in voltage, and will also heat up (but is much less likely to catch fire). I suspect this is happening here. If you have a multimeter, you can hook up your circuit to batteries, and then measure the voltage between + and - on the batteries.

P.S - +1 to @Gerben - you need one resistor per LED leg (except common). If you use the TLC5940, you would need 3 TLC5940s; as I said before, you can daisy-chain them. This does, however, mean that you can control each LED individually.


body:
I've also asked this question over on stack exchange so I'll link the actual question [here][1].

The short story is I have a plot that updates in real time from data collected on an Arduino. The plot updates on a 50ms + overhead interval and I can either choose on the Arduino side to either delay the loop 50ms + compensation or use `flush()`. I'm running into some problems with the delay option where my program begins to lag (Python side). I'm wondering if flush will work as I expect and hold the output until my python program reads from the serial port. So then the Python program is completely controlling the flow of data every time it polls for an update.

Edit: Here's a snippet of the code.

    void loop() {
      // put your main code here, to run repeatedly:
      val1 = analogRead(0);
      val2 = analogRead(1);
      Serial.print(val1);
      Serial.print(" ");
      Serial.print(val2);
      Serial.print("\n");
      //Serial.flush();
      delay(50);
    }

  [1]: https://stackoverflow.com/questions/34074697/interfacing-matplotlib-with-arduino

title: Interfacing Arduino with matplotlib animation

Answers: 1

body:
On the Arduino side, `flush` simply waits until the last byte has been fully transmitted.  It says nothing about how quickly it is being read by the PC.

The general problem you are having is called "flow control".  It has been solved with many different techniques, like "handshaking".  For example, the PC could send a character when it has received the last byte of a data set (a line, as returned by `readline`):

    line = self.ser.readline()
    self.ser.write("!"); // Tell Arduino line was received
    line = line.split()

While the PC proceeds to parse the line, the Arduino will eventually receive the handshake character:

    void loop()
    {
      // Send a line
      Serial.println( ... );

      // Wait for handshake character
      bool gotHandshake;
      do {
        while (!Serial.available())
          ; // wait for chars
        char c = Serial.read();
        gotHandshake = (c == '!');
      } while (!gotHandshake);
    }

Then the Arduino can proceed to send the next data set (i.e., a line).  The OS on the PC will buffer characters from the Arduino until the python program receives them with `readline` and sends another handshake character.  No `delay` required.


body: I have a large quantity of gyro values and I read them through the Arduino serial monitor. I'd like to know how I can use these values in other programming languages (such as C/C++/Java) after the values are read. Are there particular  libraries for the Arduino that could help me in this way?

title: Read gyro output values with other programming languages

Answers: 2

body: If your Arduino sketch is printing the data as ASCII numeric strings (human-readable), then any language with support for reading and writing to a serial device can interact with your Arduino on the port it is connected to, and collect the gyro data as it is being sent.

body:
Yes, of course you can.

In C/C++ there are different libraries depending on your operating system - that is if you even really need a library to help you at all (in Linux you certainly don't - you just use standard system calls - open, read, etc).

In Java there are a few different ones.  RXTX is a common (though not very good) one.  Personally I ise JSSC(Java Simple Serial Connector) since it contains the JNI files for all the main platforms - you don't have to get the right separate library packages for your specific OS like you do with RXTX.

Then of course there's things like PySerial for Python, Device::SerialPort for Perl, and whatever nonsense Microsoft have created for C# and their .NET stuff.

So in general: pick a language you are comfortable with, then ask Google how to use the serial port in it.


body:
I have just started my first project. I got through with 2 periodically blinking LEDs. Now I want one LED (blue) to be lit constantly and the other (red) to be blinking as before. Can anyone help me with this?

This is my code for blinking LEDs.

    int red_led = 4;
    int blue_led = 3;

    void setup() {

      pinMode(red_led, OUTPUT);

      pinMode(blue_led, OUTPUT);

    }

    void loop() {

      digitalWrite(blue_led, LOW);

      digitalWrite(red_led, HIGH);

      delay(1000);

      digitalWrite(blue_led, HIGH);

      digitalWrite(red_led, LOW);

      delay(1000);

     }

title: One LED being constant and another blinking

Answers: 2

body:
The wonderful thing about the Arduino is that it hides a lot of the programming "noise" and lets you concentrate on the code that is actually doing the work. Part of the joy of programming is starting to "own" the code and being able to make it do what you want.

The answer here isn't too hard, and I'm sure that many could answer your question – but I think you might enjoy the experience more (and you would earn more respect) if you make a stab at it yourself first. Or if you already have, tell us what you've tried and what happened when you tried it. That will help us help you to see not only the steps necessary, but the concepts that will enable you to branch off on your own.

Do you know what is causing the LEDs to blink in your current code?

body:
Remember that the setup() function runs once, and then the loop() function runs forever.  So to keep the blue LED light, simply turn it on, but never off.  The code for the red LED remains unchanged.

    const int red_led  = 4;
    const int blue_led = 3;

    void setup()
    {
        pinMode(red_led, OUTPUT);
        pinMode(blue_led, OUTPUT);

        digitalWrite(blue_led, HIGH);  // LED On
    }

    void loop()
    {
        digitalWrite(red_led, HIGH);  // LED On
        delay(1000);
        digitalWrite(red_led, LOW);   // LED Off
        delay(1000);
    }


body:
I was creating Arduino function which sends two `int` and additional `char`s between them and at the beginning and end of `char` array - then print that array to the serial port in almost real time. (For example "X50Y100T".)

I don't want to use `String` object in Arduino and I found two possible solutions:

 - Using `sprintf()`:

        char sendBuffer[16];
        void dataSend(int first, int second) {
          sprintf(sendBuffer, "X%dY%dT", first, second);
          Serial.println(sendBuffer);
        };

 - Or something like this:

        char sendBuffer[16];
        void dataSend(int first, int second){
          char convert[6];
          sendBuffer[0] = 'X';

          itoa(first, convert, 10);
          strcat(sendBuffer, convert);

          sendBuffer[strlen(sendBuffer)] = 'Y';

          itoa(second, convert, 10);
          strcat(sendBuffer, convert);

          sendBuffer[strlen(sendBuffer)] = 'T';

          Serial.println(sendBuffer);
          memset(sendBuffer,0,sizeof(sendBuffer));
        };

My question is - which one is better from technical point of view?

The `sprintf()` looks better but it increases the sketch size by ~1,5KB. Are there any other drawbacks of `sprintf()`? The second solution do many things to achieve same thing and I don't know if it's efficient... Maybe there are other solutions for sending this kind of `char` array?

title: What is better: one sprintf() or multiple strcat() and itoa()?

Answers: 4

body:
As a general principle code that is easy to read and modify is "better" – the problem here is that there are many "betters" to consider:

 - Readability
 - Maintainability
 - Space efficiency
 - Time efficiency

There is no universal answer to which of those is the most important. My personal bias is to start with code that is easy to read and obvious in its function. Then if time or space are an issue to start looking for ways to improve.

In your code, you could also do something like this:

      itoa(first, sendBuffer[1], 10);

Which would save you a function call and perhaps some space.

Also keep in mind that the cost of `sprintf()` in terms of space may get amortized over many uses, so it might not be as bad as it initially seems.

body:
Why do you feel you need to use either method? Neither are needed. Just print the individual parts:

    Serial.print('X');
    Serial.print(first);
    Serial.print('Y');
    Serial.print(second);
    Serial.println('T');

No intermediate buffers, just sending the data direct out to the UART.

body:
Here's a method that for some reason uses slightly fewer bytes of flash memory than Majenko's does, while producing the same output:

Add `#include <Streaming.h>` at the beginning of the program, and replace the five statements shown in Majenko's answer with the following line:

    Serial << 'X' << first << 'Y' << second << 'T' << endl;

That is, use the `Streaming.h` [contributed library](https://www.arduino.cc/en/Reference/Libraries), which adds some “syntactic sugar” to Arduino C.  At compile time it converts C++-like `<<` Serial stream operators to `Serial.print` statements, without increasing code size.  You can install it via [`Streaming5.zip`](http://arduiniana.org/Streaming/Streaming5.zip) from [arduiniana.org](http://arduiniana.org/libraries/streaming/).

When the `#if`-delimited sections in the program shown below are selected individually (by changing two of the three 01's at a time to 0's), I got the following compiled-code and RAM figures, running the program on a Nano, where all three ways appear to give the same output:

          Bytes  Bytes
    Alt.  Flash   Ram    Note
     1    2,204   182    Five Serial.print stmts
     2    3,384   190    Using snprintf()
     3    2,176   182    One Streaming stmt

I don't know whether this slight decrease (from 2204 to 2176 bytes of flash) is replicable, but the method probably is worth trying in your situation.

The program:

    #include <Streaming.h>
    void setup() {
      Serial.begin(115200);
    }
    void loop() {
      int first=50, second=100;
      //enum { first=50, second=100};
    #if 01
      Serial.print('X');
      Serial.print(first);
      Serial.print('Y');
      Serial.print(second);
      Serial.println('T');
    #endif
    #if 01
      char sendBuffer[16];
      snprintf(sendBuffer, sizeof sendBuffer, "X%dY%dT", first, second);
      Serial.println(sendBuffer);
    #endif
    #if 01
      Serial << 'X' << first << 'Y' << second << 'T' << endl;
    #endif
    }

Note, I used `snprintf()` rather than `sprintf()` because it's easier to avoid buffer overruns with `snprintf()` than with `sprintf()`.

body:
The sprintf() function has a memory cost because of the library import at compile time.  But it only costs that once, no matter how many more times you use it.  Unless you're running out of space, memory used is not a big deal.  There's no point keeping some memory unused on an Arduino.

I think it's better to use sprintf() because:

 - sprintf() produces code that is more readable, since the final output string can be easily visualised - obviously with only place holders for the variable parts.
 - Making minor changes to the output is quicker, since there's not lines of output generator functions to re-organise.
 - You end up with less code.  Less code is is easier to debug and maintain.

I would however, encourage you to use snprintf().  This function differs from sprintf() by taking the maximum buffer size as an argument.  This will help prevent problems with buffer-overruns (i.e.: accidentally putting more data into a string than in can hold)

Sprintf on Arduino does not include support for floating point numbers though.  This is quite a drawback.  One needs to use additionally use dtostrf().

The real takeaway point is this:  Only optimise your program when you need to.  [Donald Knuth][1] said: "Premature Optimisation is the root of all evil".

  [1]: https://en.wikipedia.org/wiki/Donald_Knuth


body: I would like to write code in Arduino language, compile it in the Arduino IDE, grab the resulting binary code, and flash it to the Due via the TX/RX UART pins, bypassing both the USB Programming Port and Atmel16U2 chip. Before the UART flash, I am manually toggling the Erase and Reset pins on the Due to initiate a hard reset of the SAM3X chip, and SAM-BA now waits for the code. I would like to know: can I directly grab the binary code compiled by the Arduino IDE and give it to SAM3X via UART or is there extra code baked into that binary by the Arduino compiler that would cause this method to fail?

title: Flash Arduino Due via UART

Answers: 1

body:
It depends
==========
This may not have been the answer the question was originally asked, but now it appears to be: it depends on which revision of the Due you have.

The V03 [schematics][1] on the website show a 74LVC1G125DCK part designated IC10 that is being used to translate the 5V TXD signal from the ATMega16u2 (being used as a serial transceiver) to the 3.3V logic needed for the ATSAM3X8.  As drawn the TXD line is connected to the buffer/level converter input but it is also connected to its active-low output-enable line.  In effect, they're not just using it to convert logic levels, they are also converting the signal to a kind of open collector signal.  Looking at the ATSAM3X8 datasheet shows that, yes, there is an internal pullup in the pin receiving the signal.

**If your Due is of this design,** then yes, you can program the chip by attaching a USB->logic-level-serial adapter to D0 and D1 (USART) pins and program using the SAM-BA protocol. You need to make sure you are not sending over the on-board serial transceiver while this is happening so as to not have it wired-ORing its data with your adapter. The ATMega16U2 has code in it that controls the ATSAM3X8's erase pin, as well as reset pin, by request of the PC via serial-over-USB's DTR and RTS.  Since the erase signal is not routed to outside of the Due (on its headers), you would need to use the erase button, barring some modification to the board.

**However, not all Due are of this design.** Some DUE boards have the output-enable of 74LVC1G125DCK hard-wired active rather than connected to the transceiver TXD; so on these designs it does **not** behave as open-collector, and the ATMega16u2 serial transceiver is actively driving the line when idle.  This destroys the ability to program the board over UART via pins D0 and D1.  It does however make cleaner rising edges.  Without modifying the board, no, you can't do it with this design.

Identification
--------------

So far as I can tell, whether or not your ATMega16U2->ATSAM3X8 connection is open collector/UART-programming-friendly follows the location of the buffer part.  The chip is an SC70 package, a small 5-pin thing that looks a bit like SOT23-5.  If it is located off the ATMega16U2 itself it seems you have a open-collector configuration, again so far as I've been able to tell.  If it is located next to D0, between D0 and the "COMMUNICATION" header, then you have one that drives-high.

If you have a scope, you can put it on D0 and watch the edges generated when you send traffic from the PC over the ATMega16U2 at higher baud rates.  You will either see characteristic open-collector rising edges or you won't and that will answer the question.

  [1]: https://www.arduino.cc/en/uploads/Main/arduino-Due-schematic.pdf


body:
I'm using an Arduino Uno with the Adafruit Data Logger Shield powered by a Voltaic 5V 2A battery pack. When writing to an SD card, the time stamp never changes (always reports the same now.unixtime). However, when powered from a laptop, the time stamp is correct and everything seems to be working.

The input voltage from the battery is confirmed to be just over 5V and not substantially lower the the laptop usb port.

Has anyone seen this before? Any ideas?

title: Arduino Uno data logger shield recording nonsense time

Answers: 3

body:
Where are you brining the power onto the Arduino board? If you bring it in through the external power connector you need to account for the voltage needed to run the regulator. You might be running into problems with low voltage and some part of your system that is sensitive to it.

You could try bring the power in on the 5 V pin, but then you are taking responsibility for the quality of the power supply.

body: If you are putting just over 5V into the Vin, it goes through the on-board regulator and needs a 7v minimum per https://www.arduino.cc/en/Main/ArduinoBoardUno  The Adafruit Data Logger Shield doc at https://learn.adafruit.com/downloads/pdf/adafruit-data-logger-shield.pdf shows a 9V battery pack.

body:
The problem was indeed a question of voltage.

I was using the battery to supply 5 volts to the DC power port, which as suggested by the comments needs 7 volts or more. The problem is fixed by using the battery, which supplies a stable 5V, to give power to the USB port (or, presumably the 5V pin, though that is not available in my application).


body:
I have a problem calibrating my GY-61 accelerometer on an Arduino Uno to get values in m/s2.

Analog-reading code:

<!-- language: c -->

    const int xPin = A5;
    const int yPin = A4;
    const int zPin = A3;
    // ...
    void loop() {
       int xRead = analogRead(xPin);
       int yRead = analogRead(yPin);
       int zRead = analogRead(zPin);

       float xData = (((float)xRead - 337.92) / 61.44 * 9.81);

       accData= sqrt((xData*xData)+(yData*yData)+(zData*zData));

 xData should show values in m/s2.
What do those values  `337.92`  and  `61.44` mean and how can I calibrate them to get right values?

Values I get (in one position without moving):

    xData   yData   zData    accData
    -11.16   1.61   -0.79    11.31
    -0.79  -11.48    0.01    11.51
    -0.47   -0.63  -10.68    10.71

accData should be near 9.81 m/s2, also x or y or z, depending on rotation.

title: Accelerometer sensor gy-61 convert to m/s2

Answers: 0