title: How to deal with unusual neopixel grid

text:
# Question
Title: How to deal with unusual neopixel grid
I have built a custom installation in my home with 896 WS2812 LED driven by an ArduinoMega 2560 and powered by several rails just fine. However, the installation is arranged in a checkerboard-like pattern. There are 14 panels with 8 strips of 8 LED each (64 LED per panel), The strips are soldered in zigzag pattern within a panel, and the tiles are connected via leads in a "column progressive" fashion.

Hooking this up and running it works well but I'm trying to deal with the unusual pattern I've created, and having a hard time scaling with my current solution. I am worried that my solution is not very graceful and will use up a lot of unnecessary RAM. I am currently using Adafruit's NeoMatrix library.

My solution is to "fake" like I have many more pixels and use the `setRemapFunction()` to throw these fake grid points away. But as I continue to add fake pixels, I assume the overhead RAM is set aside for them and I will max out before getting done. I have 896 real pixels total, but at this rate I'll be declaring that I have 1,792. This is my attempt to deal with the offset, and is a work in progress. This is utilizing about half of my total grid so far:

```
const int16_t grid[] = {
0,  15,  16,  31,  32,  47,  48,  63,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 256, 271, 272, 287, 288, 303, 304, 319,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
1,  14,  17,  30,  33,  46,  49,  62,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 257, 270, 273, 286, 289, 302, 305, 318,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
2,  13,  18,  29,  34,  45,  50,  61,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 258, 269, 274, 285, 290, 301, 306, 317,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
3,  12,  19,  28,  35,  44,  51,  60,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 259, 268, 275, 284, 291, 300, 307, 316,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
4,  11,  20,  27,  36,  43,  52,  59,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 260, 267, 276, 283, 292, 299, 308, 315,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
5,  10,  21,  26,  37,  42,  53,  58,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 261, 266, 277, 282, 293, 298, 309, 314,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
6,   9,  22,  25,  38,  41,  54,  57,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 262, 265, 278, 281, 294, 297, 310, 313,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
7,   8,  23,  24,  39,  40,  55,  56,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 263, 264, 279, 280, 295, 296, 311, 312,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,

-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 128, 143, 144, 159, 160, 175, 176, 191,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 384, 399, 400, 415, 416, 431, 432, 447,
-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 129, 142, 145, 158, 161, 174, 177, 190,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 385, 398, 401, 414, 417, 430, 433, 446,
-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 130, 141, 146, 157, 162, 173, 178, 189,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 386, 397, 402, 413, 418, 429, 434, 445,
-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 131, 140, 147, 156, 163, 172, 179, 188,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 387, 396, 403, 412, 419, 428, 435, 444,
-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 132, 139, 148, 155, 164, 171, 180, 187,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 388, 395, 404, 411, 420, 427, 436, 443,
-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 133, 138, 149, 154, 165, 170, 181, 186,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 389, 394, 405, 410, 421, 426, 437, 442,
-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 134, 137, 150, 153, 166, 169, 182, 185,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 390, 393, 406, 409, 422, 425, 438, 441,
-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 135, 136, 151, 152, 167, 168, 183, 184,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 391, 392, 407, 408, 423, 424, 439, 440,

64,  79,  80,  95,  96, 111, 112, 127,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 320, 335, 336, 351, 352, 367, 368, 383,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
65,  78,  81,  94,  97, 110, 113, 126,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 321, 334, 337, 350, 353, 366, 369, 382,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
66,  77,  82,  93,  98, 109, 114, 125,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 322, 333, 338, 349, 354, 365, 370, 381,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
67,  76,  83,  92,  99, 108, 115, 124,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 323, 332, 339, 348, 355, 364, 371, 380,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
68,  75,  84,  91, 100, 107, 116, 123,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 324, 331, 340, 347, 356, 363, 372, 379,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
69,  74,  85,  90, 101, 106, 117, 122,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 325, 330, 341, 346, 357, 362, 373, 378,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
70,  73,  86,  89, 102, 105, 118, 121,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 326, 329, 342, 345, 358, 361, 374, 377,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
71,  72,  87,  88, 103, 104, 119, 120,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 327, 328, 343, 344, 359, 360, 375, 376,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,

-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 192, 207, 208, 223, 224, 239, 240, 255,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 448, 463, 464, 479, 480, 495, 496, 511,
-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 193, 206, 209, 222, 225, 238, 241, 254,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 449, 462, 465, 478, 481, 494, 497, 510,
-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 194, 205, 210, 221, 226, 237, 242, 253,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 450, 461, 466, 477, 482, 493, 498, 509,
-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 195, 204, 211, 220, 227, 236, 243, 252,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 451, 460, 467, 476, 483, 492, 499, 508,
-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 196, 203, 212, 219, 228, 235, 244, 251,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 452, 459, 468, 475, 484, 491, 500, 507,
-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 197, 202, 213, 218, 229, 234, 245, 250,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 453, 458, 469, 474, 485, 490, 501, 506,
-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 198, 201, 214, 217, 230, 233, 246, 249,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 454, 457, 470, 473, 486, 489, 502, 505,
-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 199, 200, 215, 216, 231, 232, 247, 248,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 455, 456, 471, 472, 487, 488, 503, 504,

};

```

I am using this like so:

```
#define PIN 6

#define WIDTH 32 // So far. Will be 56 when I finish creating array.
#define HEIGHT 32

/**
 * Setup the lightwall matrix.
 *
 * Each panel is 8x8 pixels. There are 7 columns and 2 rows,
 * but they are arranged in a checkerboard pattern.
 */
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(WIDTH, HEIGHT,PIN,
  NEO_MATRIX_TOP     + NEO_MATRIX_LEFT +
  NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
  NEO_GRBW           + NEO_KHZ800
);

uint16_t remapXY(uint16_t x, uint16_t y) {
  y = y * WIDTH + x;
  return grid[y];
}

void setup() {
  matrix.setRemapFunction(remapXY);
  matrix.begin();
}

```

So the `remapXY()` returns the correct key of the array, thus the reason for the crazy array pasted above. And that array is only halfway complete (tediously typing it out!)

But so far it is working. I have a pacman animation (not pictured) scrolling across the screen and being "off screen" for a believable amount of time. That is the whole point of this madness. But am I going about it all wrong? Attached is also a picture of the full visible matrix for visual aid.

Starting from the upper left corner is panel 1, then lower left panel 2. Next column top is panel 3, bottom panel 4. And so on.

So will I need more RAM in order for this to be performant? Or is there a better way to code my way out of this problem? I have a lot of animations and ambient effects planned, not all of which will strictly require this offset.

Is there another way to "mask" or delay some pixels off screen temporarily based on where they should be? Only to put them back where they belong afterward?

# Answer
break it down into blocks to determine the upper left corner of any 8x8 grid

```
const int16_t grid[8][8] = {
       {0,  15,  16,  31,  32,  47,  48,  63},
       {1,  14,  17,  30,  33,  46,  49,  62},
       {2,  13,  18,  29,  34,  45,  50,  61},
       {3,  12,  19,  28,  35,  44,  51,  60},
       {4,  11,  20,  27,  36,  43,  52,  59},
       {5,  10,  21,  26,  37,  42,  53,  58},
       {6,   9,  22,  25,  38,  41,  54,  57},
       {7,   8,  23,  24,  39,  40,  55,  56}
};

const int16_t block[7][4] = {
       { 0,  -1,   4,  -1,   8,  -1,  12},
       {-1,   2,  -1,   6,  -1,  10,  -1},
       { 1,  -1,   5,  -1,   9,  -1,  13},
       {-1,   3,  -1,   7,  -1,  11,  -1}
};

blockNumber = block[x/8][y/8];

// some checking for the -1 value

pixelNumber = blockNumber * 64 + grid[x%8][y%8]

//

```
> 3 votes

# Answer
This indeed looks awesome!

I suggest getting rid of the big `grid` array, and instead generate the mapping programmatically. Given that it is very regular, the mapping can be computed instead of stored:

```
uint16_t remapXY(uint16_t x, uint16_t y) {

    // Compute panel position and offset of pixel within that panel.
    uint8_t pannel_x = x / 8;
    uint8_t offset_x = x % 8;
    uint8_t pannel_y = y / 8;
    uint8_t offset_y = y % 8;

    // Is this a missing panel?
    if ((pannel_x + pannel_y) & 1)
        return -1;

    // Compute panel number.
    uint8_t pannel = pannel_y / 2 + pannel_x * 2;

    // LED index within the panel.
    uint8_t led = 8 * offset_x;

    if (offset_x & 1)  // numbered bottom to top
        led += 7 - offset_y;
    else               // numbered top to bottom
        led += offset_y;

    return pannel * 64 + led;
}

```

I hope this will save enough memory to make the whole thing work.
> 2 votes

---
Tags: arduino-mega, neopixel, ws2812
---


# Question
Title: Does the ESP8266 somehow remember wifi access data?
Today I did some tinkering with an ESP8266, trying out OTA and writing a webserver. To find an error, I reduced the sketch to just the following lines:

```
#include <ESP8266WebServer.h>

ESP8266WebServer server(80);

void setup() {
  Serial.begin(115200);
  server.on("/", []() {
    Serial.println("Sending response...");
    server.send(200, "text/plain", "Hi there!");
  });
  server.begin();
}

void loop() {
  server.handleClient();
}

```

Notice that there is no code to connect to a Wifi network. However, the chip still connects to my local, WPA2-secured, network on every boot. I can ping the chip, my browser can get the "Hi there!" message via http, the Serial message gets printed.

How is this possible? Does the ESP8266 somehow retain the Wifi information, maybe because of some old OTA data that was not completely overwritten?

I'm using platformio. Here's my entire platformio.ini:

```
[env:d1_mini]
platform = espressif8266
board = d1_mini
framework = arduino

```

I posted the compile and upload log here: https://pastebin.com/BtGrFZiu

# Answer
> 15 votes
Yes, normally the last WiFi credentials will be saved in flash and the ESP8266 loads this data on bootup and reconnect to the last known WiFi. See https://github.com/esp8266/Arduino/issues/2843#issuecomment-334250100:

> the SDK stores some info, including the wifi credentials, in a sector of the flash.
>
> That sector is kept between flashings to allow for a quick startup after update. On boot, before your sketch is executed, the SDK will retrieve the wifi credentials and attempt a quick connection.

This behaviour can be controlled by using the function `WiFi.setAutoConnect(autoConnect)` as documented in https://github.com/esp8266/Arduino/blob/master/doc/esp8266wifi/station-class.rst#setautoconnect. This in turn calls the Espressif SDK function `wifi_station_set_auto_connect` (API reference)

In short: This is normal behaviour. If you want to make sure that your ESP8266 does not connect to any WiFi unless you tell it do it explicitly, call `WiFi.setAutoConnect(autoConnect)` at the beginning.

Edit: From within the firmware code, you can use `system_restore`. The documentation says that it would reset WiFi related data. This should destroy previous settings. The function can be included from https://github.com/esp8266/Arduino/blob/master/tools/sdk/include/user\_interface.h within Arduino-ESP8266. I have not tried this myself nor can I say that it actually erases security-critical information from flash though.

Or, as you also have found out, hard-erasing the entire flash will purge the WiFi data with absolute certainty. This can be achieved by using `esptool.py` with the `erase_flash` option, e.g. `python esptool.py -p COM6 erase_flash`. Then you can flash the new firmware which will not use previous WiFi settings (but will probably open up the default access point again).

Then there's also `ESP.eraseConfig` which erases only the relevant flash sectors.

---
Tags: esp8266, wifi
---


# Question
Title: Do prototypes need to follow the order of the functions?
I define prototypes prior to calling the functions.

Does the order of the prototypes have to match the order of the functions in the code?

I'd like to sort the prototypes alphabetically, while I wouldn't care in which order they appear in the code.

I am after common or best practice.

# Answer
There is no specific best practice in this regard.

The rest of this answer is primarily opinion based, and hence off topic for this site.

If you have classes it's common, but in no way required, universal or "bad" not to do, to group the public, private and protected methods together.

Really, group them in a way which makes sense for your program - related functions together. If you have so many methods / functions that they need a lot of organizing, split them into groups of related functionality - using classes or whatever.
> 0 votes

# Answer
> Does the order of the prototypes have to match the order of the functions in the code?

No.

> I'd like to sort the prototypes alphabetically, while I wouldn't care in which order they appear in the code.

You can do that. It would make the prototype easier to find, I suppose, however most editors these days have search functions.

> I am after common or best practice.

Because the Arduino IDE automatically generates function prototypes the common practice is not to use them at all.

If you want to know best practice **in general** I suggest you ask on Stack Overflow.

---

Years ago I programmed Burroughs Medium Systems in BPL (Burroughs Programming Language), a language similar to Algol (which Pascal looks a bit like).

In BPL you could not use a function or variable which had not been previously defined. Thus, the "main" function would always appear at the end of the source file. Major functions (called by the main function) would therefore precede it, and minor functions would appear earlier again. Thus you could tell the hierarchy of function calls, roughly, by the order in which the functions appeared.

In C (and C++) you don't need function prototypes if you have all your code in a single file, and if you follow that convention. Put the main code at the end and the things it calls before them. You only need function prototypes then in unusual cases where A might call B but B might call A.
> 1 votes

---
Tags: programming, c, prototype
---


# Question
Title: Use SD Card while Pin 11 is being used for PWM
On Arduino Uno Rev3, I just ran the `speaker_pcm` demo that used TIMER1 and TIMER2 to generate a PWM wave. However, this means that the Pins 3, 9, 10 and 11 can not be used anymore; according to the documentation:

```
Takes over Timer 1 (16-bit) for the 8000 Hz timer. This breaks PWM
(analogWrite()) for Arduino pins 9 and 10. Takes Timer 2 (8-bit)
for the pulse width modulation, breaking PWM for pins 11 & 3.

```

I wanted to change the program such that the WAV data was read from a SD card. However, this is what documentation for `SD.h` library says:

```
The communication between the microcontroller and the SD card uses SPI,
which takes place on digital pins 11, 12, and 13 (on most Arduino boards)

```

This means both the `SD.h` and `speaker_pcm` want to use pin 11, and the requirement to use these pins is dictated by the hardware. I am guessing that this clash will create problems.

Is there any way I can make this work? Can I switch between SD card reading and Audio playing somehow (essentially multiplexing in software)? Or will this collision of pin usage not be a problem?

# Answer
The program you link to does *not* take over pins 3, 9, 10 and 11, it takes over Timer 1 and Timer 2, which are used to provide PWM capability on those pins. This means you cannot do `analogWrite()` on those pins anymore, but you still can use them for other purposes, including SPI access to an SD card.

Note, however, this line of code:

```
int speakerPin = 11; // Can be either 3 or 11, two PWM outputs connected to Timer 2

```

This of course will conflict the SPI port using pin 11 as MOSI. You can fix this conflict simply by setting `speakerPin` to 3 instead of 11.
> 3 votes

---
Tags: arduino-uno, pwm, sd-card
---


title: When RFID tag is removed

text:
# Question
Title: When RFID tag is removed
After rewriting and getting a good grip on what I have got in my sketch so far, I need some assistance.

So in my sketch I can play an MP3 track with a certain tag, but when that tag is removed I can't start the fading out process.

So for all that helped on previous ones, where I just mashed a lot of code together and hoped for the best, this one should start to have some good foundations to build on.

But I'm stuck on the part that's commented out.

//rfid

```
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN         9  // reset pin 9
#define SS_PIN          10 // sda pin 10
MFRC522 rfid(SS_PIN, RST_PIN); // Create MFRC522 instance

// = 0001.mp3    8C DE 63 A9   uid's for me to relate to mp3 tracks.
// = 0002.mp3    0A 97 F3 16 /
// = 0003.mp3    3A 5F DE 16

//mp3 player
#include<SoftwareSerial.h>
int mp3Pin[2] = { 5, 4 }; //Rx/Rx

// For the checksum to the mp3
#define startByte 0x7E
#define endByte 0xEF
#define versionByte 0xFF
#define dataLength 0x06
#define infoReq 0x01

SoftwareSerial mp3(mp3Pin[0], mp3Pin[1]); // Rx, Tx

void setup() {
  Serial.begin(9600); // Initialize serial communications with the PC
  SPI.begin(); // Init SPI bus
  rfid.PCD_Init(); // Init MFRC522
  rfid.PCD_DumpVersionToSerial(); // Print version of RFID

  //Mp3
  mp3.begin(9600); // Init mp3
  delay(1000);
  sendMP3Command(0x3F, 0, 0); // Send request for initialization parameters
  sendMP3Command(0x06, 0, 20); // Vol set to 30
  sendMP3Command(0x07, 0, 0); // EQ = pop
}

void loop() {
  // Look for new cards
  if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
    //In new card found and new serial
    /*printHex(rfid.uid.uidByte, rfid.uid.size); // Print the Hex uid &
      Serial.println(); // use to get new uids.*/
    {
      String content = "";
      byte letter;
      for (byte i = 0; i < rfid.uid.size; i++) {
        content.concat(String(rfid.uid.uidByte[i] < 0x10 ? " 0" : " "));
        content.concat(String(rfid.uid.uidByte[i], HEX));
      }
      content.toUpperCase();
      if (content.substring(1) == "0A 97 F3 16") {
        //change here the UID of the card/cards that you want to give access
        //Serial.println("hello World");
        Serial.println("0002.mp3");
        sendMP3Command(0x03, 0, 0002); // Play track 0002.mp3
        sendMP3Command(0x19, 0, 0); // Loop track playing
        delay(30);
      }
      /*else !rfid.PICC_IsNewCardPresent();{
        sendMP3Command(0x06, 0, 28); // Reduce vol by 2 and fade out
        delay(30);
        sendMP3Command(0x06, 0, 26);
        delay(30);
        sendMP3Command(0x06, 0, 24);
        delay(30);
        sendMP3Command(0x06, 0, 22);
        delay(30);
        sendMP3Command(0x06, 0, 20);
        delay(30);
        sendMP3Command(0x06, 0, 18);
        delay(30);
        sendMP3Command(0x06, 0, 16);
        delay(30);
        sendMP3Command(0x06, 0, 14);
        delay(30);
        sendMP3Command(0x06, 0, 12);
        delay(30);
        sendMP3Command(0x06, 0, 10);
        delay(30);
        sendMP3Command(0x06, 0, 8);
        delay(30);
        sendMP3Command(0x06, 0, 6);
        delay(30);
        sendMP3Command(0x06, 0, 4);
        delay(30);
        sendMP3Command(0x06, 0, 2);
        delay(30);
        sendMP3Command(0x06, 0, 0);
        //sendMP3Command(0x16, 0, 0); // Stop
        delay(500); // Change value if you want to read cards faster
        }*/
    }
    // Halt PICC
    rfid.PICC_HaltA();
    // Stop encryption on PCD
    rfid.PCD_StopCrypto1();
  }
}

void sendMP3Command(byte Command, byte Param1, byte Param2) {
  // Calculate the checksum
  unsigned int checkSum = -(versionByte + dataLength + Command + infoReq + Param1 + Param2);
  // Construct the command line
  byte commandBuffer[10] = { startByte, versionByte, dataLength, Command, infoReq, Param1, Param2, highByte(checkSum), lowByte(checkSum), endByte };
  for (int cnt = 0; cnt < 10; cnt++) {
    mp3.write(commandBuffer[cnt]);
  } // Delay needed between successive commands delay(30); }
  /*   // Print the Hex uid & use to get new uids.
    void printHex(byte * buffer, byte bufferSize) {
    for (byte i = 0; i < bufferSize; i++) {
      Serial.print(buffer[i] < 0x10 ? " 0" : " ");
      Serial.print(buffer[i], HEX);
    }
    }*/

```

# Answer
Basically, you have written this code:

```
void loop()
{
  // Look for new cards
  if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial())
  {
    {
      // ...
      if (content.substring(1) == "0A 97 F3 16")
      {
        // play
      } else
      {
        // stop
      }
    }
    // ...
  }
}

```

Try something like this:

```
bool playing = false;

void loop()
{
  // Look for new cards
  if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial())
  {
    // ...
    if (content.substring(1) == "0A 97 F3 16")
    {
      // play
      playing = true;
    }
    // ...
  }
  if (playing && !anyCardPresent())
  {
    // stop
    playing = false;
  }
}

```

and for the implementation od anyCardPresent refer to this discussion \- if more consecutive calls of PICC\_ReadCardSerial fail, you can consider this as card being removed
> 1 votes

---
Tags: programming
---


title: Variables not saving

text:
# Question
Title: Variables not saving
I'm trying to write web server code. However, I am having trouble with part of it.

Currently, to get it to save a bool variable I have it use a pin, as when I ran the code without it, after the page refreshes it resets the variable to its original value.

How do I get it to save the variable in this code without it using the pin?

```
digitalWrite (equalPin, server.arg("equal").toInt());
char equalText[80];
if(equalState) {
  strcpy(equalText, "priority is equal. <a href=\"/?equal=0\">Deactivate</a>");
  equalState = false;
} else {
  strcpy(equalText, "priority is not equal. <a href=\"/?equal=1\">Activate</a>");
  equalState = true;
}
equalState = digitalRead(equalPin);

```

I also have several over copies of this for different pages but if I change 1 of them they all change and reset after 10 seconds.

The code follows the example on this site.

# Answer
same code snippet without using pin

```
char equalText[80];

if (equalState){
  strcpy(equalText, "priority is equal. <a href=\"/?equal=0\">Deactivate</a>");
  equalState = false;
}
else {
  strcpy(equalText, "priority is not equal. <a href=\"/?equal=1\">Activate</a>");
  equalState = true;
}
equalState = server.arg("equal").toInt();

```

but it does not make much sense to set the value if you already switched the state based on it's previous value
> 1 votes

---
Tags: arduino-uno, esp8266, nodemcu
---


# Question
Title: Arduino Uno R1 I soldered resistor but I cannot DFU program atmega8u2
I have an Arduino R1 board (the very first one) and I managed to solder the resistor into Arduino's Atmega8u2 (I went to a specialist in order to do that). Then I reset atmega8u2 and by wiring the pins mentioned in: https://www.arduino.cc/en/Hacking/DFUProgramming8U2

I can confirm it via this message over my GNU/Linux machine by running `dmesg`:

```
[ 1544.679504] usb 1-6: new full-speed USB device number 42 using xhci_hcd
[ 1544.808341] usb 1-6: New USB device found, idVendor=03eb, idProduct=2ff7
[ 1544.808350] usb 1-6: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[ 1544.808356] usb 1-6: Product: Arduino Uno DFU

```

I also to confirm that I run `lsusb` and I got the following result:

```
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 248a:8367
Bus 001 Device 058: ID 03eb:2ff7 Atmel Corp.
Bus 001 Device 003: ID 058f:6362 Alcor Micro Corp. Flash Card Reader/Writer
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

```

Further indicating to me that arduino is in DFU mode over my ubuntu 16.04 machine. Also I further verify via `dfu-util -l` command:

```
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2014 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to dfu-util@lists.gnumonks.org

Found DFU: [03eb:2ff7] ver=0000, devnum=63, cfg=1, intf=0, alt=0, name="UNKNOWN", serial="UNKNOWN"

```

The I try to run:

`sudo dfu-programmer atmega8u2 erase`

But for some reason I get the following error: `dfu-programmer: no device present.`

Do you know why I get this error and how I can fix it?

# Edit 1

I installed the latest version of dfu-programmer and compiled from source via https://sourceforge.net/projects/dfu-programmer/files/dfu-programmer/0.7.2/ but still I get the error. I also tried to compile it with `libusb-1.0.0`

# Edit2

I also tried this version with `libusb-1.0.0` but still the same error occurs.

# Edit 3

As many suggest I tried to do multiple times but still I get this error.

# Edit 4

I also used `dfu-util` and I try to insert the data into the atmega8u2 via:

```
 sudo dfu-util -d 03eb:2ff7 -D ./Arduino-usbserial-uno.hex -R

```

But I get the error:

```
dfu-util 0.8

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2014 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to dfu-util@lists.gnumonks.org

dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
Opening DFU capable USB device...
ID 03eb:2ff7
Run-time device DFU version 0100
Claiming USB DFU Interface...
Setting Alternate Setting #0 ...
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 0100
Device returned transfer size 3072
Copying data from PC to DFU device
Download    [                         ]   0%            0 bytesdfu-util: Error during download
dfu-util: can't detach
Resetting USB to switch back to runtime mode

```

# Answer
According to https://gebloggendings.wordpress.com/category/elektronik/arduino/ it is sometimes not to assume that the `atmega8u2` is always the correct value in my case was the `at90usb82` resulting into using the following command sequence:

```
sudo dfu-programmer at90usb82 erase
# Flashing the arduino provided .hex
sudo dfu-programmer at90usb82 /usr/share/arduino/hardware/arduino/firmwares/atmegaxxu2/arduino-usbserial/Arduino-usbserial-uno.hex
# reset the board
sudo dfu-programmer at90usb82 reset

```

Further information you can find into:
> 1 votes

---
Tags: arduino-uno, usb, programmer
---


# Question
Title: 3.3v Arduino I2C communication with motor controller powered at ~6v
I am trying to just use the voltage from 4 Alkaline AA batteries in series (6v nominal) to power a motor with the TI drv8830 IC.

My question is, will this circuit (specifically just pulling the sda and scl pins to 3.3v) work reliably? The datasheet says at maximum of 6.8v vcc the chip will still recognize 3.3v i2c lines (minimum 3.13V at that vcc voltage) but will the varying voltage of the battery cause the communication to be unstable? There is a 10uf capacitor between vbat and gnd (not shown).

# Answer
> will the varying voltage of the battery cause the communication to be unstable?

No. As the battery voltage drops the input HIGH threshold (which is a function of VCC) also drops. If anything as the battery voltage drops the communication becomes *more* stable.

Since I2C is an *open drain* protocol the voltage makes no different for sending data - that voltage is set by the pull-up resistors to 3.3V.
> 1 votes

---
Tags: motor, i2c, voltage-level
---


title: SIM900 and Mega 2560 not sending SMS

text:
# Question
Title: SIM900 and Mega 2560 not sending SMS
I just bought a SIM900 Arduino shield from AZDelivery. I only have a Mega 2560 board, thus I am trying to use this although most examples (like the tutorial from AZDelivery) are with the Uno board. I am using the SIM card from my mobile phone, not having any PIN. This is the Arduino library I am using.

1. I didn't flash anything on the SIM900 board prior to testing, because in the instructions from AZDelivery Ebook this was not mentioned.
2. My NetLight LED is blinking constantly (1 blink per second) I guess it is not finding the mobile network.
3. At the momemt, I only have a 1A supply, though I've already ordered a new one with 2A. Could this be the reason for point 2? Does the board need 2A to log into the network?
4. Asuming it would log into the network, the AZDelivery Instruction Sketch/Example is using "SoftwareSerial.h" due to its compatibility to the Uno board. Since I am using a Mega board, can I just use D30 and D31 and set them as Rx and Tx using the SoftwareSerial library?
5. Can you give me a link to an up-to-date library and/or example for SIM900 working with the Mega 2560 Rev3 and Arduino 1.8.4?

I hope you can help me getting started with the SIM900 module.

# Answer
I was just able to send an SMS (even with the 1A supply). Here the answers to my questions.

1. No, it is not necessary to flash the SIM900 board
2. I was not connected, because I didn't insert the SIM card properly on the shield.
3. No it does not necessarily need 2A for logging into network and obviously not for sending SMS though there might be reasons for the board consuming 2A during SMS sending, e.g. bad network connection.
4. If you want to use Sotware Serial, you need certain digital lines allowing software interrupts. In the case of the **MEGA board**, e.g. D10, D11 or for the **UNO** D7,D8.
5. I was using this tutorial to get communication via SoftwareSerial working. Afterwards I added the code for sending SMS.

I hope I can help some others who are looking for a low level description of how to get started with MEGA and SIM900.
> 2 votes

---
Tags: arduino-mega
---


title: Arduino + Solenoid Lock

text:
# Question
Title: Arduino + Solenoid Lock
I was trying to use a solenoid lock alongside the arduino, using a 12V 2A DC adapter, TIP120, and a diode.

The circuit looks something like this. However, the lock isn't going in automatically (it requires a push).

I've tested the circuit using a multimeter, and the output given by the transistor, is indeed 12V, however, when connected to the lock, the potential difference is around 8V. I don't know if that's normal, but the lock isn't going in on it's own.

Can anyone help me with this issue?

# Answer
It sounds like your 12 volt adaptor is not powerful enough to operate the lock solenoid. If you power up the solenoid **only** and **directly** using the adaptor it should work. If it doesn't, you'll need a more powerful adaptor. If it does work, then the problem is somewhere in your driver circuit or Arduino sketch.
> 1 votes

---
Tags: arduino-uno, electronics, transistor
---


# Question
Title: How to use a DC buck converter to regulate Uno R3 input voltage?
I have had a rough time trying to understand why this isn't working correctly. Quick background: I set up a system to pop open car doors using touch sensors. I heard that powering the Arduino Uno R3 straight off the car battery is not a good idea, so I bought a buck converter. I wired it up and calibrated the output on the converter for 5V. When I hooked it up to the Arduino (via the barrel jack), I experienced some odd effects. The output pins and the 5v power pins were only getting 3.5V. I had to adjust the buck converter up to about over 7V in order to get 5v on the Uno.

Then the sensors started acting oddly. Auto triggering and alternately not working. Anyone know what I am doing wrong?

Converter I bought: https://www.amazon.com/gp/product/B0159W0UL2/ref=oh\_aui\_detailpage\_o07\_s00?ie=UTF8&psc=1

# Answer
> 3 votes
The barrel jack needs 9-12 V, the internal voltage regulator of the Arduino will reduce this to 5 V.

Since you only supply 5 V, there is a loss in the internal voltage regulator why you probably get only 3.5 V.

And after applying 7 V, probably some (sub) system gets less than the necessary voltage, or there are occasional 'downspikes' lower than 5 V.

The default adapter that you use for supplying voltage to the Uno, also is 9V-12V. Also, check the polarity.

See the following link for more info:

What adapter

# Answer
> 2 votes
If you are getting a clean 5v from the buck converter, you can/should run that directly to the 5v pin on the Arduino. Using the barrel jack(at 7-12V) still uses the on board linear(inefficient) Regulator to produce the 5v the board needs. You will want to ensure you are outputing a clean 5v during all phases of the car being on/off/startup.

---
Tags: arduino-uno, battery
---


title: Understanding USBHID_DESC report

text:
# Question
Title: Understanding USBHID_DESC report
Recently Ran the USBHID\_DESC program on my Arduino Uno with a USB hub attached to my joystick. I wanted to be able to program my joystick to integrate with my project. Circuits@Home developed the code and have 2 articles dealing with understanding the report. But they are very sparse with details and only have a single example to go off of. Many of the fields that I got returned are not described at all in the tutorial. Further more, attempting to dig through the official documentation from USB.org itself has been extremely overwhelming. I don't really know how to start. Can anyone help me interpret the data fields for this controller?

This is the data that I recieved from the serial monitor:

> Start 0000: 05 01 09 04 A1 01 09 01 A1 00 09 30 09 31 09 32
> 0010: 09 BB 15 80 25 7F 46 FF 00 66 00 00 66 00 00 75
> 0020: 08 95 04 81 02 C0 09 39 15 01 25 08 35 00 46 3B
> 0030: 01 65 14 75 04 95 01 81 02 05 09 19 01 29 04 15
> 0040: 00 25 01 75 01 95 04 81 02 95 08 81 01 05 08 09
> 0050: 43 15 00 26 FF 00 35 00 46 FF 00 75 08 95 04 91
> 0060: 82 55 00 65 00 55 00 65 00 55 00 C0
> Usage Page Gen Desktop Ctrls(01)
> Usage Game Pad
> Collection Application
> Usage Pointer
> Collection Physical
> Usage X
> Usage Y
> Usage Z
> Usage Undef
> Logical Min(80)
> Logical Max(7F)
> Physical Max(FF00)
> Unit(0000)
> Unit(0000)
> Report Size(08)
> Report Count(04)
> Input(00000010)
> End Collection
> Usage Hat Switch
> Logical Min(01)
> Logical Max(08)
> Physical Min(00)
> Physical Max(3B01)
> Unit(14)
> Report Size(04)
> Report Count(01)
> Input(00000010)
> Usage Page Button(09)
> Usage Min(01)
> Usage Max(04)
> Logical Min(00)
> Logical Max(01)
> Report Size(01)
> Report Count(04)
> Input(00000010)
> Report Count(08)
> Input(00000001)
> Usage Page LEDs(08)
> Usage Slow Blk On Time
> Logical Min(00)
> Logical Max(FF00)
> Physical Min(00)
> Physical Max(FF00)
> Report Size(08)
> Report Count(04)
> Output(10000010)
> Unit Exp(00)
> Unit(00)
> Unit Exp(00)
> Unit(00)
> Unit Exp(00)
> End Collection Game Pad Pointer X Y Z Undef(00)(00)(7F)(00)
> Hat Switch(00)
> Btn0001
> (00) Btn0002
> (00) Btn0003
> (00) Btn0004
> (00)
> (00)(00)(00)(00)(00)(00)(00)(00)
> Slow Blk On Time

# Answer
It's pretty easy to follow if you indent and break it up right. Let me add some annotation too:

```
Usage Page Gen Desktop Ctrls(01)  // Usages describe what the
Usage Game Pad                    // following data is used for.
Collection Application
    Usage Pointer        // Use the settings for a physical
    Collection Physical  // pointing device
        Usage X       // It has four axes -
        Usage Y       // X, Y, Z and some other undefined axis.
        Usage Z
        Usage Undef
        Logical Min(80) // Output the values 0x80 to 0x7F, which when
        Logical Max(7F) // interpeted as signed bytes is -128 to 127.
        Physical Max(FF00) // The input has a range 0 to 255
        Unit(0000)
        Unit(0000)
        Report Size(08)  // The report value is 8 bits long,
        Report Count(04) // and there are 4 of them (one per axis)
        Input(00000010)  // This ends this "input" section.
    End Collection

    Usage Hat Switch // Describing a HAT Switch now.
    Logical Min(01)  // Interpret it as a value between 1 and 8
    Logical Max(08)
    Physical Min(00) // The input to it is between 0 and 0x3B01.
    Physical Max(3B01) // Not sure that value is interpreted properly.
    Unit(14)
    Report Size(04)  // The report has 4 bits in it,
    Report Count(01) // and there is just one of them.
    Input(00000010)  // And end the input section.

    Usage Page Button(09)  // Next come the buttons.
    Usage Min(01)      // These are basically button numbers
    Usage Max(04)      // - there's 4 buttons, 1 through 4.
    Logical Min(00)    // A button is either off (0)
    Logical Max(01)    // or on (1).
    Report Size(01)    // And can only have one state, so size 1.
    Report Count(04)   // There's 4 buttons, so 4 reports.
    Input(00000010)    // And end the input.

    Report Count(08)   // This is a special one. It keeps the settings
    Input(00000001)    // from before (the haven't been changed), but
                       // is just a dummy one to pad out the data to
                       // the right size. Alignment is key.

    Usage Page LEDs(08)    // Now we have 4 LEDs with an
    Usage Slow Blk On Time // 8-bit PWM value. 0-FF which doesn't
    Logical Min(00)        // need interpreting, so 0=0 and FF=FF.
    Logical Max(FF00)
    Physical Min(00)
    Physical Max(FF00)
    Report Size(08)    // As I said, 8 bit,
    Report Count(04)   // and there's 4 of them.
    Output(10000010)   // And it's output.

    Unit Exp(00)   // Now there seems to be a bit of junk.
    Unit(00)
    Unit Exp(00)
    Unit(00)
    Unit Exp(00)
End Collection Game Pad // And the end.

```

So interpreting that, you get a report sent to you that has:

```
Byte     Function
0        X Axis 0-255 which you map to -128 to 127
1        Y Axis 0-255 which you map to -128 to 127
2        Z Axis 0-255 which you map to -128 to 127
3        Another Axis 0-255 which you map to -128 to 127
4        Upper 4 bits buttons, lower 4 bits HAT direction
5        Padding byte to make ita multiple of 16 bits long

```

And you can send a 4 byte report where:

```
Byte     Function
0        LED 1 PWM
1        LED 2 PWM
2        LED 3 PWM
4        LED 4 PWM

```

Those "LEDs" could be force feedback motors or vibrators.

Also I suspect there is maybe a small amount of corruption or mis-interpretation of multi-byte values in the output.
> 2 votes

---
Tags: arduino-uno
---


title: Teensy 2.0 with MCP23017-E

text:
# Question
Title: Teensy 2.0 with MCP23017-E
I've recently bought two more MCP23017-E's for a project, but after hooking them up to my Teensy 2.0 I couldn't get them to react to anything. Suspecting faulty hardware, I hooked them up to an old LCP1114, and got them running just fine. I've tried porting the code I used, which still gave no result.

I'm using the following code:

```
#include "Wire.h"
const byte device=0b01000000; //default addrress of IO chip

const byte IODIRA=0x00;
const byte IODIRB=0x01;

const byte GPIOA=0x12; //IO pins, port A
const byte GPIOB=0x13; //IO pins, port B
const byte OLATA=0x14;//O pins A
const byte OLATB=0x15;//O pins B

const byte GPPUA=0x0C; //pull up resistors ,port A
const byte GPPUB=0x0D; //pull up resistors ,port B

char iCounter = 0;

void setup() {
  Wire.begin();
  seti2cbyte(device,IODIRA,0x00);
  seti2cbyte(device,IODIRB,0xFF);
  seti2cbyte(device,GPPUB,0xFF);  //enable pull-up resistors on port B
}

byte geti2cbyte(byte address, byte ptr) {
  Wire.beginTransmission(address);
  Wire.write(ptr);
  Wire.endTransmission();
  Wire.requestFrom(address, 1); // request one byte of data from MCP20317
  byte inputs=Wire.read();
  return inputs;
}

void seti2cbyte(byte address, byte ptr, byte value) {
  Wire.beginTransmission(address);
  Wire.write(ptr); // set MCP23017 memory pointer to GPPUA address
  Wire.write(value); // enable pull up resistors
  Wire.endTransmission();
}

void loop() {
  seti2cbyte(device,OLATA,iCounter);
  byte port_b = geti2cbyte(device,GPIOB); //get status of pins 21-28
  Serial.print(iCounter++);Serial.println(port_b);
  delay(500);
}

```

I don't see a blinking LED, and port\_b stays at 255 (or -1 I figured after reading the Wire.cpp)

I've tried different methods, even running SPI myself (setting pins high and low manually). The only difference I see is that the Teensy 2.0 is 5V, and the LCP1114 runs at 3.3V. The data sheet for the MCP23017-E states that it is also rated for 5V though.

Why does it seem like my MCP23017-E's won't work at 5V, while the data sheet states they should?

MCP23017-E datasheet

> • Operating Voltage: \- 1.8V to 5.5V @ -40°C to +85°C \- 2.7V to 5.5V @ -40°C to +85°C \- 4.5V to 5.5V @ -40°C to +125°C

# Answer
You have the wrong device address. You've included the R/W bit in the address, which you shouldn't. An I2C address is only 7 bits, not 8. Drop one bit:

```
const byte device=0b0100000; //default addrress of IO chip

```
> 1 votes

---
Tags: i2c, voltage-level, teensy
---


# Question
Title: Making a distance sensor for human interaction
I want to make a sensor that senses a person between 1.5 m and 0.2 m, connected to an LED that is on 100% at 0.2 m and 1% at 1.5 m and gradually scales.

Is an ultrasonic sensor the best sensor to use here?

# Answer
> 0 votes
Most arduino compatible ultrasonic sensors should work perfectly for your use case. You would just have to program the arduino then but I am going to assume that you know how to do that.

Here is a link to the one that I personally use: https://www.amazon.com/HC-SR04-Ultrasonic-Distance-MEGA2560-ElecRight/dp/B01MA4O5G5/ref=sr\_1\_3?ie=UTF8&qid=1524520770&sr=8-3&keywords=ultrasonic+sensor

---
Tags: arduino-mega, sensors, led, hardware
---


# Question
Title: Fio Keyboard program out of control, how to reset?
My question involves a Sparkfun Fio v3, similar to the Arduino Fio.

I had a student who was testing his understanding of the Keyboard library. He uploaded a sketch that continuously sends output, emulating a keyboard, saying "Hello!If you're reading this, then you did things right!" (I don't have his code, unfortunately, so I can't post it.)

So, now, whenever I connect it via the USB, I can't upload a new sketch because the Serial channel is clogged with this output. (Error Message: "avrdude: stk500\_getsync() attempt 1 of 10: not in sync: resp=0x00" and so on)

I've tried putting the cursor inside the header comment in 'Blink', so that the new characters that are being spammed to my code are all inside a comment, and this makes it possible to compile, but it won't sync and upload. I've tried burning a new bootloader, and this fails as well (Message: "Error while burning bootloader.").

It seems to me that the only way to get this device back is to reset the memory without connecting to a computer, but I can't find any way to do this.

Is there any way to rescue this device?

# Answer
Hehe... This is a fun one to try and get out of. The normal way is to reflash the bootloader...

If it's the same as the Leonardo you get about 8 seconds after a reset while just the bootloader runs before it starts to spam everything with text. So you can try:

1. Open notepad or something similar
2. Plug in the board
3. Press *and hold* the RESET button (or connect the RESET pin to GND with wire)
4. Open the IDE and load Blink.ino

Now the tricky bit. If the correct serial port isn't selected, you need to, within the space of 8 seconds:

1. Release the reset button.
2. Let the PC enumerate the device
3. Open the serial ports menu and select the right port
4. Press *and hold* the RESET button again.

Now you can program it, in a similar way:

1. Press UPLOAD in the IDE.
2. Just *before* it finishes compiling (turn on verbose output can help you time it better) release the RESET button.

If you timed it right the bootloader should run and accept the new program *before* the existing sketch runs and starts spamming everything.
> 1 votes

# Answer
Majenko's suggestion should work - the bootloader should give you a few seconds in which to upload the new sketch, although timing it can be critical.

If that fails, you can reburn the bootloader which will erase the existing sketch. I have a sketch which uploads various bootloaders, the ATmega32U4 being one of them.

Judging by the schematic and also a photo of the board, you would need to solder on a 6-pin header (circled).

Then run 6 wires as described on my page above to another Arduino (see "Wiring for Leonardo") and burn the bootloader. That only takes a couple of seconds. You could make up a suitable cable with a 6-pin socket to make it easier next time a student does the same thing. :)

This will definitely work (if you get the wiring right) because it uses ICSP programming, which means the sketch on the board doesn't have a chance to run. In fact the programming is not via the USB interface at all.

The bootloader uploading starts with a chip erase, which therefore removes any existing sketches.
> 0 votes

---
Tags: bootloader, keyboard
---


# Question
Title: Small Arduino with Bluetooth HID interface
I am trying to create a bluetooth gamepad for my phone.

I saw this:

https://www.amazon.com/DFRobot-Beetle-BLE-Arduino-Bluetooth/dp/B014KQHEH6/ref=cm\_cr\_arp\_d\_product\_top?ie=UTF8

It says its bluetooth HID, but there are some conflicting comments saying it is serial over bluetooth. Is there something similar in a small form factor with an hid bluetooth module that I can use?

# Answer
Based on the fact that the controller you mentioned has a TI CC2540 Bluetooth processor, I have found a few webpages with information about HID capabilities in the CC2540. Based this the CC2540 should support HID.

Some example code.
Question on the TI forums, with a link to example code.
> 1 votes

---
Tags: bluetooth
---


# Question
Title: Controlling multiple fans using arduino uno
I'm kind of new on the field of Arduino. Although I have a question concerning multiple fan connection on 1 arduino PWM pin. The goal is to connect around 8 to 16 fans on 1 arduino pwm header pin and control their speeds separately using a potentiometer. As I seen it can be achieved by using transistors. The question is are there any limitations on how many fans can I connect and control seperatly using tranzistors? Can I for example use 16 transistors and control 16 fans seperatly ?

Thank you for your answers in advance

# Answer
One PWM pin can control only one fan (or one group of fans). You can't have one PWM pin outputting different values to different fans, since one pin can only have one value. (Yes, there are ways of multiplexing it through time slicing but that is both hard and not a good idea).

You need one PWM per fan if you want individual control of each fan's speed. That means a maximum of 6 fans on an Arduino.

To get more you would either have to use software PWM (which can introduce jitter which may not be a problem with simple fans), or an external PWM controller. Or add more Arduinos.

If all you want is potentiometer control of the fans you can do it without using an Arduino. A pair of op-amps (it can be a single dual op-amp chip), one acting as a triangle wave oscillator, and the other as a comparator, will generate PWM for you. Here's an example:

> Image by ElectroBOOM (watch his videos sometime, they're hilarious)
> 1 votes

# Answer
One option for controlling multiple PWM output is to use a I2C PWM Driver (e.g. PCA9685). It has 16 PWM outputs and is controlled from the arduino with I2C which only requires 2 pins on the arduino.

Tutorial: https://learn.adafruit.com/16-channel-pwm-servo-driver
> 1 votes

---
Tags: arduino-nano, pwm, arduino-pro-mini, transistor
---


# Question
Title: how to set the pin 13 only HIGH for 1 minute if sensor at pin 8 give HIGH?
```
int PUMP = 13;
int sensor = 8;
int val;

void setup() {
  pinMode(13,OUTPUT);
  pinMode(8,INPUT);
}

void loop() {
  val = digitalRead(8);
  if(val == HIGH)
  {
    digitalWrite(13,HIGH);
  }
  else
  {
    digitalWrite(13,LOW);
  }

  delay(0);
}

```

# Answer
> 3 votes
Just add delay after you turn on pin 13. So it would be:

```
int PUMP = 13;
int sensor = 8;
int val;

void setup() {
  pinMode(13, OUTPUT);
  pinMode(8, INPUT);
}

void loop() {

  val = digitalRead(8);

  if (val == HIGH)
  {
    digitalWrite(13, HIGH);
    delay(60000); //60000ms is 1 minute
  }
  else
  {
    digitalWrite(13, LOW);
  }
}

```

# Answer
> 2 votes
I want to add to the answer of Ian:

* If you later want to do something within that minute, you should not use `delay`. Instead use millis, see Blink without delay and use the same principle. It is considered bad practice to use delays, since it prevents from doing anything else in the mean time. For your small example it is not a problem though.
* Also check what you really mean with requirement 'set pin 13 high if pin 8 is high' :

+ What if pin 13 stays high for 2 minutes, should pin 8 stay high 1 minute from the start that pin 13 got high (thus will be low when pin 13 is still high)
    + Or should pin 8 stay high 1 minute after pin 13 gets to low again. In this case you need to check for flanks instead of only the current state.

# Answer
> 1 votes
That's a poor way to do it, the uC is then sitting there for a minute unable to do anything else. A better way is to capture the time of the input pin, then keep checking the time until 1 minute has elapsed.

```
void loop(){
   if ((digitalRead(8) == HIGH) && (timerRunning == 0)){
      startTime = millis(); // all time variables are type unsigned long
      digitalWrite (13, HIGH);
      timerRunning = 1;
   }
   if (timerRunning == 1){
      timeNow = millis();
      if ((timeNow - startTime)>= 60000UL){
         timerRunning = 0;
         digitalWrite (13, LOW);
      } //end time pass check
   } // end timer running check
   // now you can do other stuff while waiting for time to pass
} // end loop

```

---
Tags: arduino-mega
---


title: Set variable value with serial?

text:
# Question
Title: Set variable value with serial?
so I need to make a arduino program, generates 2 random numbers, makes a + calculation with them and asks user the right answer. If the answer is right AKA Calculation==User Answer, then led is set to LOW, and serialprint sent. If its wrong, Led lights up and serialprint sent again. It works if i set the variables manually etc. But the I think the problem is with my serialRead, somehow it doesnt set the value it got from the user as the value of the variable (Luku4)

Here is the code, I hope you can help me.

```
int Luku1 = 0;
int Luku2 = 0;
int Luku3 = 0;  //Summa
int Luku4 = 0; //Vastaus
const int ledPin = 13;
byte i = 0;

void setup() {

  for (i=0; i<4; i++){
pinMode(ledPin, OUTPUT);
}

randomSeed(analogRead(0));
Serial.begin(9600);
Serial.println("Arvotaan 2 satunnaislukua ja summataan ne yhteen. Kerro oikea vastaus");
}

void loop() {
  Serial.println("Arvotaan 2 satunnaislukua");
  Luku1 = random(1,5);
  Luku2 = random(1,5);
  Serial.println(Luku1);
  Serial.println("+");
  Serial.println(Luku2);
  Luku3 = Luku1 + Luku2;
  delay(100);
  Serial.println("Mika on vastaus?");
  Luku4 = Serial.read();
    while(Serial.available() == 0){}

  if (Luku4==Luku3) {
    digitalWrite(ledPin, LOW);
    Serial.println("Oikea vastaus");
    delay(2000);
  }

  else{
    digitalWrite(ledPin, HIGH);
    Serial.println("Vaarin");
    delay(2000);
    digitalWrite(ledPin, LOW);

  }
}

```

# Answer
You are comparing a byte which was read through uart with a number. If you send number '5' through uart, you won't get number 5, but character '5'. To convert single character to number, you can do following:

```
Luku4 = Serial.read(); // '0' .. '9'
Luku4 = Luku4 - '0'; // 0..9

```

But this will work only for single digit numbers, for more robust solution please refer to readString function to see how you can read strings from UART and to function atoi which converts string to number.
> 2 votes

# Answer
You are reading Serial before you check that there is anything valid to read:

```
Luku4 = Serial.read();
while(Serial.available() == 0){}

```

Try swapping those two lines.
> 1 votes

# Answer
Try changing these lines

```
Luku4 = Serial.read();
while(Serial.available() == 0){}

```

to these lines

```
while(Serial.available() == 0){}
Luku4 = Serial.parseInt();

```

As shown in the Arduino documentation, Serial.parseInt() will read a number from Serial. If a non-number character is entered it will return 0.
> 0 votes

---
Tags: serial, programming, sketch
---


title: Timer0 overflow interrupt not working

text:
# Question
Title: Timer0 overflow interrupt not working
I try to use the Timer0 of an Arduino Leonardo (ATmega32u) to trigger an interrupt at regular intervals, using plain avr-gcc (not the arduino library). I try to blink the built-in LED as test, but it does not light up.

If I place a `PINC=0x80;` in the main function, the LED turns up, but not if I do it from the interrupt. What am I doing wrong?

EDIT : The LED turns on with `TCCR0B = (1 << CS00);`, (no prescaler) or `TCCR0B = (1 << CS01)` (prescaler /8), but it does not with `TCCR0B = (1 << CS00) | (1 << CS02);` (prescaler /1024, what I want). At 16MHz CPU frequency the resulting frequency should be more than 15kHz, so I should see it instantly.

Here is my code:

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

ISR(TIMER0_OVF_vect)
{
    PINC = 0x80;
}

int main()
{
    DDRC = 0b10000000;

    //Start Timer 0 @ 15625 Hz
    TCCR0A = 0;
    TCCR0B = (0b101 << CS00);
    TIMSK0 = (1 << TOIE0);
    sei();

    while(true); // Avoid return from main
}

```

# Answer
I just found the answer here : https://www.avrfreaks.net/forum/atmega32u4-arduino-leonardo-strange-timer-behavior

It seems that the USB connection generates higher-priority interrupts. I still don't know why the interrupts do work at higher frequency.

Solutions include powering the board from a USB charger or other power source rather than through the computer USB or adding the following code before the interrupt enable :

```
// Clear usb interrupt flags
USBINT = 0;
UDINT  = 0;
for (uint8_t i = 0; i < 6; i++)
{ // For each USB endpoint
    UENUM = i; // select the _i-th endpoint
    UEINTX = UEIENX = 0; // Clear interrupt flags for that endpoint
}

```

Thanks to those who helped me !
> 1 votes

---
Tags: interrupt, timers, arduino-leonardo, atmega32u4, avr-gcc
---


# Question
Title: How to protect link/url form ESP-12E for controlling LED
I am using ESP8266 ESP-12E NodeMCU for controlling LEDs and Relay.

When ESP-12e power on it connect into my home wifi network and it gives IP address such as 192.168.0.104, and by that I can control my devices through Localhost.

I am using link or url to control my application such as

192.168.0.104/status1=1 (for starting LED 1 start)

192.168.0.104/status1=0 (for turn off LED)

but my point is how to secure 192.168.0.104/status1=1 or 192.168.0.104/status1=0.

Because it is open for all and however if some one do just for fun and turn off my Relays and LEDs it will be very risky for home application.

Here is my code, this code works very well:

```
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

const char* ssid = "Asif Wifi";
const char* password = "asif0172";

ESP8266WebServer server(80);

const int output1 = D1;
const int output2 = D2;
const int output3 = D3;
const int output4 = D4;

boolean device1 = false;
boolean device2 = false;
boolean device3 = false;
boolean device4 = false;

void handleRoot() {
  //digitalWrite(led, 1);
  //server.send(200, "text/plain", "hello from esp8266!");
  //digitalWrite(led, 0);

  String cmd;
      cmd += "<!DOCTYPE HTML>\r\n";
      cmd += "<html>\r\n";
      //cmd += "<header><title>ESP8266 Webserver</title><h1>\"ESP8266 Web Server Control\"</h1></header>";
      cmd += "<head>";
      cmd += "<meta http-equiv='refresh' content='3'/>";
      cmd += "</head>";

      if(device1){
        cmd +=("<br/>Device1  : ON");
      }
      else{
        cmd +=("<br/>Device1  : OFF");
      }

      if(device2){
        cmd +=("<br/>Device2  : ON");
      }
      else{
        cmd +=("<br/>Device2  : OFF");
      }

       if(device3){
        cmd +=("<br/>Device3  : ON");
      }
      else{
        cmd +=("<br/>Device3  : OFF");
      }

      if(device4){
        cmd +=("<br/>Device4  : ON");
      }
      else{
        cmd +=("<br/>Device4  : OFF");
      }

      cmd += "<html>\r\n";
      server.send(200, "text/html", cmd);
}

void handleNotFound(){
  //digitalWrite(led, 1);
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  //digitalWrite(led, 0);
}

void setup(void){
  pinMode(output1, OUTPUT);
  pinMode(output2, OUTPUT);
  pinMode(output3, OUTPUT);
  pinMode(output4, OUTPUT);

  digitalWrite(output1, LOW);
  digitalWrite(output2, LOW);
  digitalWrite(output3, LOW);
  digitalWrite(output4, LOW);

  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");

  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
  }

  server.on("/", handleRoot);

  server.on("/status1=1", [](){
    server.send(200, "text/plain", "device1 = ON");
    digitalWrite(output1, HIGH);
    device1 = true;
  });

  server.on("/status1=0", [](){
    server.send(200, "text/plain", "device1 = OFF");
    digitalWrite(output1, LOW);
    device1 = false;
  });

  server.on("/status2=1", [](){
    server.send(200, "text/plain", "device2 = ON");
    digitalWrite(output2, HIGH);
    device2 = true;
  });

  server.on("/status2=0", [](){
    server.send(200, "text/plain", "device2 = OFF");
    digitalWrite(output2, LOW);
    device2 = false;
  });

  server.on("/status3=1", [](){
    server.send(200, "text/plain", "device3 = ON");
    digitalWrite(output3, HIGH);
    device3 = true;
  });

  server.on("/status3=0", [](){
    server.send(200, "text/plain", "device3 = OFF");
    digitalWrite(output3, LOW);
    device3 = false;
  });

  server.on("/status4=1", [](){
    server.send(200, "text/plain", "device4 = ON");
    digitalWrite(output4, HIGH);
    device4 = true;
  });

  server.on("/status4=0", [](){
    server.send(200, "text/plain", "device4 = OFF");
    digitalWrite(output4, LOW);
    device4 = false;
  });

  server.onNotFound(handleNotFound);
  server.begin();
  Serial.println("HTTP server started");
}

void loop(void){
  server.handleClient();
}

```

Only need to know how to secure this system, that's it.

Thank you.

Dear Garben,

well I am trying in your way but I can not add variable and can not operate by operator..... Here is my code:

```
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

const char* ssid = "Asif Wifi";
const char* password = "asif0172";

const char* pwd = "dada123456";

ESP8266WebServer server(80);

const int output4 = D4;

boolean device4 = false;

void handleRoot() {
  //digitalWrite(led, 1);
  //server.send(200, "text/plain", "hello from esp8266!");
  //digitalWrite(led, 0);

  String cmd;
      cmd += "<!DOCTYPE HTML>\r\n";
      cmd += "<html>\r\n";
      //cmd += "<header><title>ESP8266 Webserver</title><h1>\"ESP8266 Web Server Control\"</h1></header>";
      cmd += "<head>";
      cmd += "<meta http-equiv='refresh' content='3'/>";
      cmd += "</head>";

      if(device4){
        cmd +=("<br/>Device4  : ON");
      }
      else{
        cmd +=("<br/>Device4  : OFF");
      }

      cmd += "<html>\r\n";
      server.send(200, "text/html", cmd);
}

void handleNotFound(){
  //digitalWrite(led, 1);
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  //digitalWrite(led, 0);
}

void setup(void){

  pinMode(output4, OUTPUT);

  digitalWrite(output4, LOW);

  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");

  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
  }

  server.on("/", handleRoot);

  server.on("/status4=1&password=" + pwd, [](){
    server.send(200, "text/plain", "device4 = ON");
    digitalWrite(output4, HIGH);
    device4 = true;
  });

  server.on("/status4=0&password=" + pwd, [](){
    server.send(200, "text/plain", "device4 = OFF");
    digitalWrite(output4, LOW);
    device4 = false;
  });

  server.onNotFound(handleNotFound);
  server.begin();
  Serial.println("HTTP server started");
}

void loop(void){
  server.handleClient();
}

```

# Answer
You need to take a look at the HttpBasicAuth example that comes with the ESP8266's ESP8266WebServer library that you are using. It is simple enough.

Here it is pasted in for reference:

```
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>
#include <ESP8266WebServer.h>

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

ESP8266WebServer server(80);

const char* www_username = "admin";
const char* www_password = "esp8266";

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if(WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("WiFi Connect Failed! Rebooting...");
    delay(1000);
    ESP.restart();
  }
  ArduinoOTA.begin();

  server.on("/", [](){
    if(!server.authenticate(www_username, www_password))
      return server.requestAuthentication();
    server.send(200, "text/plain", "Login OK");
  });
  server.begin();

  Serial.print("Open http://");
  Serial.print(WiFi.localIP());
  Serial.println("/ in your browser to see it working");
}

void loop() {
  ArduinoOTA.handle();
  server.handleClient();
}

```

The key part is this bit:

```
    if(!server.authenticate(www_username, www_password))
      return server.requestAuthentication();

```

Add that into your handler for your URL and it will ask for a username and password which you provide as `www_username` and `www_password`.

There's a more advanced example too if you want to delve deeper.
> 1 votes

---
Tags: arduino-uno, esp8266, nodemcu, http, home-automation
---


title: How to decrease adc accuracy?

text:
# Question
Title: How to decrease adc accuracy?
I read in this atmega328p datasheet the following on page 308:

From sect. 28.4:

> By default, the successive approximation circuitry requires an input clock frequency between 50kHz and 200kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the input clock frequency to the ADC can be higher than 200kHz to get a higher sample rate.
>
> The ADC module contains a prescaler, which generates an acceptable ADC clock frequency from any CPU frequency above 100kHz. The prescaling is selected by the ADC Prescaler Select bits in the ADC Control and Status Register A (ADCSRA.ADPS). The prescaler starts counting from the moment the ADC is switched on by writing the ADC Enable bit ADCSRA.ADEN to '1'. The prescaler keeps running for as long as ADEN=1, and is continuously reset when ADEN=0.
>
> When initiating a single ended conversion by writing a '1' to the ADC Start Conversion bit (ADCSRA.ADSC), the conversion starts at the following rising edge of the ADC clock cycle.
>
> A normal conversion takes 13 ADC clock cycles. The first conversion after the ADC is switched on (i.e., ADCSRA.ADEN is written to '1') takes 25 ADC clock cycles in order to initialize the analog circuitry.

By required bandwidth is 120 kHz, and 5 bit accuracy will suffice for my purpose. So, I understand that I can achieve this by changing the prescaler to a lower division number, thus increasing the clock frequency fed into the ADC (as per the diagram in the aforementioned document).

However, the document only specifies the min and max times required for ADC conversion for 50 kHz (12 to 280 microseconds at 50kHz bandwidth).

My question: Given my requirement of 120kHz bandwidth, what is the lowest prescaler division value I should use to guarantee ADC completion time to within 1/120kHz seconds (8.3us)?

EDIT: This is another question I have: Why does the accuracy change when using a lower divider value? Surely we are simply changing the clock frequency fed into the ADC converter, not the ADC algorithm itself; so why should the bit accuracy change?

# Answer
> 2 votes
From: http://forum.arduino.cc/index.php?topic=6549.0

The documentation states that 13 cycles are neccesary for ADC conversion. Thus, using the clk/13\*8 divisor configuration, and 16 MHz system clock, the upper bound becomes 154KHz

The forum post in the above link continues to say that "ADC clock frequencies above 1MHz are uncharacterised", however this was quoting another document for which the link is dead. I could not find this statement in the most recent documentation.

Edit: Another forum post where a user successfully used an atmega328p to achieve 360000 samples/sec, so it is technically possible: http://forum.arduino.cc/index.php?topic=8795.0

---
Tags: arduino-uno, adc
---


title: Reading bitswise for 'FALSE'

text:
# Question
Title: Reading bitswise for 'FALSE'
In the sketch I'm working on, I'm storing several 1-bit values representing different boolean states in a single byte, trying to save precious RAM. (example for 5 boolean states: `dec10` = `b00001010`, the five states are `0`, `1`, `0`, `1`, `0`)

I'm then using an `if` statement to determine if the relevant bit is `TRUE` or `FALSE`:
`if ((options>>3) & 1 == 1)`

The above will evaluate `true` when the relevant bit is `1`, so if I want to carry out something in that case, great, no problem!

**However**, if I want my `if` statement to evaluate `TRUE` in the event that the relevant bit is `0`, I can't work out what code I need.

---

I thought the problem might be that the other 'non-relevant' bits were interfering, so I tried bit shifting the LSB all the way to MSB position and then shifting back to LSB:
`if ((options<<4>>7) & 1 == 0)`
but this still isn't doing what I'm trying to achieve (and seems like a lot of work for the processor).

It also feels like I've tried just about every combination of `~&0`, `!&0`, `==0`, `!=0`, `~&1`, `!&1`, `==1`, `!=1` there is, but I must have missed something...

Can anyone tell me how I get an if statement to evaluate true in the event that the bit is a zero?

# Answer
> 4 votes
The simplest thing is just to mask an individual bit, not do any shifting:

```
if (options & 0x04) {
    // Do something if true
} else {
    // Do something if false
}

```

Or, to invert it:

```
if (!(options & 0x04)) {
    // Do something if false
} else {
    // Do something if true.
}

```

The thing with C is that 0 is false, and *anything else* is true. So if your `options` variable contains `0b00001010` and you AND it with 0x04 (which is HEX for `0b00001000`) you end up with `0b00001000`. That is 0x04, which is something other than 0, so it's true.

If `options` contains `0b00000010` and you AND it with 0x04, you get `0b00000000`, which is 0. Since 0 is false the result is false.

You don't care what the actual number is - you only care if it's 0.

# Answer
> 2 votes
There is an alternative to doing bit shifts, and that is to use the `bit` macro which is defined in Arduino.h (and thus is automatically available).

```
#define bit(b) (1UL << (b))

```

Now if you want to see if the second bit is set (which as a mask would be 0x04, being 1 shifted left 2 times) you can do this:

```
if (options & bit (2))
   {
   // bit number 2 is set
   }
else
   {
   // bit number 2 is clear
   }

```

This is easier to read than:

```
if (options & (1 << 2))

```

or:

```
if (options & 0x04)

```

---

And to invert it:

```
if (!(options & bit (2)))
   {
   // bit number 2 is clear
   }

```

Or:

```
if ((options & bit (2)) == 0)
   {
   // bit number 2 is clear
   }

```

---

Also, the various processor bits are given as bit numbers in the Atmega include files (rather than bit masks).

So, for example, to set some processor bits you can do this:

```
WDTCSR |= bit (WDCE) | bit (WDE);

```

That is easier to read than:

```
WDTCSR |= (1 << WDCE) |  (1 << WDE);

```

And much easier than turning them into hex numbers:

```
WDTCSR |= 0x10 | 0x08;

```

And in case you are wondering how to clear a bit, you *and* in the 1s complement:

```
WDTCSR &= ~bit (WDCE);

```

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


title: Arduino IDE Display Code Line Numbers

text:
# Question
Title: Arduino IDE Display Code Line Numbers
In the Arduino IDE: How can I get the line numbers shown in a sidebar of the editor?

It is hard to find which line my errors are referring to without them...

I am using Arduino IDE on a form of Windows.

# Answer
Go to **File \> Preferences.** Under the **Settings** tab, click the checkbox for **Display line numbers**.

Keep in mind that this option is available in the latest version of the Arduino Integrated Development Environment (v1.6.6). In case you are using GNU/Linux distribution is recomended to use the one that is **NOT** in the distribution's repositories but the one that is offered in https://www.arduino.cc/en/Main/Software

If you are using a Linux OS this solution may not work. Look at the 'preferences.txt' where you can edit your preferences in a file without a GUI.It will display all possible options available for your current version of Arduino IDE on your OS. It is usually in the '.arduino' folder which may be in your 'home' folder.
> 8 votes

---
Tags: arduino-ide
---


# Question
Title: How to indicate an End of a stream on USB
I am making a Lora-USB passthrough device using arduino and somehow I want to indicate that a stream over some data has ended.

So far I have done:

```
void onLoRaReceive(int packetSize) {
  if (packetSize == 0) return;          // if there's no packet, return

  byte[packetSize] buffer=[];

  while (LoRa.available()) {
    site_t recievedData=LoRa.readBytes(buffer,packetSize);
    Serial.write(buffer,recievedData);
  }
}

```

So what I want to know is how the software reading from the serial interface will know that a packet has ended; One way I thought is by sending an `EOF` byte but I am afraid of "rogue" `EOF` values in packet data.

An another way is to send the packet size through the Serial interface as well but how I will make it understand that what I am sending now is the size and expect X size of data?

# Answer
> 1 votes
LoRa has a moderate data rate and typically substantial gaps between packets, so a simple thing you can do is send the data as *printable* ASCII hex with newlines or other terminators.

This will just short of double the amount of data you have to move, but do so in a very simple and deterministic way, and you can crank up the serial baud rate to handle it, especially as the baud rate only actually "exists" between two ATmega chips *within* the Uno.

Another plus is that the data becomes human readable, which is handy for debugging, especially if you might want to intermix advisory messages and data.

# Answer
> 1 votes
What you need is some form of *protocol*. Some system that both ends of the communication channel agree on.

Most serial protocols use certain characters to indicate certain things, and indeed the ASCII character set has certain characters earmarked for certain jobs in communication, so it makes sens to use those.

One you can use is EOT - End Of Transmission - character 0x04. Note: there is no such thing as an "end of file character 'EOF'". That's purely a DOS construct.

And yes, you may wonder about a rogue 0x04 in the data stream triggering the end, and you're not the first to think about that. That's why there's character 0x10 - DLE. That's Data Link Escape. Its purpose is to tell the receiving end "The next character I send is a data character. Don't interpret it as a control character.".

So for every 0x04 in the data stream you should send 0x10,0x04 instead. Your receiver code then sees the 0x10 and makes a note that the next character should not be interpreted as a control character, but raw data.

Problem solved.

But what, you ask, about there being a rogue 0x10 in the data stream? Isn't that going to cause the same problem?

Yes. And you deal with it in exactly the same way. Just prefix it with 0x10. Since the receiver should then know to always interpret the next character as data, regardless of what it is, it will see the next 0x10 as data.

So as an example, sending the following data stream:

```
0x06,0x31,0xc7,0x04,0x91,0x10,0x04,0x73

```

would be done as:

```
0x06,0x31,0xc7,[0x10],0x04,0x91,[0x10],0x10,[0x10],0x04,0x73

```

(Added 0x10s highlighted with brackets).

It can be good to use some of the other control bytes as well, such as SOH for Start Of Header, STX for Start of TeXt, ETX for End of TeXt, etc. You can then do such things as tell the receiver where the start of your packet is, and what the different bits of it are. Adding a header with the length and a checksum can also be worthwhile too, for increased reliability and data integrity.

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


title: Wifi proof with WeMos D1 ESP8266 Ad-Hoc

text:
# Question
Title: Wifi proof with WeMos D1 ESP8266 Ad-Hoc
I am trying to use a WeMos module to send a broadcast message through an peer-to-peer network (Ad-Hoc). The thing is that i can't give a SSID nor Password to that network, i just can define it through them IP Addresses. As you suspect i don't have a specific idea of the configuration of the Wemos module.

**What am I talking about?**

I need to receive messages in a IEEE802.11 software-defined radio module. In this module I can't establish a network, just listen to a channel, and read whatever someone is sending. Think about it as a sniffer. But in this case i can assign to this module a MAC and IP within the Network.

**What do I need?**

I need just to:

```
Initialize peer-to-peer (Ad Hoc) network without an SSID nor Password.
Set a channel (I do it with channel 13, it is most times free).
Send a broadcast message in that channel to the SDR module in the network.

```

**In other words** Module SDR: \- IP:192.168.123.2 \- MAC: xxx Wemos \- IP:192.168.123.3 \- MAC: xxx

Through Wemos:

* wifi, send broadcast message

The mask is /24, then it is going to send the message to all IPs from 192.168.123.2 to 192.168.123.254, then, for sure to the SDR Module, and i could receive it.

Thanks in advance.

Best regards,

Cristian

# Answer
> 1 votes
ESP8266 does not currently support Ad-Hoc/IBSS mode.

---
Tags: esp8266, wifi
---


# Question
Title: Major difference between DTR signal and RTS signal?
I actually had a doubt about what is the difference between the RTS signal and DTR signal ? I already know this that the DTR signal is used to auto reset when we use Arduino and similar MCUs. Can anyone say what is the major difference between these signals and what is their active state ?

# Answer
> 11 votes
Electrically they are both the same. The difference is what they are used for.

DTR means Data Terminal Ready and indicates that the connected device is ready to receive data.

> Data Terminal Ready (DTR) is a control signal in RS-232 serial communications, transmitted from data terminal equipment (DTE), such as a computer, to data communications equipment (DCE), for example a modem, to indicate that the terminal is ready for communications and the modem may initiate a communications channel.

RTS means Request To Send and indicates to the connected device that it wants to send data.

> The DTE asserts RTS to indicate a desire to transmit to the DCE, and in response the DCE asserts CTS to grant permission, once synchronization with the DCE at the far end is achieved.

Basically DTR is used to indicate the presence of some equipment, and RTS is one half of hardware flow control (along with CTS) to start and stop communication.

On USB communication (e.g., using FT232 USB to UART adaptor, etc) the meaning is less clear. DTR is asserted when the port is opened (usually) and RTS is most likely not asserted at all. It's at the whim of the operating system and/or the driver whether DTR is automatically asserted or not, and whether RTS is even implemented.

# Answer
> 12 votes
DTS and RTS are used on esp8266 boards with USB (Wemos, NodeMcu) to reset the board and to set io 0 low for bootloader mode. You can see it in source code of esptool.py. Sometimes you want a reset without going to bootloader mode.

```
RTS = either CH_PD/EN or nRESET (both active low = chip in reset
DTR = GPIO0 (active low = boot to flasher)

```

# Answer
> 1 votes
As a counter point, industrial systems utilize the UART protocol at much higher rates - 10 Mbits for example. RTS/CTS can prove very useful when a large data set is being received at a higher rate. We have clients using LVDS and RS-485 IO types for the higher speeds. DTR/DSR is occasionally used to see if the other equipment is on-line but this signal pair is in the rare to use category.

---
Tags: rs232
---


# Question
Title: Small Baseball Scoreboard using 2 to 3 breadboards
I'm helping my son start an Arduino small baseball scoreboard (roughly 2 or 3 breadboards in size). Im thinking to use qty 2, 2 digit 7 segment LED's (score of each team), an LCD 1602 module (inning tracker), using a serial monitor. Last is 3 individual LED's (controlled with a switch or remote).

My question is: can one arduino drive all of this? What would be a recommended configuration? Thank you,Dave

# Answer
Actually, you can very easily verify this yourself:

1. Per item (1602LCD, 7 segment LCD and LEDs check how many pins you need and what type, like e.g. I2C or SPI for the 1602 LCD). The 7 segment displays can have many or less pins, depending on the 'controller', See the reaction of CrossRoads below.
2. Count them together. If it fits on the Arduino you want to use OK. The Uno is cheapest, so if it fits on it, you use that, otherwise you can go to the Mega.
3. As alternative, and you need 'generic pins, called GPIOs' (not SPI/I2C) for some, you can use multiplexers like 74HC595 to reduce the number of GPIOs needed, at the cost of some speed (not critical for your project), and some more programming work.
4. In some cases you can use a MAX7219 driver IC, see (again) the remark of Crossroads below.
> 3 votes

---
Tags: power, led, spi, switch, project
---


# Question
Title: Arduino Nano with CH340 reboots on OS X El Capitan
I installed OS X El Capitan beta on my Macbook. Now my Nano-sized Chinese Arduino operating on CH340 chip reboots the laptop when USB is unplugged. While plugged, it works fine, I can upload sketches and send/receive data via Serial.

I've tried reinstalling the CH340 driver and running the following command as per this solution and it didn't help:

```
sudo nvram boot-args="kext-dev-mode=1 rootless=0"

```

I appreciate any ideas...

# Answer
> 4 votes
There is a new signed driver for OS-X El Capitan and Yosemite. This is all you want.

http://kig.re/2014/12/31/how-to-use-arduino-nano-mini-pro-with-CH340G-on-mac-osx-yosemite.html

# Answer
> 1 votes
The command you ran only disables driver signing verification, which means OSX stops blocking it. If it is crashing it is likely to be either a bug in OSX, or a bug in the driver. My guess is it is a bug in the driver and you'll probably have to wait until they release an updated version that is compatible with El Capitan.

# Answer
> 1 votes
It turns out I didn't have the latest Beta. I now updated to the latest and now my CH340-based Arduino doesn't get detected at all! Pretty much in line with everyone else complaining all over internet.

# Answer
> 1 votes
Check this video https://www.youtube.com/watch?v=0zuRukW7o0A

* Reboot and press CMD+R immediately after reboot to enter in Recovery Mode
* Open Terminal from Recovery mode
* Run the command csrutil enable --without kext
* Reboot
* Install driver

# Answer
> 0 votes
If you have macOS High Sierra like mine 10.13.4 This is work for me https://github.com/awangga/NFCReader

---
Tags: arduino-nano
---


title: Arduino resets my MacBook Pro

text:
# Question
Title: Arduino resets my MacBook Pro
Every time I connect the Arduino Uno to the Mac through USB port, the Mac restarts. Why is this happening? How can Arduino make such a sophisticated machine reset? This also happens with my ESP12E Node MCU.

# Answer
> 5 votes
It is almost certainly a device-driver issue. Since Arduinos are probably a little way down the pecking order for things that Apple is interested in, they probably don't test as extensively as (say) printers.

> How can Arduino make such a sophisticated machine reset?

Device drivers would operate with elevated privileges, because they need to control, well, *devices*, like hard disks, printers, etc. If one has a programming error (like dereferencing a NULL pointer) then it could crash the whole operating system.

---

I suggest you look at this page: IDE 1.6.12 released with Sierra support and more

It says there:

> A new version of the Arduino IDE (1.6.12) supporting OSX Sierra is available for download! All OSX users updating to Sierra are invited to also update the IDE to avoid crashes when uploading sketches.

This may or may not help. They seem to be suggesting that the *IDE* crashes rather than the Mac, but it could be worth trying.

---

There are some posts on macOS Sierra Usb Serial Crash which seem relevant:

> I need to use a arduino nano and my Mac with mac os sierra is rebooted when i plug in the arduino

It sounds like the CH340 chip set used on **clone** Arduinos is causing this.

A suggested new device driver fix is at ch340g-ch34g-ch34x-mac-os-x-driver

# Answer
> 0 votes
i have had the same problem and found that the CH340 driver was at fault. With the Arduino MEGA clone attached to the computer, it would throw a kernal panic at startup, then keep restarting over and over.

With the clone unhooked, the computer started normally. Therefore the driver when trying to load at startup was cauing a panic.

I went back to the web site and found an “updated” driver that solved the panic problem. It starts and runs OK, BUT -

1. Every print command prints twice. A simple “Hello World” prints twice.

I don't have a solution for the double print.

2. The program would compile, but never load in to the clone. When I switched the USB cable from a 6ft one to the included 1 ft blue one, it worked.

# Answer
> 0 votes
My MacOS is High Sierra 10.13.4 the simple solution is :

1. Download CH341SER\_MAC.zip from here https://github.com/awangga/NFCReader/raw/master/driver/CH341SER\_MAC.zip
2. remove old driver, please open terminal and run command:

rm -rf /System/Library/Extensions/usbserial.kext

rm -rf /Library/Extensions/usbserial.kext
3. Unzip CH341SER\_MAC and install CH34x\_Install\_V1.4.pkg then restart MAC,
4. after rebooting login to your MAC and open terminal, Conect arduino into your Mac and Look at your serial folder : ls /dev/
5. You can access your Arduino on /dev/cu.wchusbserialfa130 or /dev/tty.wchusbserialfa130 or just type : ls /dev/cu. then tab twice.

---
Tags: arduino-uno, esp8266, mac-os, clones
---


title: SIM808 module restarting repeatedly

text:
# Question
Title: SIM808 module restarting repeatedly
I have bought SIM808 module, everything working fine. All AT commands are giving expected response, i'm accessing it through hyperterminal. My problem is that whenever i make or receive a call or SMS , GSM gets restarting.(I can able to make/receive call, getting ring/alert for small period of time and then interrupt). But there is no Under or Lower voltage power down or warning. I have tried with DC power supply of 5V/500mA , 5V/1A and 5V/2A. What might be the reason ? Please help. extra info : It has one LM2576S voltage regulator in-built.

# Answer
> 1 votes
Check the datasheet and I think you will find you need 3 amps peak. It requires this peak current when you make a call or send a text/sms.

Use a 5A power supply and that should solve the problem.

I have never tried it but "super capacitors" *might* work, providing the extra power when its needed, it depends how long you need the 3A for.

# Answer
> -1 votes
I too faced the same problem and solved it.

Just use a 3.3V logic converter or a 3.3V interface, as the 5V causes the device to restart.

---
Tags: power, shields, gsm, gps, input
---