body:
I recently started playing with Arduino in order to do several projects, including:

 - A system which will measure some characteristics of the indoor air and could alert me if something goes wrong (for instance if the percentage of CH4 goes beyond a threshold).

 - A system I can bring with me on a walk which will measure the pollution and other characteristics of the air outdoors.

While the quantity and the diversity of the sensors for such projects, as well as the ease of use is mind blowing, I'm blocked at one aspect: the casing. Both of the projects require to put the electronics within a plastic case with:

 - Enough space for not only Arduino, but also the sensors. Some, such as MQ2/MQ5, can be quite large.

 - Holes for air flow, which are large enough to let small particles, but small enough to keep insects and large dust out of the electronics.

 - A hole for an USB cable and possibly a hole for the LED.

Unfortunately, the popular sites selling Arduino-related stuff have practically nothing when it comes to the cases. In most cases, the choice is limited to (1) the enclosures for Arduino itself (or other boards), with no holes in them and (2) the multicolored modular systems which look like LEGO bricks.

Outside Arduino-related sites, the only idea I have is to buy somewhere an old smoke detector, throw away the electronics and put Arduino and the sensors inside. For now, most smoke detectors I've seen seem too small for the task, and have to be modified in order to accommodate the USB cable.

Am I missing something? How other people do when they need an enclosure which fits Arduino and sensors and doesn't look geeky?

  [1]: https://www.adafruit.com/index.php?main_page=category&cPath=208

title: Where do I find the enclosures for an Arduino and a bunch of sensors?

Answers: 4

body:
for many projects i use distribution box like this one:

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

  [1]: https://i.stack.imgur.com/6rGNU.jpg

body:
I think your problem is that you are looking specifically for Arduino enclosures. Such a search tends to lead you to boxes for just an Arduino and nothing else - maybe with the headers poking out the top.

Instead, you should be looking more generically. There are thousands and thousands of "project enclosures" from many manufacturers (Hammond is a big name in these).

You take a generic project box of the right size and shape for what you want to create and in a material suitable for your needs, and cut / grind / drill / glue it to be what you want.

Most electronics suppliers will have an "Enclosures and Housings" section on their website. Have a browse through your favourite.

As far as air vents go, one good trick I have used is to simply drill holes (with a steady hand so you get them lined up nice and straight) and glue some fine mesh on the inside.  One good source of fine mesh is to go to your local smoking supplies reseller (tobacconist) and buy some "pipe meshes" (the flat ones, not bowl shaped ones) - also available from low-cost online resellers of any old junk (eBay, etc), which look like this:

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

(Also available in brass).  They typically come in different mesh sizes to suit your needs.

  [1]: https://i.stack.imgur.com/bVXzA.jpg

body:
Look into "Really Useful Boxes", found online, or at stores like Office Depot.  Lot of sizes available, pretty easy to mount cards & connectors into.
I have several projects lower down on [this page][1] where you can see how I used them.

[1]:http://www.crossroadsfencing.com/BobuinoRev17

body:
I just came across your question, and I think this may be useful if you're still interested in project enclosures. I've designed and created stackable, modular and extensible enclosures for Arduino (fits Uno and Mega footprints), Raspberry Pi (three different versions, for A+, B+/4B and Zero (can accommodate up to 4 Zeros), and Breadboard and breadboard-friendly MCUs. All of these enclosures have 4"x2.4"x1.2"(h) space on the inside, enough for one or two shields or hats. They also come with replaceable sides/tops that can allow you to add sensors and peripherals, like a Pi Camera, High Quality Camera, Tripod mount, Ultrasonic sensors (HC-SR04), momentary push button switches, RS232 ports and more. The enclosure is made of acrylic with 6 separate flat pieces, so that means you can also hack it to easily add holes and mounts to customize it yourself.

You can find more details on https://www.protostax.com/

Hope you find it helpful! Let me know if you have any questions.
Cheers, and Happy Making!
Sridhar Rajagopal


body:
I am trying to connect a USB Camera with my NodeMCU v0.9.

 - VCC  Red          +5V
 - D-      White          Data
 - D+      Green          Data
 - GND  Black          Ground

I dismantled the USB-cable and connected the VCC cable to 5V and the black ground Cable to GND.
Now I have DATA + and DATA - cable from the USB, which I connected to D5/D6 GPIO of the NodeMCU. I can now read the digital signal of the camera.

But I am not quite sure how to process the data cables signal. I am not familiar with the USB Data + / - cable concept.

Any ideas on how I can process the video image ?

title: Connect NodeMCU with USB Camera

Answers: 1

body:
You can't. It's as simple as that. To do it you require:

1. An MCU or MPU with a USB Host or OTG module built in.
2. Drivers for that module to enumerate the device
3. Drivers for the specific device you are connecting
4. Software to deal with the data provided by the device.

The ESP8266 has none of those.

Sounds to me like you want a Raspberry Pi.


body: My project is to create a decimal adder via voice recognition. Its like a calculator that only does addition. I am using hc-06 bluetooth module to convert my voice to a string. Let's say for example, I say "21+22" then the lcd would print "21 + 22 = 43". I have no problem in displaying my voice message on the lcd. My problem is that the string can't evaluate the equation. I used toInt() but it only recognizes the first integer. Is there a code to recognize the string and convert numerical values to int separated by + then evaluate it by adding the 2 intergers?

title: String to equation problem

Answers: 2

body:
There is no one single function for performing a calculation from a string like you are after in C.

Instead you will have to parse and split your string up into chunks and convert the two numbers into integers (maybe confirming that there is a + between them) and perform the calculation on those two individual integers.

body:
The standard IO library ([sscanf][1]) can help you with that:

    String s = "21+22";
    int x;
    int y;
    int items = sscanf(s.c_str(), "%d+%d", &x, &y);
    if (items != 2) /* error handling */
    int z = x + y;

Cheers!

  [1]: https://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html#ga5507d0e1bbfd387fbb2ffcfd8f5dca6f


body:
I was reading in the OpenWRT wiki that you can indeed connect to the serial TTY console of an Open WRT roouter using the serial console if you're careful aabout the voltages.  https://wiki.openwrt.org/doc/hardware/port.serial.cables#method_b_no_physical_changes_to_arduino_board

However, I don't know anything about the voltages of my particular model of OpenWRT router a Netgear WNR2000v4.  I know that it is accessible via 3 holes on the board but I know nothing of the voltages.  Does anyone know or have experince with this about what voltages / wires to use to access it via the serial console?

title: Connecting to a WNR2000v4 Netgear Router via Serial Connection with an Arduino Uno and a sketch?

Answers: 1

body:
>The WNR2000v4 serial port is at JP1: 115200 8N1 at 3.3V. Pads are, from left to right with the ethernet ports on right: [GND] [Rx] [Tx] [Vcc]

Source: https://wiki.openwrt.org/toh/netgear/wnr2000, PCB picture: https://wiki.openwrt.org/_detail/media/netgear/wnr2000/wnr2000v1_pcb_detail_small.jpg?id=toh:netgear:wnr2000


body:
Have an upcoming project where user input will be based on spinning a large cog and I have several UNOs available

Since rotary encoders need two pins, only a Mega would be able to handle the 7-8 encoders needed. Unless theres a better method of reading them?

Is it worth using an ATTiny85 per encoder and passing all this data to a mega via 1 pin each? This way, I could extend the project beyond 7-8 later?

Or is this idea out the window, because there's a much simpler way?

title: Reading several rotary encoders

Answers: 1

body:
Library and schematics are at https://github.com/maxgerhardt/rotary-encoder-over-mcp23017.

To read a rotary encoder (i.e., detect state changes of the knob), there are two possible implementations:

* poll the state of the two output pins and check for changes
* set up an interrupt which will be called when an output pin changes, then check for changes

Using interrupts is more efficient than always polling the pins, because an action is only executed when an actual change occurs.

Per rotary encoder you would need two pins on your microcontroller. However, we can use GPIO expanders over e.g. I2C or SPI, such as

* Microchip [MCP23017][1] (16-bit, I2C)
* Texas Instruments [PCF8575][2] (16-bit, I2C), [PCF8574](http://www.ti.com/product/PCF8574) (8-bit, I2C)

Using a port expander over I2C has the advantage being a bus that only uses 2 pins. This means that there can be multiple (up to 127) devices on the I2C bus, and each I2C device can then e.g. provide 16 GPIO pins.

Using an ATTiny85 per encoder and possibly joining them via an I2C bus is also possible, however more expensive and more work.

I've chosen a MCP23017 here because it is interrupt-capable, has 16-bit and I had it lying around. A PCF8574 would have also worked just fine, since it has the same capabilites.

Tests were made using an MCP23017 and a KY-040.

![](https://i0.wp.com/henrysbench.capnfatz.com/wp-content/uploads/2015/05/Keyes-KY-040-Rotary-Encoder-Pin-Outs.png)

The written library uses a modified [Adafruit MCP23017][3] library and the [Rotary][4] library. The Rotary library also handles debouncing by using a state-machine based approach for decoding. The library is a simple header file which defines a `RotaryEncOverMCP` C++ object, with which a rotary encoder connected to an MCP23017 device can be easily described and managed. It has an example for the polling method and the interrupt method.

For 1 encoder, one can write down schematic like: (interrupt based)

[![schem][5]][5]

[![enter image description here][6]][6]

Since one MCP23017 has 16 ports, we can connect up to 8 rotary encoders to one such device.

[![enter image description here][7]][7]

However the MCP23017 also has three address pins with which its I2C address can be selected. This means we can have 2^3 = 8 such device on the same I2C bus (i.e., connected to the same SDA and SCL lines).

Thus, with one I2C bus, which uses 2 pins, we can have a maximum of 8xMCP23017 and 64 rotary encoders (assuming no interrupts are used, which would need 1 pin for any number of rotary encoders). At the cost of 2 more pins on the microcontroller, we can create another software bit-banged I2C bus, each of which adds again a maximum of 64 rotary encoders.

Assuming D2 to D13 and A0 to A5 are free, on these 18 pins we can have 9 I2C buses with a total of 72 MCP23017 devices hosting a grand total of 576 rotary encoders. Whatever one might need that for.

I've tested this library with one rotary encoder and a MCP23017, but the code is structured in a way that adding more encoders is just adding an entry in an array.

[![enter image description here][8]][8]

[![enter image description here][9]][9]

  [1]: https://www.microchip.com/wwwproducts/en/MCP23017
  [2]: http://www.ti.com/product/PCF8574
  [3]: https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/
  [4]: https://github.com/brianlow/Rotary/
  [5]: https://i.stack.imgur.com/esepX.png
  [6]: https://i.stack.imgur.com/4jgus.png
  [7]: https://i.stack.imgur.com/B1Pdv.png
  [8]: https://i.stack.imgur.com/wezEx.jpg
  [9]: https://i.stack.imgur.com/ZSiAW.png


body:
I have a digispark that uses trinket keyboard library to send media keys back to the computer using a rotary encoder. I currently have it configured to send normal media keys but about 2 weeks ago i started needing to change binds on what the rotary encoder does so i needed a driver of some sort. i asked and i got answers that i can't use serial ports but i can use unused keys like f13+ keys so i use the f keys now to communicate to c# software (it listens on these f keys and as soon as they are pressed depending on the configuration it does what it needs to do).
I don't think that code is needed for this demonstration but if u need it i'll be happy to edit this.

So i made the software and now comes a problem of what happens when u plug in the device that doesn't have the driver. its useless, so i need a way for the digispark to find out if there is a software that can "reprogram" what the rotary encoder does and if there isn't use the default functions(the media keys).

**Questions:**

1. How would i go about finding out if there is the needed driver on that computer where the digispark is plugged in

2. Is there any way to add my program made in c# to the digispark, i got a usb headset and when i first plugged it in it installed its driver, so when i plug in my digispark can it load the program

**Solutions that i think may work but i have no idea how to do them:**

1. using one of these unused keys as Boolean, when its held down lets say by the c# software can the digispark using the trinket or any other compatible Tiny85 library determine if that key is pressed down or not (this may interfere with other software so i don't think its perfect solution)

2. If anyone here knows any library or custom firmware that allows the digispark(Tiny85) to communicate on serial ports that'd be pretty useful and would solve the whole question.

For the second problem: do i need any other hardware to do this as i only have a [Tiny85 digispark][1] and a [rotary encoder with a breakout board ][2]

If you have a solution please provide me code or links where i may learn how to do this because as of now i have no idea how to do this, i know my way around c# but i'm a noob in arduino programming. I already asked this on stack overflow a week ago but didn't get any comments or answers. I'm sorry if this counts as a duplicate i'll remove the one on stack overflow if needed. thank you for understanding

  [1]: https://www.aliexpress.com/item/1PCS-ATTINY85-Module-Digispark-kickstarter-Micro-development-board-for-Arduino-usb/32748964049.html?spm=a2g0s.9042311.0.0.27424c4d6mXTpT
  [2]: https://www.aliexpress.com/item/1PCS-FREE-shipping-Rotary-Encoder-Module-Brick-Sensor-Development-for-Dropshipping-KY-040/32726570531.html?spm=a2g0s.9042311.0.0.27424c4d6mXTpT

title: C# Arduino: How to detect if the needed software is present on the computer

Answers: 1

body:
> How would i go about finding out if there is the needed driver on that computer where the digispark is plugged in

I can't think of any way to do that. That's like asking if a keyboard you plug into a USB port can tell if you have Photoshop installed or not.

---

> Is there any way to add my program made in c# to the digispark ...

No. The Digispark is a tiny computer based on the Attiny85 which has 8k of program memory, some of which is dedicated to a bootloader which lets you upload new code.

---

Your project is far too ambitious for the level of hardware you are proposing to use. In fact this video which I watched the other day comes to mind:

https://www.youtube.com/watch?v=s7AXskSxxMk

---

From a comment:

> the **it** refers to the digispark, when connected the digispark checks if the f17 key is pressed down and if it is that means my program is running in the background so use the functions that are compatible with the program

OK, so you want the host computer (not the Digispark) to pretend it is holding down F17, and then when the Digispark is plugged in it checks if F17 is down, and if so it knows that the desired program is running on the PC. Is that your idea?

The problem here is that the Digispark is a USB device (not a USB host). I suppose it would be possible to write a special device driver on the PC that, once the Digispark connects, would send some special code to say whether or not the program is running. However with the Digispark only having 8 KB of program memory, this extra code (on the Digispark) might be hard to fit in. Plus you would need to write your USB device driver. Plus the device driver would need to be able to query what programs are running.

I think a far simpler solution would be to have an On/Off button on the Digispark. If you plug it into a PC which has this special program running you press the button, then the Digispark sends the alternative commands to your C# program.


body:
I am working on a university final project and have run into a problem with programming Arduino, after a 3 year hiatus. I have a pressure transducer that is sending pressure data at 10Hz. I have successfully programmed my Arduino Pro Micro to read the data as it is coming in. I'm using the SoftwareSerial library to set digital pins 8 and 9 to RX and TX, respectively. As the pressure transducer is continuously streaming data values, I read each character, store them in an array, and print them to the Serial Monitor. I'm using a start and end-marker to recognize each incoming character and put them into the array. The raw data output from the transducer is in the form:

    *000114.2927
    *000114.2926
    *000114.2927

And this is the code I am using.

    #include <SoftwareSerial.h>
    #define paroRX 8
    #define paroTX 9

    SoftwareSerial paroSerial(paroRX, paroTX);

    const byte numChars = 16;
    char paroChars[numChars];     //array to store received data
    char paroToSend[numChars];      //array to transmit
    boolean newParoData = false;

    void setup(){
      Serial.begin(9600);     //with transmitter radio
      paroSerial.begin(9600);
    }

    void loop(){
      paroSerial.listen();
      readParo();      //read from Paro and store values in paroChars
      if(newParoData == true){
        for(int i=0; i<16; i++){
          paroToSend[i] = paroChars[i];
        }
        Serial.print(paroToSend); Serial.print('\n');     //transmit Paro data with a new line for each value
        newParoData = false;
      }
    }

    void readParo(){
      static boolean receiveInProgress = false;
      static byte index = 0;
      char startMarker = '*';
      char endMarker = '\n';
      char pd;
      while(paroSerial.available() && newParoData == false){
        pd = paroSerial.read();
        if(receiveInProgress == true){
          if(pd != endMarker){
            paroChars[index] = pd;
            index++;
            if(index >= numChars){
              index = numChars - 1;
            }
          }else{
            paroChars[index] = '\0';      //terminate string
            receiveInProgress = false;
            index = 0;
            newParoData = true;
          }
        }else if(pd == startMarker){
          receiveInProgress = true;
        }
      }
    }

And this is the output that I get, which is correct. I don't really want that * in front anyways.

    000114.2927
    000114.2928
    000114.2927
    000114.2929

But all of this happens at 10Hz, which means I get a constant stream of readings on the Serial Monitor. I want to slow this down to 1Hz, or just one reading per second. The obvious solution that occurred to me was to put a delay in the loop. So I tried to implement this with delay(1000) and using the millis() function as well, but I get strange readings like:

    000114.2927
    ***000114
    **2928
    ***.000114
    000114.2928

How can I read at 1Hz from the 10Hz data stream? I want to just store one data value from the stream per second in the form of 000114.2927, then ignore the rest while the Arduino does something else.

Thanks!

title: Read one value from continuous data stream at a lower frequency

Answers: 3

body:
I would use Stream class timed functions. Serial is implementation of Stream. The property `timeout` (`setTimeout`) sets how long will the blocking functions wait for the next byte/character. Default timeuot is 1000 ms.

Timed functions of Stream are `find`, `parseInt`, `parseFloat`, `readBytes`, `readBytesUntil`, `readString` and `readStringUntil`. (Non blocking read functions are `available`, `read` and `peek`.)

body:
You're thinking backwards. You don't want to *read* slower (which is what delay does), you want to *only send every 10th entry*.

That is, count the lines as they come in. When you hit 10 you print one and reset your count.

In other words:

    static int count = 0;

    if(newParoData == true){

      count ++;
      if (count == 10) {
          count = 0;

          // (Why copy the line just to send the copy...?)
          for(int i=0; i<16; i++){
            paroToSend[i] = paroChars[i];
          }
          Serial.print(paroToSend); Serial.print('\n');     //transmit Paro data with a new line for each value
      }
      newParoData = false;
    }

body:
Majenko’s answer is spot on: you just have to count the sentences you
read and repeat one every ten sentences. And you don't need two copies
of the sentence you are reading: one is enough. But I would add that you
don't even need a single copy: you can just echo back the characters you
read, without ever storing them, until you hit a `'*'`:

<!-- language: lang-c++ -->

    void loop()
    {
        static uint8_t sentence_count;
        if (paroSerial.available()) {
            char c = paroSerial.read();
            if (c == '*') {
                // Increment the sentence count modulo 10.
                if (++sentence_count == 10)
                    sentence_count = 0;
            } else if (sentence_count == 0) {
                // This is one sentence we have to repeat.
                Serial.write(c);
            }
        }
    }

As a side note, if your program doesn't read input from the computer,
and if it doesn't send anything to the transducer, then you may consider
getting rid of `SoftwareSerial` and using only the hardware serial port:

* the receiver part of the port for reading the data from the transducer
* the emitter part to send the data to the computer.

Yes, it is perfectly fine to use the receiver and the transmitter for
different links. The only caveat is that you will have to use the same
port configuration on both sides: if the transducer talks at
9600 bps, then the whole port will have to run at 9600 bps.


body:
I have Arduino Code that utilizes the I2CDev library to control an MPU-6050. I am pretty new to coding and copied and pasted most of the code from examples I have found around. I am starting to run out of programming space on my Arduino, and I have found that one line of the code takes up 21%, or 6000 bytes of the programming memory. I found the function that the line related to and I have it shown below.

The link to the I2CDev libarary can be found on Github here as well:
https://github.com/jrowberg/i2cdevlib

Is there a way to decrease it? Ot can someone explain to me why it is taking up so much space? Thanks!

    uint8_t MPU6050::dmpInitialize() {
    // reset device
    DEBUG_PRINTLN(F("\n\nResetting MPU6050..."));
    reset();
    delay(30); // wait after reset

    // enable sleep mode and wake cycle
    /*Serial.println(F("Enabling sleep mode..."));
    setSleepEnabled(true);
    Serial.println(F("Enabling wake cycle..."));
    setWakeCycleEnabled(true);*/

    // disable sleep mode
    DEBUG_PRINTLN(F("Disabling sleep mode..."));
    setSleepEnabled(false);

    // get MPU hardware revision
    DEBUG_PRINTLN(F("Selecting user bank 16..."));
    setMemoryBank(0x10, true, true);
    DEBUG_PRINTLN(F("Selecting memory byte 6..."));
    setMemoryStartAddress(0x06);
    DEBUG_PRINTLN(F("Checking hardware revision..."));
    DEBUG_PRINT(F("Revision @ user[16][6] = "));
    DEBUG_PRINTLNF(readMemoryByte(), HEX);
    DEBUG_PRINTLN(F("Resetting memory bank selection to 0..."));
    setMemoryBank(0, false, false);

    // check OTP bank valid
    DEBUG_PRINTLN(F("Reading OTP bank valid flag..."));
    DEBUG_PRINT(F("OTP bank is "));
    DEBUG_PRINTLN(getOTPBankValid() ? F("valid!") : F("invalid!"));

    // get X/Y/Z gyro offsets
    DEBUG_PRINTLN(F("Reading gyro offset TC values..."));
    int8_t xgOffsetTC = getXGyroOffsetTC();
    int8_t ygOffsetTC = getYGyroOffsetTC();
    int8_t zgOffsetTC = getZGyroOffsetTC();
    DEBUG_PRINT(F("X gyro offset = "));
    DEBUG_PRINTLN(xgOffsetTC);
    DEBUG_PRINT(F("Y gyro offset = "));
    DEBUG_PRINTLN(ygOffsetTC);
    DEBUG_PRINT(F("Z gyro offset = "));
    DEBUG_PRINTLN(zgOffsetTC);

    // setup weird slave stuff (?)
    DEBUG_PRINTLN(F("Setting slave 0 address to 0x7F..."));
    setSlaveAddress(0, 0x7F);
    DEBUG_PRINTLN(F("Disabling I2C Master mode..."));
    setI2CMasterModeEnabled(false);
    DEBUG_PRINTLN(F("Setting slave 0 address to 0x68 (self)..."));
    setSlaveAddress(0, 0x68);
    DEBUG_PRINTLN(F("Resetting I2C Master control..."));
    resetI2CMaster();
    delay(20);

    // load DMP code into memory banks
    DEBUG_PRINT(F("Writing DMP code to MPU memory banks ("));
    DEBUG_PRINT(MPU6050_DMP_CODE_SIZE);
    DEBUG_PRINTLN(F(" bytes)"));
    if (writeProgMemoryBlock(dmpMemory, MPU6050_DMP_CODE_SIZE)) {
        DEBUG_PRINTLN(F("Success! DMP code written and verified."));

        // write DMP configuration
        DEBUG_PRINT(F("Writing DMP configuration to MPU memory banks ("));
        DEBUG_PRINT(MPU6050_DMP_CONFIG_SIZE);
        DEBUG_PRINTLN(F(" bytes in config def)"));
        if (writeProgDMPConfigurationSet(dmpConfig, MPU6050_DMP_CONFIG_SIZE)) {
            DEBUG_PRINTLN(F("Success! DMP configuration written and verified."));

            DEBUG_PRINTLN(F("Setting clock source to Z Gyro..."));
            setClockSource(MPU6050_CLOCK_PLL_ZGYRO);

            DEBUG_PRINTLN(F("Setting DMP and FIFO_OFLOW interrupts enabled..."));
            setIntEnabled(0x12);

            DEBUG_PRINTLN(F("Setting sample rate to 200Hz..."));
            setRate(4); // 1khz / (1 + 4) = 200 Hz

            DEBUG_PRINTLN(F("Setting external frame sync to TEMP_OUT_L[0]..."));
            setExternalFrameSync(MPU6050_EXT_SYNC_TEMP_OUT_L);

            DEBUG_PRINTLN(F("Setting DLPF bandwidth to 42Hz..."));
            setDLPFMode(MPU6050_DLPF_BW_42);

            DEBUG_PRINTLN(F("Setting gyro sensitivity to +/- 2000 deg/sec..."));
            setFullScaleGyroRange(MPU6050_GYRO_FS_2000);

            DEBUG_PRINTLN(F("Setting DMP programm start address"));
            //write start address MSB into register
            setDMPConfig1(0x03);
            //write start address LSB into register
            setDMPConfig2(0x00);

            DEBUG_PRINTLN(F("Clearing OTP Bank flag..."));
            setOTPBankValid(false);

            DEBUG_PRINTLN(F("Setting X/Y/Z gyro offset TCs to previous values..."));
            setXGyroOffsetTC(xgOffsetTC);
            setYGyroOffsetTC(ygOffsetTC);
            setZGyroOffsetTC(zgOffsetTC);

            DEBUG_PRINTLN(F("Setting X/Y/Z gyro user offsets to zero..."));
            //setXGyroOffset(0);
            //setYGyroOffset(0);
            //setZGyroOffset(0);

            DEBUG_PRINTLN(F("Writing final memory update 1/7 (function unknown)..."));
            uint8_t dmpUpdate[16], j;
            uint16_t pos = 0;
            for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
            writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

            DEBUG_PRINTLN(F("Writing final memory update 2/7 (function unknown)..."));
            for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
            writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

            DEBUG_PRINTLN(F("Resetting FIFO..."));
            resetFIFO();

            DEBUG_PRINTLN(F("Reading FIFO count..."));
            uint16_t fifoCount = getFIFOCount();
            uint8_t fifoBuffer[128];

            DEBUG_PRINT(F("Current FIFO count="));
            DEBUG_PRINTLN(fifoCount);
            getFIFOBytes(fifoBuffer, fifoCount);

            DEBUG_PRINTLN(F("Setting motion detection threshold to 2..."));
            setMotionDetectionThreshold(2);

            DEBUG_PRINTLN(F("Setting zero-motion detection threshold to 156..."));
            setZeroMotionDetectionThreshold(156);

            DEBUG_PRINTLN(F("Setting motion detection duration to 80..."));
            setMotionDetectionDuration(80);

            DEBUG_PRINTLN(F("Setting zero-motion detection duration to 0..."));
            setZeroMotionDetectionDuration(0);

            DEBUG_PRINTLN(F("Resetting FIFO..."));
            resetFIFO();

            DEBUG_PRINTLN(F("Enabling FIFO..."));
            setFIFOEnabled(true);

            DEBUG_PRINTLN(F("Enabling DMP..."));
            setDMPEnabled(true);

            DEBUG_PRINTLN(F("Resetting DMP..."));
            resetDMP();

            DEBUG_PRINTLN(F("Writing final memory update 3/7 (function unknown)..."));
            for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
            writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

            DEBUG_PRINTLN(F("Writing final memory update 4/7 (function unknown)..."));
            for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
            writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

            DEBUG_PRINTLN(F("Writing final memory update 5/7 (function unknown)..."));
            for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
            writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

            DEBUG_PRINTLN(F("Waiting for FIFO count > 2..."));
            while ((fifoCount = getFIFOCount()) < 3);

            DEBUG_PRINT(F("Current FIFO count="));
            DEBUG_PRINTLN(fifoCount);
            DEBUG_PRINTLN(F("Reading FIFO data..."));
            getFIFOBytes(fifoBuffer, fifoCount);

            DEBUG_PRINTLN(F("Reading interrupt status..."));

            DEBUG_PRINT(F("Current interrupt status="));
            DEBUG_PRINTLNF(getIntStatus(), HEX);

            DEBUG_PRINTLN(F("Reading final memory update 6/7 (function unknown)..."));
            for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
            readMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

            DEBUG_PRINTLN(F("Waiting for FIFO count > 2..."));
            while ((fifoCount = getFIFOCount()) < 3);

            DEBUG_PRINT(F("Current FIFO count="));
            DEBUG_PRINTLN(fifoCount);

            DEBUG_PRINTLN(F("Reading FIFO data..."));
            getFIFOBytes(fifoBuffer, fifoCount);

            DEBUG_PRINTLN(F("Reading interrupt status..."));

            DEBUG_PRINT(F("Current interrupt status="));
            DEBUG_PRINTLNF(getIntStatus(), HEX);

            DEBUG_PRINTLN(F("Writing final memory update 7/7 (function unknown)..."));
            for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
            writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

            DEBUG_PRINTLN(F("DMP is good to go! Finally."));

            DEBUG_PRINTLN(F("Disabling DMP (you turn it on later)..."));
            setDMPEnabled(false);

            DEBUG_PRINTLN(F("Setting up internal 42-byte (default) DMP packet buffer..."));
            dmpPacketSize = 42;
            /*if ((dmpPacketBuffer = (uint8_t *)malloc(42)) == 0) {
                return 3; // TODO: proper error code for no memory
            }*/

            DEBUG_PRINTLN(F("Resetting FIFO and clearing INT status one last time..."));
            resetFIFO();
            getIntStatus();
        } else {
            DEBUG_PRINTLN(F("ERROR! DMP configuration verification failed."));
            return 2; // configuration block loading failed
        }
    } else {
        DEBUG_PRINTLN(F("ERROR! DMP code verification failed."));
        return 1; // main binary block loading failed
    }
    return 0; // success
}

title: Decreasing a functions programming size

Answers: 1

body:
One line of code doesn't use 6000 bytes of memory. However if it calls a function, which otherwise would not be called, then the compiler has to include the function.

So, for example, if you have a function that takes 6000 bytes, but don't call it, then the compiler can omit the function itself.

---

Assuming DEBUG_PRINTLN does something, then I count 2480 bytes of string literals there. Therefore your function would at the very least take up 2480 bytes. And that is called 71 times, so if DEBUG_PRINTLN takes (say) 10 bytes to call each time, that is another 710 bytes. We are already up to 3190 bytes. Other stuff (unrelated to debugging) also probably takes quite a few bytes.

---

> I am starting to run out of programming space on my Arduino

That's not a problem until you **actually** run out of space. Who cares if you use 99% of available memory?

---

The fact that something causes a jump in memory usage is not, in itself, cause for worry. For example this sketch:

    void setup() {
      Serial.begin(115200);
      int a;
      Serial.println (a);
    }

    void loop() {  }

Compiled for a Uno using IDE 1.6.9 I get:

    Sketch uses 2,122 bytes (6%) of program storage space. Maximum is 32,256 bytes.

So, 2,122 bytes. Now change `a` to be float:

    void setup() {
      Serial.begin(115200);
      float a;
      Serial.println (a);
    }

    void loop() {  }

Now it uses 3,668 bytes:

    Sketch uses 3,668 bytes (11%) of program storage space. Maximum is 32,256 bytes. That's another 1,546 bytes just by changing one variable's type.

However it doesn't take **another** 1,546 bytes if you add a second such variable.

    void setup() {
      Serial.begin(115200);
      float a;
      float b;
      Serial.println (a);
      Serial.println (b);
    }

    void loop() {  }

That only uses another 18 bytes:

    Sketch uses 3,686 bytes (11%) of program storage space. Maximum is 32,256 bytes.

In other words, the floating-point library has now been included by the compiler. This is a once-off jump in usage. Of course, if I now do something with I2C there will be another jump as that additional library is loaded.


body:
I already have an Arduino Uno, and I want to learn Internet-of-Things. I'm planning to use an ESP8266 since it's cheap. Should I purchase an ESP8266 Wifi transceiver module to use with my Arduino Uno or just buy an ESP8266 NodeMCU board?

Is there any advantage using an ESP8266 NodeMCU board to using my Arduino Uno with an ESP8266 Serial transceiver module?

title: Arduino Uno with ESP8266 Wifi transceiver or ESP8266 NodeMCU board?

Answers: 1

body:
In my opinion, it is more desirable to program the ESP8266 directly. I'm always shivering when I see a Uno (ab)using the ESP8266 as a WiFi bridge when the ESP8266 already has everything needed for the project. Of course, this is highly project specific.

Advantages of programming an ESP8266 directly:

 * you learn about a new MCU and architecture (XTensa vs AVR)
 * you learn to use a new Arduino Core (Arduino-ESP8266)
 * ESP8266 is way more powerful than the Arduino Uno
  * 80MHz (overclockable to 160MHz) vs 16 MHz
  * ~40kB free RAM at startup vs 2 kB
  * 4 MB Flash vs 32kB
  * can use an RTOS like FreeRTOS
  * Flash can be used as filesystem (e.g. for a [HTTP(S) server](https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer))
  * ==> we can build way more complex projects
 * WiFi radio and stack directly on the processor, no need to get information via a serial bridge
  * higher speed, more direct control over sockets etc.
 * you can try out other frameworks and languages, such as
  * [Micropython](https://docs.micropython.org/en/latest/esp8266/esp8266/tutorial/intro.html)
  * [esp-open-rtos](https://github.com/SuperHouse/esp-open-rtos)
  * the [NodeMCU firwmare](https://nodemcu.readthedocs.io/en/master/) (Lua language)
  * Espressif's [NON-RTOS](https://github.com/espressif/ESP8266_NONOS_SDK) / [RTOS](https://github.com/espressif/ESP8266_RTOS_SDK) SDKs
 * easier to move to its big brother, the [ESP32](https://en.wikipedia.org/wiki/ESP32) (Dual-Core XTensa LX6 @ 240MHz, WiFi + BT, 4MB Flash, 520kB RAM (+4MB PSRAM optional), tons of peripherals and accelerators) for even more complex projects

Disadvantages:

* only 1 ADC input (vs. 6) with a voltage range of 0 to 1.0V (unlike the normal 5V range on the Uno)
 * remedy: external ADCs via I2C / SPI (e.g. [MCP3008](https://www.adafruit.com/product/856))
* 3.3V device, must be careful when connecting to existing 5V devices or shields
 * remedy: [logic level shifters][1], voltage regulators
* less number of available digital GPIO pins (9 vs 13)
 * remedy: external GPIO expanders via I2C/SPI (e.g. [PCF8574][2], [MCP23017][3])

In summary, I think a good way of acquiring a better skillset is to try to explore and program a new board directly vs programming the old board and slapping the new one on top over serial. I hope this gave a rough overview of why an ESP8266 might be better (or worse) for a certain project.

  [1]: https://www.sparkfun.com/products/12009
  [2]: http://www.ti.com/product/PCF8574
  [3]: https://www.adafruit.com/product/732


body:
As I'm experiencing weird bugs in a rather lengthy project, I started analyzing my RAM usage on my ATMEGA328P with Arduino bootloader. At least I tried to and wrote the following piece of code. Consider the following written in Arduino IDE 1.8.5:

    extern int __heap_start, *__brkval;

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

    void loop() {
      // put your main code here, to run repeatedly:
      delay(500);
      f1();
      delay(500);
      freeRAM();
    }

    void f1() {
      int local = 0;
      local = 6;
      freeRAM();

    }

    void freeRAM() {
      int local = 0;
      local = 5;
      if (*__brkval == 0) {
        Serial.println("The break point is 0,...");
        Serial.println((int)&local - __heap_start);
      }
      else {
        Serial.println("The break point is not 0,...");
        Serial.println((int)&local - *__brkval);
      }
    }

And the rather unexpected output:

    The break point is not 0,...
    2048
    The break point is 0,...
    2294
    The break point is 0,...
    2294
    The break point is 0,...
    2294
    The break point is 0,...
    2294
    The break point is 0,...
    2294
    The break point is 0,...
    2294
    The break point is 0,...
    2294

I was expecting 2 different values of free RAM because on the second call of freeFram(); the function call and local variables of f1() should already be popped from the stack. Perhaps i misused the external variables (__heap_start, __brkval) or I misinterpreted one of the links I read:

[memories-of-an-arduino][1]

[Lecture 08: Memory Allocation and Program Memory Layout][2]

Perhaps someone could elaborate on this.

EDIT:
@Gerben: Thx for the hint, didn't change anything though!

@Edgar:

Looking at a snippet of the objdump:

     76e:   0e 94 8e 01     call    0x31c   ; 0x31c <delay.constprop.3>
     772:   1a 82           std     Y+2, r1 ; 0x02
     774:   19 82           std     Y+1, r1 ; 0x01
     776:   1a 83           std     Y+2, r17        ; 0x02
     778:   09 83           std     Y+1, r16        ; 0x01
     77a:   0e 94 5a 02     call    0x4b4   ; 0x4b4 <_Z7freeRAMv>
     77e:   0e 94 8e 01     call    0x31c   ; 0x31c <delay.constprop.3>
     782:   0e 94 5a 02     call    0x4b4   ; 0x4b4 <_Z7freeRAMv>
     786:   0e 94 5f 01     call    0x2be   ; 0x2be <_Z14serialEventRunv>
     78a:   f1 cf           rjmp    .-30            ; 0x76e <main+0xfe>

I realized the compiler was indeed inlining the call to f1(). Changing f1() to:

    __attribute__((noinline)) void f1() {
      volatile int local = 0;
      local = 6;
      freeRAM();

    }

and results in the following objdump:

     784:   0e 94 8e 01     call    0x31c   ; 0x31c <delay.constprop.3>
     788:   0e 94 94 02     call    0x528   ; 0x528 <_Z2f1v>
     78c:   0e 94 8e 01     call    0x31c   ; 0x31c <delay.constprop.3>
     790:   0e 94 5a 02     call    0x4b4   ; 0x4b4 <_Z7freeRAMv>
     794:   0e 94 5f 01     call    0x2be   ; 0x2be <_Z14serialEventRunv>
     798:   f5 cf           rjmp    .-22            ; 0x784 <main+0xf0>

which therefore results in the desired behaviour:

    The break point is 0,...
    2294
    The break point is 0,...
    2288
    The break point is 0,...
    2294
    The break point is 0,...
    2288
    The break point is 0,...
    2294
    The break point is 0,...
    2288
    The break point is 0,...
    2294

Thanks a lot!

A question that's on my mind now: Looking at the values of freeRam, shouldn't the value be smaller than 2048? Am I calculating wrong?

EDIT #2: In the meantime it turned out that my "memory"-problem was actually some self induced pointer stupidity :/

But for the sake of completeness, and if someone is on the search for a method for memory analysis like I was, here are my 2 cents.

@Gerben: I'm sry, I realised that I have to declare the function noinline as well as declare some volatile variable in it to stop the compiler from inlining the call. So Edgar and you were both right at the beginning!!

@Edgar you were completly right again, with you and some reading from here:

[Official freeRam() command #5289][3]

I came up with the following code:

    extern int __heap_start, *__brkval;

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

    void loop() {
      // put your main code here, to run repeatedly:
      reportFreeRAM();
      delay(500);
      f1();
      delay(500);

    }

    __attribute__((noinline)) void f1() {
      //String s = "foobar";
      volatile char arr[7] = "foobar";
      reportFreeRAM();

    }

    void reportFreeRAM () {
      int v;
      Serial.println("-------RAM Report---------");
      Serial.print("__brkval = ");
      Serial.println((int)__brkval);
      Serial.print("FreeRAM: ");
      Serial.println((int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval));
    }

which results in the following output:

    -------RAM Report---------
    __brkval = 0
    FreeRAM: 1792
    -------RAM Report---------
    __brkval = 0
    FreeRAM: 1781
    -------RAM Report---------
    __brkval = 0
    FreeRAM: 1792
    -------RAM Report---------
    __brkval = 0
    FreeRAM: 1781
    -------RAM Report---------
    __brkval = 0
    FreeRAM: 1792

and if f1() is changed to:

    __attribute__((noinline)) void f1() {
      String s = "foobar";
      //volatile char arr[7] = "foobar";
      reportFreeRAM();
    }

we see the following result:

    -------RAM Report---------
    __brkval = 0
    FreeRAM: 1786
    -------RAM Report---------
    __brkval = 519
    FreeRAM: 1773
    -------RAM Report---------
    __brkval = 510
    FreeRAM: 1786
    -------RAM Report---------
    __brkval = 519
    FreeRAM: 1773
    -------RAM Report---------
    __brkval = 510
    FreeRAM: 1786

which is rather interesting, because you see the break-point-pointer getting initialised with the first allocation for the String variable and after that the value jumping back and forth. Which is to my understanding the expected behaviour. For my application I wanted to check if I had allocated any memory dynamically, so I guess an easy check would be to check (int)__brkval for zero. Perhaps someone could elaborate if that is always a good idea or not.

So sry for the lengthy post, I just wanted to show what I found, in case someone stumbles over the same kind of question.

Thx @Gerben and @Edgar!

  [1]: https://learn.adafruit.com/memories-of-an-arduino/measuring-free-memory
  [2]: https://www.usna.edu/Users/cs/aviv/classes/ic221/s16/lec/08/lec.html
  [3]: https://github.com/arduino/Arduino/issues/5289

title: Question about memory allocation analysis

Answers: 0


body:
i'm trying to make a digital dice to play catan with, here's what i have so far

    #include <LiquidCrystal.h>
    #include <DFR_LCD_Keypad.h>

    // this is factory config shield initialisation
    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

    // initialise the keypad
    DFR_LCD_Keypad keypad(A0, &lcd);
    int lcd_key     = 0;
    int abc_key_in;
    int read_LCD_buttons;
    int  diceOne;
    int  diceTwo;
    #define btnSELECT 4
    int read_LCD_buttons()
    {
      abc_key_in = analogRead(0);
    if (abc_key_in < 790) return btnSELECT;}
    const int button = 4;
    const int BUTTON4LOW = 400;
    const int BUTTON4HIGH = 650;

    void setup() {
      lcd.begin(16, 2);
      lcd.setCursor(0, 0);
      lcd.print("Press to dice");
      pinMode (A0, INPUT);
      i
    }

    void loop() {
      int reading =  analogRead (A0);

      lcd_key = read_LCD_buttons();

     if (reading<BUTTON4LOW && reading<BUTTON4HIGH) {
        diceOne = random(1, 7);
        diceTwo = random(1, 7);

      if (diceOne + diceTwo == 7) {
        lcd.clear();
        lcd.setCursor(7, 0);
        lcd.print("7");
        lcd.setCursor(3, 1);
        lcd.print("The pirate");

          if (diceOne + diceTwo == 3,2,1,5,4,6) {
              lcd.clear();
              lcd.setCursor(7, 0);
              lcd.print("fish");
          }
          }
      }
    }
    }

and im running into a error code saying

    Arduino: 1.8.5 (Windows Store 1.8.10.0) (Windows 10), Board: "Arduino/Genuino Uno"

    demo_simple:15: error: 'int read_LCD_buttons()' redeclared as different kind of symbol
     int read_LCD_buttons()
                          ^
    C:\Users\taran\Desktop\arduino\demo_simple\demo_simple.ino:11:5: note: previous declaration 'int read_LCD_buttons'
     int read_LCD_buttons;
         ^
    C:\Users\taran\Desktop\arduino\demo_simple\demo_simple.ino: In function 'int read_LCD_buttons()':
    demo_simple:15: error: 'int read_LCD_buttons()' redeclared as different kind of symbol
     int read_LCD_buttons()
                          ^
    C:\Users\taran\Desktop\arduino\demo_simple\demo_simple.ino:11:5: note: previous declaration 'int read_LCD_buttons
     int read_LCD_buttons;
         ^
    C:\Users\taran\Desktop\arduino\demo_simple\demo_simple.ino: In function 'void setup()':
    demo_simple:28: error: 'i' was not declared in this scope
       i
       ^
    C:\Users\taran\Desktop\arduino\demo_simple\demo_simple.ino: In function 'void loop()':
    demo_simple:34: error: 'read_LCD_buttons' cannot be used as a function
       lcd_key = read_LCD_buttons();
                                  ^
    C:\Users\taran\Desktop\arduino\demo_simple\demo_simple.ino: At global scope:
    demo_simple:58: error: expected declaration before '}' token
     }
     ^
    exit status 1
    'int read_LCD_buttons()' redeclared as different kind of symbol

title: making a digital dice

Answers: 1

body:
You have

    int read_LCD_buttons;

    int read_LCD_buttons()
    {
    //..
    }

You can't have a variable `int read_LCD_buttons` at the same time as a function called `read_LCD_buttons` -- this identifier is already taken. It looks however like you're not assigning or reading anything from this variable, so it probably never should have existed in the first place -- deletion is the solution.

In the case that you wanted to write a function prototype (which you by the way don't have to write in the Arduino IDE because it autogenerates them), the correct form would have been

    int read_LCD_buttons();

i.e., the exact same prototype ended by a `;`.

In `setup()` you have a random `i` which doesn't belong there.

    void setup() {
      lcd.begin(16, 2);
      lcd.setCursor(0, 0);
      lcd.print("Press to dice");
      pinMode (A0, INPUT);
      i //delete this line
    }

Finally, you have a mismatch of opening and closing curly braces. Always format your code correctly, so that these errors are more easily spotted! You have one final `}` too much.

    void loop() {
      int reading = analogRead(A0);

      lcd_key = read_LCD_buttons();

      if (reading < BUTTON4LOW && reading < BUTTON4HIGH) {
        diceOne = random(1, 7);
        diceTwo = random(1, 7);

        if (diceOne + diceTwo == 7) {
          lcd.clear();
          lcd.setCursor(7, 0);
          lcd.print("7");
          lcd.setCursor(3, 1);
          lcd.print("The pirate");

          if (diceOne + diceTwo == 3, 2, 1, 5, 4, 6) {
            lcd.clear();
            lcd.setCursor(7, 0);
            lcd.print("fish");
          }
        }
      }
    }
    } //This } is too much!

Then you'll also see that the third `if` statment which checks for a sum is actually within another expression where it was asserted that the sum is already 7. Then the inner `if` can never become true. You probably meant to move the `if` to the outer part, i.e. write

    void loop() {
      int reading = analogRead(A0);

      lcd_key = read_LCD_buttons();

      if (reading < BUTTON4LOW && reading < BUTTON4HIGH) {
        diceOne = random(1, 7);
        diceTwo = random(1, 7);

        if (diceOne + diceTwo == 7) {
          lcd.clear();
          lcd.setCursor(7, 0);
          lcd.print("7");
          lcd.setCursor(3, 1);
          lcd.print("The pirate");
        }
        //the line below is still wrong
        if (diceOne + diceTwo == 3, 2, 1, 5, 4, 6) {
          lcd.clear();
          lcd.setCursor(7, 0);
          lcd.print("fish");
        }
      }
    }

Next, this expression makes no sense.

    if (diceOne + diceTwo == 3,2,1,5,4,6)

I think you meant that "if the sum of diceOne and diceTwo are equal to either 3, 2, 1, 5, 4, or 6 (i.e. within 1 and 6 inclusive), then do something.

Using multiple or statments this would be expressed as

    if ((diceOne + diceTwo == 3) || (diceOne + diceTwo == 2) || (diceOne + diceTwo == 1) || (diceOne + diceTwo == 5) ||(diceOne + diceTwo == 4) || (diceOne + diceTwo == 6))

Or using the simpler interval check, assuming both numbers are positive and greater than 1.

    if( diceOne + diceTwo <= 6)

Also this expression is suspect

    if (reading<BUTTON4LOW && reading<BUTTON4HIGH)

When you have a LOW and a HIGH boundary and you want to check if `reading` is between these, you would write it as "if reading is greater than the lower boundary and less than the higher boundary", i.e.,

    if (reading > BUTTON4LOW && reading < BUTTON4HIGH)


body:
**Problem:**
SPI Connection between two D1 (ESP8266) boards does not work properly, only master to slave transfers data correctly.

**What I did:**
I connected two Wemos D1 R2 via SPI and installed the library from https://github.com/esp8266/Arduino. I connected MISO, MOSI, SCK, SS and ground 1:1. On one D1 I run SPISlaveTest on the other SPIMaster from the examples. The D1 are located directly beside each other, cables are only 15 cm long.

**Effect:**
While the slave receives strings from the master fine the master seems to get crippeled answers from the slave, they appear as ??? and other characters. If I connect the slaves SS to +3.3V it reacts like expected: The slave receives no more, the master gets no reponses.

**What I already tried:**

- Updated the Libraries to the latest versions
- Changed delay to wait for answer
- tried SafeMaster.ino
- Changed D1 hardware on both sides

Everything unfortunately did not help.

Any tip is very appreciated.

Thanks!

title: Connect two D1 R2 (8266) via SPI with Github SPISlave Library

Answers: 0


body:
I'm working on a project with Arduino UNO that needs connection with a cloud server, that is why I'm using ESP8266 module.

I'm already connecting to wi-fi and making GET and POST request but my problem is get the response from these requests.

Here is my code:

    /* Doing all these steps to make the request
    AT+RST
    AT+CWMODE=1
    AT+CWJAP="MyNetwork","MyPassword"
    AT+CIPMUX=1
    AT+CIPSTART=0,"TCP","myserver.com.br",80
    AT+CIPSEND=0,270
    */

    String data = "data=example";

    String command = "POST /webservice/v1/dispositivo/atualizar_data_requisicao HTTP/1.1\r\n";
    comando += "Host: " + SERVER + "\r\n";
    comando += "User-Agent: Arduino/1.0\r\n";
    comando += "Connection: Close\r\n";
    comando += "Content-Type: application/x-www-form-urlencoded;\r\n";
    comando += "Content-Length: " + String(data.length()) + "\r\n\r\n";
    comando += data;

    esp8266.println(command);

    delay(2000);

    String response;

    while(esp8266.available()) {
      response += esp8266.readStringUntil('\r');
    }

    Serial.print("Request response: ");
    Serial.println(response);

When I run this code the only response I can get is something like:

    Recv 270 bxt⸮⸮C⸮
    SEND OK

    +IPD,0.569:HTTP/1.0 200 OK

But I was expecting a JSON.

Can someone tell me what I am doing wrong and how can I resolve it?

---

Edit.

Ok, after Code Gorilla helps me (Thank you so much) and a lot of research what I did was program Arduino UNO to send some commands that I invented to serial and program ESP8266 to read the serial and, depending of the command that it reads, do requests and stuff.

ESP8266 is a lot easyer to make requests and have a lot of others possibilities, like HTTPS requests, that you can't do using AT Commands.

When I create this ask I didn't know that I could program directly in ESP8266, but when Code Gorilla told me about it and helps me with some articles I could finally continue with my project.

title: Response from ESP8266 is returning unknown characters

Answers: 1

body:
    String command = "POST /webservice/v1/dispositivo/atualizar_data_requisicao HTTP/1.1\r\n";
    comando += "Host: " + SERVER + "\r\n";
    ...
    esp8266.println(command);

I suspect this is just a typo because it shouldn't compile.  But you are adding all the HTTP headers to **commando** not **command**.

Usually the ? means that the character is unprintable.  So to help diagnose the issue display the integer value for each character that is returned.  Something **LIKE** this (I've never used a `String` before so length() might not be right)

    Serial.print("Request response: ");
    Serial.println(response);
    for (int index = 0; index < response.length(); ++index)
    {
       Serial.print (response[index]);
       Serial.print (" ");
    }

If you want to program the ESP directly then have a look at these guides, they should give you the general idea.  Its usually as easy as programming an UNO once you are setup.

http://www.whatimade.today/esp8266-easiest-way-to-program-so-far/
https://learn.adafruit.com/adafruit-huzzah-esp8266-breakout/using-arduino-ide
https://www.hackster.io/harshmangukiya/how-to-program-esp8266-with-arduino-uno-efb05f


body:
I've been piecing together various lighting effects. I am wanting to have each lighting effect loop until another button is pressed to trigger another lighting effect.

I've come to a bit of standstill at the moment. I've created a loop that doesn't seem to end. I've had a look around but I can't work out how to fix my code. Sorry in advanced, I'm new to using arduinos but if anyone could help out, it would be much appreciated.
Thanks!
<!-- language-all: lang-cpp -->

    //www.elegoo.com
    //2016.12.9

    #include "IRremote.h"
    #include <Adafruit_NeoPixel.h>
    #ifdef __AVR__
    #include <avr/power.h>
    #endif
    #define PIN 6

    Adafruit_NeoPixel strip = Adafruit_NeoPixel(20, PIN, NEO_GRB + NEO_KHZ800);

    int receiver = 11; // Signal Pin of IR receiver to Arduino Digital Pin 11

    /*-----( Declare objects )-----*/
    IRrecv irrecv(receiver);     // create instance of 'irrecv'
    decode_results results;      // create instance of 'decode_results'
    int Remote = 0;

    /*-----( Function )-----*/
    void translateIR() // takes action based on IR code received

    // describing Remote IR codes

    {

      switch(results.value)

      {
      case 0xFFA25D: Serial.println("POWER");
      ArrowRight(strip.Color(25, 0, 0), 100); //Red
      ArrowRight(strip.Color(0, 0, 25), 100); //Blue
    //  Remote = 0xFFA25D;
      break;

      case 0xFFE21D: Serial.println("FUNC/STOP");
      ArrowLeft(strip.Color(25, 0, 0), 100); // Red
      ArrowLeft(strip.Color(0, 0, 25), 100); // Blue
    //  Remote = 0xFFE21D;
      break;

      case 0xFF629D: Serial.println("VOL+"); break;
      case 0xFF22DD: Serial.println("FAST BACK");    break;
      case 0xFF02FD: Serial.println("PAUSE");    break;
      case 0xFFC23D: Serial.println("FAST FORWARD");   break;
      case 0xFFE01F: Serial.println("DOWN");    break;
      case 0xFFA857: Serial.println("VOL-");    break;
      case 0xFF906F: Serial.println("UP");    break;
      case 0xFF9867: Serial.println("EQ");    break;
      case 0xFFB04F: Serial.println("ST/REPT");    break;
      case 0xFF6897: Serial.println("0");    break;
      case 0xFF30CF: Serial.println("1");    break;
      case 0xFF18E7: Serial.println("2");    break;
      case 0xFF7A85: Serial.println("3");    break;
      case 0xFF10EF: Serial.println("4");    break;
      case 0xFF38C7: Serial.println("5");    break;
      case 0xFF5AA5: Serial.println("6");    break;
      case 0xFF42BD: Serial.println("7");    break;
      case 0xFF4AB5: Serial.println("8");    break;
      case 0xFF52AD: Serial.println("9");    break;
      case 0xFFFFFFFF: Serial.println(" REPEAT");break;

      default:
        Serial.println(" other button   ");

      }// End Case

      delay(0); // Do not get immediate repeat

    } //END translateIR
    void setup()   /*----( SETUP: RUNS ONCE )----*/
    {
      Serial.begin(9600);
      Serial.println("IR Receiver Button Decode");
      irrecv.enableIRIn(); // Start the receiver
      strip.begin();
      strip.show();
      Remote = 0;

    }/*--(end setup )---*/

    void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
    {
      if (irrecv.decode(&results)) // have we received an IR signal?

      {
        translateIR();
        irrecv.resume(); // receive the next value
      }
    }/* --(end main loop )-- */

    void ArrowRight(uint32_t c, uint8_t wait) {
      while (Remote = 0xFFA25D) {
        for (uint16_t i = strip.numPixels()/2; i < strip.numPixels(); i++) {
          strip.setPixelColor(i, c);
          strip.show();
          delay(wait);
        }
        for (uint16_t i = 0; i < strip.numPixels(); i++) {
          strip.setPixelColor(i, 0);
        }
        strip.show();
        delay(wait);
      }
    }

    void ArrowLeft(uint32_t c, uint8_t wait) {
      while (Remote = 0xFFE21D) { // The j<# determines how many cycles
        for (uint16_t i = strip.numPixels()/2-1; i + 1 > 0 ; i--) {
          strip.setPixelColor(i, c);
          strip.show();
          delay(wait);
        }
        for (uint16_t i = strip.numPixels(); i + 1 > 0 ; i--) {
          strip.setPixelColor(i, 0);
        }
        strip.show();
        delay(wait);
      }
    }

title: Breaking out of a while loop using IR remote for neopixel

Answers: 1

body:
There are a few causes for eternal loops and other things that will go wrong in your code.

As ChrisL noted above you are assigning a value to Remote in the while condition which is almost certainly not what you wanted to do.  On the plus side, every C/C++ programmer ever has also made that same mistake at some time or another.

Now if you change it to `while (Remote == 0xcFFE21D)` it still won't work, because Remote is always 0.  You have commented out the lines that set Remote, but they are after the call to the function.  To be honest since you know the value before you call the function (because of the switch statement) you don't need to check the value within the function so you could remove the while loop all together.  If you intention is to call this function repeatedly until a different button is pressed on the remote, the way you are doing it won't work.  you need to store the last button pressed value and then pass that into the switch statement.  When a different button is pressed update the 'last button pressed' value.

You for loop conditions need looking at.  I don't think that the number of lights in the strip is going to change while the program is running.  If that's true then your are wasting processor instructions by doing `strip.numPixels()/2-1` you might want to look at setting global values in setup.

Also the for loops might benefit from using `i >= 0` because then you don't need to do `i+1` every loop.


body:
I'm having trouble completing this code for my university final project. I feel like I'm almost there, but I can't seem to find the final buttons to press. I'm using the Arduino Pro Micro.

I have one static pressure transducer connected to the hardware serial pins, RX1 and TX0. I have one differential pressure transducer connected to digital pins 10 (Rx) and 16 (TX), on which I have implemented SoftwareSerial. I'm reading the output data from each of these transducers. Which means technically I don't need to connect the TX pins, because I'm not writing anything to them. They are already programmed to give a continuous serial data stream.

With lots of great help from StackExchange and the Arduino Forums, I'm able to write code to check for a start-marker and end-marker from the two serial ports. I'm storing each character in an array for each of the transducers.

Here is the code I'm using for the static pressure transducer:

    const byte numChars = 16;
    char paroChars[numChars];     //array to store received data
    boolean newParoData = false;

    void setup(){
      Serial.begin(9600);     //with computer
      Serial1.begin(9600);     //with Paro transducer
    }

    void loop(){
      readParo();      //read from Paro and store values in paroChars
      if(newParoData == true){
        Serial.println(paroChars);      //print Paro data with a new line for each value
        newParoData = false;
      }
    }

    void readParo(){      //reads each character from Paro and stores it in array
      static boolean receiveInProgress = false;
      static byte index = 0;
      char startMarker = '*';
      char endMarker = '\n';
      char pd;
      while(Serial1.available() && newParoData == false){
        pd = Serial1.read();
        if(receiveInProgress == true){
          if(pd != endMarker){
            paroChars[index] = pd;
            index++;
            if(index >= numChars){
              index = numChars - 1;
            }
          }else{
            paroChars[index] = '\0';      //terminate string
            receiveInProgress = false;
            index = 0;
            newParoData = true;
          }
        }else if(pd == startMarker){
          receiveInProgress = true;
        }
      }
    }

I do get the correct output on the Serial Monitor from the static pressure transducer when I upload this program to the Arduino:

    000114.2927
    000114.2928
    000114.2927
    000114.2929

Similar code goes for the differential pressure transducer:

    #include <SoftwareSerial.h>
    #define honeywell_RX 10
    #define honeywell_TX 16

    SoftwareSerial honeySerial(honeywell_RX, honeywell_TX);

    const byte numChars = 16;
    char honeyChars[numChars];     //array to store received data
    boolean newHoneyData = false;

    void setup(){
      Serial.begin(9600);     //with computer
      honeySerial.begin(9600);      //with Honeywell transducer
    }

    void loop(){
      readHoney();      //read from Honeywell and store values in honeyChars
      if(newHoneyData == true){
        Serial.println(honeyChars);    //print Honeywell data with a new line for each value
        newHoneyData = false;
      }
    }

    void readHoney(){     //read each character from Honeywell and store it in array
      static boolean honeyReceiveInProgress = false;
      static byte index = 0;
      char honeyStartMarker = '?';
      char honeyEndMarker = '?';
      char hd;
      while(honeySerial.available() && newHoneyData == false){
        hd = honeySerial.read();
        if(honeyReceiveInProgress == true){
          if(hd != honeyEndMarker){
            honeyChars[index] = hd;
            index++;
            if(index >= numChars){
              index = numChars - 1;
            }
          }else{
            honeyChars[index] = '\0';      //terminate string
            honeyReceiveInProgress = false;
            index = 0;
            newHoneyData = true;
          }
        }else if(hd == honeyStartMarker){
          honeyReceiveInProgress = true;
        }
      }
    }

And this is the output I get on the Serial Monitor for the differential pressure transducer, which is also correct:

    01CP=0.0000
    01CP=0.0001
    01CP=-0.0001
    01CP=0.0000

My problem is combining these two programs. Basically, I want to be able to read from the Hardware Serial port first, make sure that the data is valid, store it, then exit the function. After that, read from the SoftwareSerial port, make sure the data is valid, store it, and exit the function. After this I would print both arrays to the Serial Monitor. I don't know how to read from the Serial ports only until the array is filled up with valid characters, then exit. If I combine these two programs, the output is distorted, meaning the values are either bunched together, or there are random characters showing.

I found that these two pressure transducers operate at different frequencies. The static transducer gives serial output at 10Hz, while the differential transducer is about 2Hz. I'm not sure if that factors into the problem.

Basically, I want to get one reading like 000114.2927, then another like 01CP=0.0001, then print both of these to the Serial Monitor. I can't figure out how and where to break out of reading from the serial ports.

Thanks!

title: How to check for valid Serial data, then break?

Answers: 0


body:
I know it's possible to hook up multiple SPI devices, but how can one access the second drive from a sketch?

Looking at the SDWebServer.ino example, my doubt is with the `SD.begin(SS);` part. If I call `begin()` again with the other CS pin, it seems that I would lose a reference to my first volume, or maybe it won't work at all. I would instantiate another `SD` instance, but the sketch never seems to instantiate that object, it first appears in `setup()` with `SD.begin(SS);`

If I copy the lib (sd.h+sd.cpp) and replace all literal instances of `SD` with `SD2`, can I then include and use `SD2` just like the original (provided the different `.begin(pin)`)? Is there a less hacky way of using two SD cards in ESP8266 Arduino?

In case anyone's wondering, it's for a crypto project where one card will contain one-time-pads of plaintext length and the other contains the XOR'd ciphertext, both are fed by wifi upload, and the max file size must be bigger than SPIFFS, so I really need two SD cards...

title: Two SD card interfaces on one ESP8266?

Answers: 2

body:
You should (I have not tested it) be able to do it if the library is well coded and doesn't use global variables and you do something like this:

    // Don't know what the class name is so replace TYPE with what it should be.
    TYPE SDCardOne;
    TYPE SDCardTwo;

    SDCardOne.begin(CS1);
    SDCardTwo.begin(CS2);
    ....

body:
Not possible without changing the library code. Because the current library code is written intended for only one SD card, ie not intended for multiple SD cards because it will be complicated to do so. The SPI library also uses FatFS library, which is a bottleneck in this scenario.

**Worth a try.**

 [sdfatlib][1] is library written for Arduino. I have never used it, but you can give a try on ESP.

Let us know if it works.

  [1]: https://github.com/jbeynon/sdfatlib


body: Is there any way I can control the position of servo by changing the value of potentiometer for using it for 360 deg motion?

title: 360 degree motion of servo with position control

Answers: 1

body:
A pot doesn't spin all the way around, so you could map hi/lo values, but you can't run more than one lap with it.  You could add a button that silences the pot input, so that you can hold the button and dial back the pot, releasing the button to continue turning the servo with the pot. In that case, you use relative values between samples to turn the servo instead of simply feeding it the ADC value.

A rotary encoder is probably a better fit though, since it can spin 360 just like the servo. You would still want to "gear down" the encoder if you're micro-stepping, so that say, 4 turns of the encoder yields 1 turn of the servo. This allows full 360 and as much arbitrary precision as your project needs.


body:
I recently bought a Wemos D1 board and tried to connect a relay and test its connection.

I got an [example server][1] from here and executed. I connected D5 to a Relay's data and 5v and GND from Wemos board.

But this does not change the state of relay, it always remains high. I connected a LED for D5, it works perfectly with client's response.

Then I powered relay using an external 5v and ground connection, but the same result.

I have checked for possible solution, but coulnt find an answer.

The relay I am using is [this one][2]

  [1]: http://www.esp8266learning.com/wemos-webserver-example.php
  [2]: https://www.amazon.com/Songle-Household-Appliance-Relay-SRD-05VDC-SL-C/dp/B00O9WPAJ6

title: Wemos D1 doesnt drive Relay

Answers: 1

body:
The board which you are using is operating on 3v3. Even if you try to run the relay using the D5 or any other pin on the board, you may not be able to run it successfully at all times. In this case, you can go for either MOSFETs or Pull-up resistors so that you can hold the voltage to 5V for triggering the relay. I would personally suggest to go for a PNP type.

As requested by Sachith, here is the circuit suggested for the problem stated. Just note that the voltage source should be `+5 V` (which is `+1 V` in the schematic). Also, the MOSFET is not the specific one, it is just for the schematic purpose.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/Z1U1v.png)

<!-- End schematic -->


body:
I have 3 components: a relay and two LEDs...I want two timers using Arduino... In timer one, relay should be <strike>off</strike> on; one LED is off; and other is on...In second timer, relay is off; one led is on; other is off...
This is my Code:

    //const unsigned long onTime = (2 *3600000); // 2 Hours in miliseconds;
    const unsigned long onTime = (3 *1000); // 3 seconds;
    //const unsigned long onTime = (5 *60000); // 15 minutes;

    //const unsigned long offTime = (0.5 *3600000); // 1/2 Hours in miliseconds;
    const unsigned long offTime = (2 *1000); // 1 seconds;
    //const unsigned long offTime = (5 *60000); // 5 minutes;

    const unsigned long start_delay = (5 *60000);  // 5 minute in miliseconds

    // Tracks the last time event fired
    unsigned long previousMillis=0;

    // Interval is how long we wait
    int interval = onTime;

    // Used to track if relay should be on or off
    boolean relayState = true;

    void setup()
    {
      pinMode(13, OUTPUT); //Relay
      pinMode(3, OUTPUT); //LED Green for ON
      pinMode(4, OUTPUT); //LED Red for OFF

      digitalWrite(13, LOW);   // Relay Off
      digitalWrite(3, LOW);    // Green LED off
      digitalWrite(4, LOW);    // Red LED OFF

      //delay (start_delay);  // wait for 5 minute
    }
    void loop()
    {
      if (relayState == true)
      {
        // Relay ON
        digitalWrite(13, HIGH);   // Relay ON
        digitalWrite(3, HIGH);    // Green LED ON
        digitalWrite(4, LOW);    // Red LED OFF
      }
      if (relayState == false)
      {
        // Relay OFF
        digitalWrite(13, LOW);   // Relay Off
        digitalWrite(3, LOW);    // Green LED Off
        digitalWrite(4, HIGH);    // Red LED On
      }

      // Grab snapshot of current time, this keeps all timing
      long currentMillis = millis();

      // Compare to previous capture to see if enough time has passed
      if ((unsigned long)(currentMillis - previousMillis) >= interval)
      {
        // Change wait interval, based on current relay state
        if (relayState)
        {
          // Relay is currently on, set time to stay off
          interval = offTime;
        }
        else
        {
          // Relay is currently off, set time to stay on
          interval = onTime;
        }
        // Toggle the relay's state
        relayState = !(relayState);
        // Save the current time to compare "later"
        previousMillis = currentMillis;
      }
    }

Now issue is; when I make timer for seconds like OnTime is 3 second and offTime is 1 second... It works perfect... But timer for hours or minutes does not simply works... it does not switch state from on to off... It constantly remains on... What could be  the problem... Thanks!

title: Issue in long ON OFF timer using millis()

Answers: 2

body:
You declare interval as an integer, while onTime and offTime are `unsigned long`.

Change `int interval = onTime;` to `unsigned long interval = onTime;`

The maximum value of `int` is only 32767 (215-1), which is only 33 seconds.

An `unsigned long` can be as high as 4294967296 (232-1). Which is around 49.7 days worth of milliseconds.

body:
You should not depend on millis() function for long time delays, use an extra rtc chip(DS3231/DS1307) instead.

Theoretically millis() function should produce 1 millisecond time frame, but it is not exactly that. There will always be a difference; and if you multiply that small time difference with a big number, then there will be a significant delay.


body:
I plug in BT rx to digital 11, BT tx to digital 10 and then 5v and ground from the HC-05 to the arduino. I then upload this code to the HC-05 that is set as a master.

    #include <SoftwareSerial.h>

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

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

    void loop() { // run over and over
      Serial.println(mySerial.read());
      delay(2000);
    }
I then upload this code to the arduino with the HC-05 that is set as a slave:

    #include <SoftwareSerial.h>
    SoftwareSerial mySerial(10,11); // RX , TX

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

    void loop() {
      // put your main code here, to run repeatedly:
      mySerial.write("100");
      delay(2000);
    }

The issue is that I never receive "100" on the serial monitor, I only ever receive 49 and occasionally 48. When I changed it from "100" to "10" same thing happened. Any help would be appreciated.

title: Bluetooth Modules not communicating correctly

Answers: 3

body:
SoftwareSerial.read() returns a single character as an integer. When you print an integer the print() functions convert it to a human readable format.

You want to covert (cast) the output of read() to the char type. Either:

    void loop() {
      char c;
      c = mySerial.read(); // store the result in a temporary variable c
      Serial.println(c);
      delay(2000);
    }

or

    void loop() {
      Serial.println((char)mySerial.read()); // cast the type to char befor printing.
      delay(2000);
    }

However since only one character at a time is being read your output will be one character per line (assuming no data loss due to the delay):

    1
    0
    0

body: You should change the TX and the RX pins on the arduino board and pin it on to another pin other than the TXD and RXD as the are hardware pins....

body:
"You are getting 49 and 48 occasionally"?

I would expect you to get 49, 48, 48, 49, 48, 48 ...

49 is '1' in ASCII and guess what 48 means :)

This is because you are writing and reading bytes not characters.  There is a very subtle difference.

change you receiver to this and it should make more sense.

    void loop() { // run over and over
      const char letter = (char)mySerial.read(); // Turn the byte into an ASCII letter.
      Serial.println(letter);
      delay(2000);
    }

It may all still go wrong, if you read <32 or >126 but ...

Here is an ASCII table to help:
[ASCII Table][1]

  [1]: https://www.google.co.uk/imgres?imgurl=https://www.asciitable.com/index/asciifull.gif&imgrefurl=https://www.asciitable.com/&h=488&w=715&tbnid=2U31hF4tTw886M:&q=ASCII code&tbnh=143&tbnw=210&usg=__pUA7Ouijp0hts6S2oWHVbyWFJfw=&vet=10ahUKEwiHy8zesJ7bAhWrKsAKHXFqDEgQ9QEIKzAA..i&docid=OSBfy-TcJL-niM&sa=X&ved=0ahUKEwiHy8zesJ7bAhWrKsAKHXFqDEgQ9QEIKzAA  ASCII Table


body:
I have a soil sensor that reports value once every 5 minutes, deepsleep in between.
Is there a way to also report battery voltage (with ESP.getVcc())?

To get the battery voltage reading to work I need to set ADC_MODE(ADC_VCC); but that disables the reading of the sensor.

title: Read both battery voltage and analog sensor value with NodeMCU ESP8266

Answers: 2

body:
> to read VCC voltage, ADC pin must be kept unconnected. Additionally, the following line has to be added to the sketch:
ADC_MODE(ADC_VCC);

The setting of a purpose of the analog pin of esp8266 is at low level and must be projected into the compiled binary. It can't be changed at runtime.

On esp8266 if you want to use the power sensing or to have more ADC you must use an external I2C ADC.

[reference][1]

  [1]: http://esp8266.github.io/Arduino/versions/2.0.0/doc/reference.html#analog-input

body:
I found a solution that I believe works great.

Although the ADC_MODE macro cannot be modified after the board is started, we can actually set its integer input as the output of a function and then use RTC memory to trigger different modes, depending for example on how many times the board has been started.

    #include "ESP8266WiFi.h"
    #define QUERY_VCC_INTERVAL  10

    int adc_selection;
    ADC_MODE(get_adc());

    int get_adc(){

      typedef struct {
      uint32_t adc_mode;
      uint32_t count;
      } rtcStore;

      rtcStore rtcMem;

      system_rtc_mem_read(100, &rtcMem, sizeof(rtcMem));

      if ((rtcMem.adc_mode != ADC_VCC) && (rtcMem.adc_mode != ADC_TOUT)) return ADC_TOUT;

      return rtcMem.adc_mode;
    }

    int get_adc_and_write_change(){

      typedef struct {
      uint32_t adc_mode;
      uint32_t count;
      } rtcStore;

      int a;
      rtcStore rtcMem;

      system_rtc_mem_read(100, &rtcMem, sizeof(rtcMem));
      a = rtcMem.adc_mode;

      Serial.print("CYCLE NUMBER: ");
      Serial.println(rtcMem.count);

      if (rtcMem.count > QUERY_VCC_INTERVAL){
            rtcMem.adc_mode = ADC_VCC;
            rtcMem.count = 0;
      } else {
            rtcMem.adc_mode = ADC_TOUT;
            rtcMem.count++;
      }

      system_rtc_mem_write(100, &rtcMem, sizeof(rtcMem));

      return a;

    }

    void setup() {

      int vcc;

      Serial.begin(9600);
      Serial.println(" ---------- ");
      delay(1000);

      adc_selection = get_adc_and_write_change();
      Serial.print("VALUE FOR ADC MODE WAS: ");
      Serial.println(adc_selection);

      vcc = ESP.getVcc();
      Serial.print("VALUE WHEN READING VCC: ");
      Serial.println(vcc);

      if (adc_selection == ADC_TOUT){
        Serial.println("VCC SHOULD BE 65535");
       } else {
        Serial.println("VCC SHOULD NOT BE 65535");
       }

      Serial.println("RESET BOARD TO CONTINUE");
      delay(1000);

    }

    void loop() {
    }

Note that the function gets executed very early on the board startup, so we cannot even count on using or writing to global variable definitions of the script's code. This is why all structures are defined within the get_adc function.

The above code triggers ADC_MODE(ADC_VCC) for every 10 times that ADC_MODE(ADC_TOUT) is triggered. This allows me to read analogue sensors for 10 times after the board is woken up from deep sleep and then read the VCC level to gauge the battery voltage once every 10 times.

Note also that to have VCC readings work correctly I need to connect analogue sensor power to a digital pin and use that to power the sensors ON/OFF as needed.

I have tested the above code with a NodeMCU v3, on the Arduino IDE.


body:
I need some help with a project I am doing involving the DS1307 RTC. I am trying to make what is essentially a way to mins quickly check the time which involves nine LEDs slowly lighting up every 10 so that I can quickly check time but looking at it. :[![Here is a rough 3D model of the housing of the arduino][1]][1] So far I've tried TimeAlarms but I can't figure out how to do this. I have a Arduino Uno by the way.

Can someone possibly help?

  [1]: https://i.stack.imgur.com/3mxT6.png

title: Need help with an Arduino project using a RTC and LEDs

Answers: 1

body: Use the SQW pin on the DS3231 or DS1307 to create 1sec pulse, read it on your Arduino. There are very good libraries are available (like RTClib from adafruit).


body:
I am using Maniacbug Mighyty-1284p 16MHz in my project.
Here I used watchdog for safety.I used three command for watchdog.

    1. wdt_enable(WDTO_8S);
    2. wdt_reset();
    3. wdt_disable();

Is it create any problem if I use "wdt_enable(WDTO_8S);" command two times (one after another without using wdt_disable();)

title: Watchdog problem

Answers: 0


body:
I am using DC energy meter as slave.When I am testing DC energy meter using Modbus tester tool,its showing value from 1 to 24 register.I am using my own atmega328P with on board RS485 as a master device.I have connected A,B from slave to mater board.Now,I want to read slave outputs using my master.For that I have written below mentioned code.when I am serially printing array,its showing 00000000000000000000000000000000769.I am not getting full data on my master.

    #include <ModbusRtu.h>

    // data array for modbus network sharing
    uint16_t au16data[64];
    uint8_t u8state;

    int i;

    /**
     *  Modbus object declaration
     *  u8id : node id = 0 for master, = 1..247 for slave
     *  u8serno : serial port (use 0 for Serial)
     *  u8txenpin : 0 for RS-232 and USB-FTDI
     *               or any pin number > 1 for RS-485
     */
    Modbus master(0,0,1); // this is master and RS-232 or USB-FTDI

    /**
     * This is an structe which contains a query to an slave device
     */
    modbus_t telegram;

    unsigned long u32wait;

    void setup() {
      master.begin( 9600 ); // baud-rate at 19200
      master.setTimeOut( 2000 ); // if there is no answer in 2000 ms, roll over
      u32wait = millis() + 1000;
      u8state = 0;
    }

    void loop() {
      switch( u8state ) {
      case 0:
        if (millis() > u32wait) u8state++; // wait state
        break;
      case 1:
        telegram.u8id = 1; // slave address
        telegram.u8fct = 3; // function code (this one is registers read)
        telegram.u16RegAdd = 1; // start address in slave
        telegram.u16CoilsNo = 24; // number of elements (coils or registers) to read
        telegram.au16reg = au16data; // pointer to a memory array in the Arduino

        master.query( telegram ); // send query (only once)
        u8state++;
        break;
      case 2:
        master.poll(); // check incoming messages
        if (master.getState() == COM_IDLE) {
          u8state = 0;
          u32wait = millis() + 100;
        }
        break;
      }
     //au16data[4] = analogRead( 0 );

     for(i=0;i<=64;i++)
     {
      Serial.print(au16data[i]);
     }
     Serial.println("\n");
     Serial.println("\n");
     delay(1000);
     }

title: Arduino Modbus Master code to read data using arduino uno from EB meter

Answers: 1

body: The response is received when ModbusRtu library object is again in the `IDLE` state after a request was sent. In your code based on the example from the library, the response is ready in state `2` which follows state `1` where the request was sent. If in state `2` when the `master` object state changes to IDLE, you can use the response in array `au16data`.


body:
I have been working on a prototype for a wifi based universal remote controller and i have been using the IR-Remote library for the same. But i have a couple of questions which google couldn't help with.

So, the problem is that there are some remotes like hitachi or some other brands that aren't recognised by the library and the coding type shows "UNKNOWN". The raw dump shows an array of 211 integers like such:

    Timestamp : 012012.059
    Encoding  : UNKNOWN
    Code      : 794B7E67 (106 bits)
    Library   : v2.4.0

    Raw Timing[211]:
       +  3424, -  3352,    +   378, -  1336,    +   376, -   454,    +   458, -  1254,
       +   378, -  1334,    +   378, -   454,    +   460, -   352,    +   396, -  1336,
       +   460, -   356,    +   394, -  1334,    +   458, -   364,    +   466, -  1256,
       +   458, -   356,    +   392, -  1336,    +   458, -  1258,    +   456, -  1254,
       +   378, -   452,    +   460, -   360,    +   470, -  1256,    +   458, -   298,
       +   532, -   366,    +   466, -  1256,    +   458, -  1256,    +   458, -   358,
       +   472, -  1256,    +   458, -  1254,    +   458, -   358,    +   472, -   304,
       +   526, -  1258,    +   456, -   298,    +   532, -   362,    +   466, -   368,
       +   464, -  1256,    +   456, -  1258,    +   456, -  1258,    +   456, -  1256,
       +   378, -  1336,    +   458, -   360,    +   470, -   304,    +   524, -   364,
       +   466, -   364,    +   464, -   310,    +   522, -  1232,    +   482, -  1256,
       +   456, -   304,    +   526, -   310,    +   520, -   306,    +   524, -   370,
       +   462, -  1256,    +   456, -  1260,    +   454, -  1232,    +   480, -   306,
       +   524, -   366,    +   464, -   312,    +   516, -  1236,    +   478, -   368,
       +   462, -   368,    +   462, -   368,    +   386, -   454,    +   454, -   372,
       +   456, -   374,    +   458, -   372,    +   460, -   306,    +   524, -   372,
       +   458, -   370,    +   460, -   308,    +   520, -   312,    +   444, -   452,
       +   376, -   454,    +   452, -   308,    +   524, -   368,    +   462, -   372,
       +   458, -   306,    +   522, -   374,    +   458, -   368,    +   460, -   306,
       +   524, -   374,    +   458, -   308,    +   522, -   372,    +   460, -   370,
       +   458, -   374,    +   460, -   364,    +   464, -   370,    +   460, -   304,
       +   450, -   454,    +   452, -   308,    +   522, -   370,    +   460, -   368,
       +   386, -   452,    +   452, -   374,    +   456, -   312,    +   520, -  1260,
       +   452, -  1262,    +   452, -   376,    +   456, -   372,    +   458, -   376,
       +   454, -   378,    +   380, -  1334,    +   452, -  1260,    +   452, -  1264,
       +   378, -  1336,    +   378, -  1310,    +   476, -   320,    +   438, -   452,
       +   378, -   428,    +   402

    uint16_t rawData[211] = {3424, 3352,  378, 1336,  376, 454,  458, 1254,  378, 1334,  378, 454,  460, 352,  396, 1336,  460, 356,  394, 1334,  458, 364,  466, 1256,  458, 356,  392, 1336,  458, 1258,  456, 1254,  378, 452,  460, 360,  470, 1256,  458, 298,  532, 366,  466, 1256,  458, 1256,  458, 358,  472, 1256,  458, 1254,  458, 358,  472, 304,  526, 1258,  456, 298,  532, 362,  466, 368,  464, 1256,  456, 1258,  456, 1258,  456, 1256,  378, 1336,  458, 360,  470, 304,  524, 364,  466, 364,  464, 310,  522, 1232,  482, 1256,  456, 304,  526, 310,  520, 306,  524, 370,  462, 1256,  456, 1260,  454, 1232,  480, 306,  524, 366,  464, 312,  516, 1236,  478, 368,  462, 368,  462, 368,  386, 454,  454, 372,  456, 374,  458, 372,  460, 306,  524, 372,  458, 370,  460, 308,  520, 312,  444, 452,  376, 454,  452, 308,  524, 368,  462, 372,  458, 306,  522, 374,  458, 368,  460, 306,  524, 374,  458, 308,  522, 372,  460, 370,  458, 374,  460, 364,  464, 370,  460, 304,  450, 454,  452, 308,  522, 370,  460, 368,  386, 452,  452, 374,  456, 312,  520, 1260,  452, 1262,  452, 376,  456, 372,  458, 376,  454, 378,  380, 1334,  452, 1260,  452, 1264,  378, 1336,  378, 1310,  476, 320,  438, 452,  378, 428,  402};  // UNKNOWN 794B7E67

Now for such AC remotes which are unknown, which are more common than i thought would be, it is a matter of best implementation. I know I can save these arrays in variables and send them using `.sendRaw(array, sizeof(array, freq)` but then I will have to store about 15 such arrays for multiple brands. Even if I save ir codes for five different protocols, i'll be making a table of 5 * 15 = 75 huge arrays. i don't think that is a good practice nor the ESP8266 will be able to store all that.

What can be the best way to do this? What am I missing? Is there a better way to do this?

title: ESP8266 based wifi IR Universal Remote for A/Cs

Answers: 0


body:
When I connected my atmel ice to my arduino uno everything went okay.
Then I tried debugWIRE and since then I can't connect to my ATMEGA328p.
I get the error
`Failed to enter programming mode. ispEnterProgMode: Error status received: Got 0xc0, expected 0x00 (Command has failed to execute on the tool)`
I think one of the fuse bits is wrong but can't connect to the ATMEGA328p to change them. Does anyone have a idea what to do?

title: Program an Arduino Uno with an Atmel ICE

Answers: 1

body:
Your Ardunino is stuck in debugWIRE (The debug wire fuse is set). Here is a [tutorial][1] on how to get it back to programming mode.

In the tutorial I am using the AVR Dragon with AS6, but the process is the same with Atmel ICE and AS7.

You have to be in Debug Mode to disable debugWIRE. While in debug, Click Debug>Disable Debug Wire and Close.

  [1]: https://www.youtube.com/watch?v=xJKoc_TI2sw


body:
    int angleServo1,angleServo2 = 0;
    const int axisX=A0; // ось Х подключена к A0
    const int axisY=A1; // ось Y подключена к A1
    int valX, valY = 0; // переменные для хранения значений осей
    int datos[3];
    #include <SPI.h>

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

    void loop()
     {
          valX = analogRead(axisX); // значение оси Х
          valY = analogRead(axisY); // значение оси Y
          // масштабируем значение к интервалу 0-180
          angleServo1=map(valX,0,800,100,-100);
          angleServo2=map(valY,0,810,100,-100);

           datos[0] = angleServo1;
           datos[1] = angleServo2;
           Serial.write(datos, sizeof(datos));
           delay(100);
    }

  error: no matching function for call to 'HardwareSerial::write(int [3], unsigned int)'

how to remove an error and pass an array of bytes?

title: Serial.write(buf, len) error. How to remove an error and pass an array of bytes?

Answers: 1

body:
You want to send data to computer processing or print them for user to read? Functions `write` send raw data. To print the data to Serial monitor `print` and `println` functions are used.

There are two `write` functions. First sends one byte. Second sends array of bytes. There is no write function to send array of ints. You could cast the array of ints to array of bytes to send the array as raw bytes for processing on the receiving side. But then you first should perhaps send to the receiving side some control data about the data package.

      Serial.write((byte*) datos, sizeof(datos));

If you want to print numbers to Serial Monitor, the `print` functions have variants which take a number and convert it to string. But there is no `print` function to print an array of numbers. You must print them one by one in a for loop. And put some separator between them (coma, space, new line).


body:
I'm trying to read 4 **DS18B20 sensor probes** (https://amazon.com/gp/product/B00Q9YBIJI and https://amazon.com/gp/product/B008HODWBU) with a **"Wemos" LOLIN32 ESP-32 board** (https://amazon.com/gp/product/B072HBW53G).

Wiring:

* The probes' Vcc wires are connected to the ESP32 board's "3.3" pin

* the probes' ground wires are connected to one of the ESP32 board's "Gnd" pins

* the probes' data wires are connected together at the end of their furnished meter-long cable, and the wire carrying the combined data is connected to GPIO 16 on the ESP32 board.

* Additionally, there's a 4.7k resistor between GPIO16 and the 3.3v pin on the Lolin32 board to pull the 1-wire bus high.

I'm using the stock Arduino <OneWire.h> and <DallasTemperature.h> libraries.

**Sometimes, the sensors work. Often, they don't.**

Possibly noteworthy is the fact that I purchased 1 probe a few years ago, and a 3-pack of probes this week. Probes from the 3-pack ONLY work if the probe I purchased earlier is ALSO connected. Put another way...

Original probe connected: sometimes works, sometimes doesn't.

1-3 of new probes connected: never works.

1-3 of new probes connected along with original probe: sometimes works, sometimes doesn't.

Wiring should theoretically be a total non-issue... I'm using only the original ~meter-long wires, with short (~3-4") AWG20 solid hookup wire soldered to the end and connected through a breadboard.

If I unplug the wires connected to the ESP32 board's GPIO16, 3.3, and Gnd pins and connect them instead to an old Arduino Uno's D2, 5v, and Gnd pins (and change the port in the code), all tested permutations of the sensors work perfectly and reliably.

**Any ideas for troubleshooting this?**

At the moment, these are my top theories:

* GPIO16 is unsuitable for some unknown reason.

* There's at least one software bug somewhere between the ESP32's low-level firmware, the firmware that enables an ESP32 to act like it's an Arduino, the two Arduino libraries themselves, or some combination of them all. Knowing that something like this is almost certainly the problem would at least spare me from going in circles for the next few days trying to solve a problem that can't be solved.

* The 3 new sensors really don't like 3.3v, but the older one semi-tolerates 3.3v (theory fails to explain why adding a fourth sensor -- the original one -- would occasionally enable the 3 new ones to work)

* The ESP32 board can't supply enough current from the 3.3v pin to properly power the sensors (flaws in theory: if it were purely lack of current capacity, adding the fourth sensor on top of the first 3 should make matters worse, not better. And in any case, the DS18B20 sensors don't use much power, and almost by definition MUST be able to work with unstable & intermittent power for parasitic powering to be capable of working. Just to emphasize, I am NOT using parasitic power, though).

I considered trying to feed the sensors 5v, but I'm not entirely sure how to deal with the level translation between their data bus and the ESP32 board.

* I know Espressif has officially stated that the ESP8266 has 5v-tolerant i/o

*  I could swear I also read somewhere that the ESP32 is unambiguously NOT 5v-tolerant.

* I have a hunch that level-shifting Dallas 1-wire is more complicated than it seems, and that there's probably at least one "gotcha" lurking that will cause problems if I try blindly using something like a TXB0104 or MAX3378 between the sensors' data wire and the ESP32 board.

Here's the relevant code (when it works, it works for the original sensor or the original sensor + one or more of the new sensors... when it doesn't work, it fails to detect any sensors & just outputs "Temp:   " to Serial when running in loop().

    #include <OneWire.h>
    #include <DallasTemperature.h>

    #define ONE_WIRE_BUS 16
    #define TEMPERATURE_PRECISION 12

    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature dallasTempSensor(&oneWire);
    int totalOneWireDevices = 0;
    DeviceAddress tempDeviceAddress;

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

     dallasTempSensor.begin();
     totalOneWireDevices = dallasTempSensor.getDeviceCount();
     Serial.print("Locating devices...");
     Serial.print(totalOneWireDevices, DEC);
     Serial.println(" devices.");

     Serial.print("Parasite power is: ");
     if (dallasTempSensor.isParasitePowerMode())
      Serial.println("ON");
     else
      Serial.println("off");

     for (int x=0; x<totalOneWireDevices; x++) {
      if (dallasTempSensor.getAddress(tempDeviceAddress, x)) {
       Serial.print("Found device ");
       Serial.print(x, DEC);
       Serial.print(" with address: ");
       printAddress(tempDeviceAddress);
       Serial.println();
       Serial.print("Setting resolution to ");
       Serial.println(TEMPERATURE_PRECISION, DEC);
       Serial.print("Resolution actually set to: ");
       Serial.print(dallasTempSensor.getResolution(tempDeviceAddress), DEC);
       Serial.println();
      }
      else {
       Serial.print("Found ghost device at ");
       Serial.print(x, DEC);
       Serial.print(" but could not detect address. Check power and cabling.");
      }
     }
    }

    // function to print the temperature for a device

    void printTemperature(DeviceAddress deviceAddress)

    {
      float tempC = dallasTempSensor.getTempC(deviceAddress);
      //Serial.print("Temp C: ");
      //Serial.println(tempC);
      //Serial.print("Temp F: ");
      //Serial.print("    ");
      Serial.print(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
    }

    void loop() {
      // put your main code here, to run repeatedly
     //Serial.print("Requesting temperatures...");
     dallasTempSensor.requestTemperatures();
     //Serial.println("DONE");
     Serial.print("Temp:   ");
     for (int x=0; x < totalOneWireDevices; x++) {
      if (dallasTempSensor.getAddress(tempDeviceAddress, x)) {
       //Serial.print("Temperature for device: ");
       //Serial.println(x, DEC);

       printAddress(tempDeviceAddress);
       Serial.print(" = ");
       printTemperature(tempDeviceAddress);
       Serial.print("    ");
      }
     }
     Serial.println("");
     delay(5000);
    }

    void printAddress(DeviceAddress deviceAddress) {
     for (uint8_t x=6; x < 8; x++) {
      if (deviceAddress[x] < 16)
       Serial.print("0");
      Serial.print(deviceAddress[x], HEX);
     }
    }

title: DS18B20 flaky with LOLIN32 ESP32 board, rock-solid with Uno

Answers: 0