body:
In the process of learning and working on a larger project, I started by adding an `OLED` display (128x64, `SPI`). I wrote a simple script to update every 5 seconds and then display the number of seconds on both the `OLED` and the Serial port. This worked just fine and I even let it run for more than a day. Then I added a `DHT22`. This is where the issues started coming in. The `Arduino` `Mega` (clone) is powering both devices. I have a 10K resistor across the VCC and signal pins of the `DHT22`. The code should now update both the `OLED` and the serial port with the number of seconds and the temperature and humidity. This works, for awhile, and then the whole program freezes for some odd reason. The time before freezing is also at random intervals.

During my research it was suggested to add a 10uF capacitor across the ground and VCC. So I added a 10uF 50v cap and the results are still the same. Originally I had Serial.println(String(..... in the code, but I replaced all that to not use String(). I tried adding Serial.flush() at the end of the display code, but equal results.

Additional research also suggested waiting 30 seconds before trying to read the DHT22. I added this 30 second wait at the end of the setup function, but same results. I've tried checking for NaN, not checking for NaN and nothing has seemed to correct this issue.

I've also tried the program without the OLED. Same results. I've tried the program without the Serial output, but same results.

What is going on here and does anyone have any suggestions as to how to correct this?

Currently this whole thing is rigged up on a breadboard if that helps.

Below is the current code I'm trying:

    #include <Arduino.h>

    #include <SPI.h>
    #include <Wire.h>

    #include "DHT.h"

    #define DHTPIN 2
    #define DHTTYPE DHT22
    DHT dht(DHTPIN, DHTTYPE);

    // Adafruit Libraries for the OLED display
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>

    // Setup the OLED variables
    #define OLED_MOSI   9 // D1 on the OLED
    #define OLED_CLK   10 // D0 on the OLED
    #define OLED_DC    11 // DC on the OLED
    #define OLED_CS    12 // CS on the OLED
    #define OLED_RESET 13 // RES on the OLED
    Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

    // Global variables
    unsigned long currentMillis;
    long previousMillis = 0;
    #define interval 5000

    float humidity;
    float fahrenheit;

    void setup(){
      // Start the serial port transmission
      Serial.begin(9600);

      // Start the OLED
      display.begin(SSD1306_SWITCHCAPVCC);

      dht.begin();

      // Clear the memory of the OLED
      display.clearDisplay();

      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(1,0);
      display.println("Madgayrah");
      display.display();

      while(millis()<2000);

      display.setCursor(0,16);
      display.println("Arduino");
      display.display();

      while(millis()<5000);
    //  while(millis()<30000);

      Serial.println("");
      display.clearDisplay();
    }

    void loop() {
      currentMillis = millis();

      if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;
        poll_and_display(currentMillis);
      }
    }

    void poll_and_display(long currentMillis){
        read_dht22();

        Serial.println(previousMillis/1000);

        if(!isnan(humidity) && !isnan(fahrenheit)){
          Serial.print(fahrenheit, 1);
          Serial.print("* ");
          Serial.print(humidity, 0);
          Serial.println("%");
        }

        display.clearDisplay();

        display.setCursor(0,0);
        display.println(currentMillis/1000);
        if(!isnan(humidity) && !isnan(fahrenheit)){
          display.setCursor(0,16);
          display.print(fahrenheit, 1);
          display.print("* ");
          display.print(humidity, 0);
          display.print("%");
        }
        display.display();

        Serial.println("");

        Serial.flush();
    }

    void read_dht22(){
        humidity = dht.readHumidity();
        fahrenheit = dht.readTemperature(true);

    //    while (isnan(humidity) || isnan(fahrenheit)) {
    //      unsigned long tempEnteredMillis = millis();
    //      while (millis() - tempEnteredMillis < 2500);
    //
    //      humidity = dht.readHumidity();
    //      fahrenheit = dht.readTemperature(true);
    //
    //      Serial.print("Result from NaN loop = ");
    //      Serial.print(fahrenheit, 1);
    //      Serial.print("* ");
    //      Serial.print(humidity, 0);
    //      Serial.println("%");
    //    }
    }

**UPDATE:**
After continuing to research on this I discovered that `Arduino` has a Watchdog Timer, or at least SHOULD have, and this SHOULD detect hang ups and restart the `Arduino`. So I tried a hardware version of the Watchdog Timer and a software version, but neither one seemed to work and/or correct the hang up/freeze issue. Below are the links I used for the software and hardware versions.

[https://circuits4you.com/2018/01/24/tutorial-on-arduino-watchdog-timer-setup/][1]

[https://blog.frogslayer.com/creating-an-arduino-watchdog-timer/][2]

  [1]: https://circuits4you.com/2018/01/24/tutorial-on-arduino-watchdog-timer-setup/
  [2]: https://blog.frogslayer.com/creating-an-arduino-watchdog-timer/

I then ran across another post about a different solution that I have implemented and it seems to be working, but I want to give it some more time just to be sure. More updates to come.

title: DHT22 Hanging Up Entire Program

Answers: 1

body:
Here is the solution. After searching last night I ran across this post [https://forum.arduino.cc/index.php?topic=517608.new][1] . Turns out, I was using the `Adafruit` DHT library and that seems to be what the issue was. I switched over to this [https://github.com/markruys/arduino-DHT][2] DHT library and it's been running for some 14 hours now with NO issues. Looking back through the Serial output I don't even see where it returned a NaN, not even once. I'm so excited to have this corrected and hopefully this will help out someone else stuck with this problem.

  [1]: https://forum.arduino.cc/index.php?topic=517608.new
  [2]: https://github.com/markruys/arduino-DHT


body:
I'm writing a sketch which does some calculations on measured variables, and it's based on a similar program written in Java like
c = A.Ux + B.Uz;
Where A&B have various parameters Ux,Uy,Uz etc
In Delphi this notation can be used either for parameters of classes or variables in a group. Looks like there's something similar in Java. It's a tidy way to organise and manipulate variables when there are lots of them and move them between methods without having huge numbers of arguments.

Is there any way to do this in the Arduino Wiring language? I don't seem to find anything online, but I'm probably phrasing the question wrong.
Thanks in advance, Brian

title: Is there any way to group variables like group.variable as you can in Java/Delphi

Answers: 1

body:
What you are looking for is a `struct`:

    struct foo {
        uint8_t Ux;
        uint8_t Uy;
        uint8_t Yz;
    };

Then:

    struct foo A;
    struct foo B;

And:

    A.Ux = 3;
    B.Uz = 48;

    int c = A.Ux + B.Uz;

When calling a function you should really use either pass-as-pointer or pass-as-reference to avoid unnecessary copying:

    // By Reference
    int normal(struct foo &arg) {
        return (arg.Ux + arg.Uy + arg.Uz) / 3;
    }

    int avg = normal(A);

Or:

    // By pointer
    int normal(struct foo *arg) {
        return (arg->Ux + arg->Uy + arg->Uz) / 3;
    }

    int avg = normal(&A);

You can read more about structs [here](https://www.tutorialspoint.com/cprogramming/c_structures.htm).


body:
After I take a char* variable from serial communication, I use `strtok` to split variables with " ". But when I do that it acts like there is a " " after every character. I dont know why. How can I fix this ?

    void setup() {
      Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
      char* a = "The quick brown fox jumped over the lazy dog.";
      char* c = a3;
      char* b;
      b = strtok(c, " ");
      while (b != NULL) {
        Serial.println(b);
        b = strtok(NULL, " ");
      }
    }

    void loop() {
    }

outcome:

    The
    quick
    brown
    ...

This parsing code works perfectly, until I take it from serial ports. Serial code here, like this:

    #include <SoftwareSerial.h>
    #define bRSerial 9600
    #define bRmY 9600

    char vD[45];
    int i = 0;

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

    void setup() {
      Serial.begin(bRSerial);
      while (!Serial) {
        ;
      }
      mySerial.begin(bRmY);
    }

    void loop() {
      if (mySerial.available()) {
        //Serial.write(mySerial.read());
        vD[i]=mySerial.read();
        i++;
        if (i = 46) {
          char* a = vD;
          char* b;

          b = strtok(a, " ");
          while (b != NULL) {
            Serial.println(b);
            b = strtok(NULL, " ");
          }
          i=0;
        }
      }
    }

outcome:

    T
    h
    e
    q
    u
    i
    c
    k
    b
    r
    o
    w
    ...

Is there a way to fix this? i need to get it from serial and split on " ".

title: strtok() command with Serial communicaton

Answers: 2

body:
only a syntax typo. the condition should be `if ( i == 46 ) {`

if this is not only a strtok test, the you do not need strtok. read in char c, and if `c == ' '`, print vD and reset i to 0

and I do not see where you set the terminating 0 of `vD` a.k.a. `a`

body:
As @Juraz mentioned, in the case you have a typo. Also I'd have suggestions as one who had spent a while coding reading process in terminal. When you need to read something from a serial port it is good to use the `while()` loop, instead of `if()`, so I recommend changing:

    while (mySerial.available()) {
      //Serial.write(mySerial.read());
      vD[i]=mySerial.read();
      i++;
      if (i == 46) {
        char* a = vD;
        char* b;

        b = strtok(a, " ");
        while(b != NULL) {
          Serial.println(b);
          b = strtok(NULL, " ");
        }
        i=0;
      }
    }


body:
new to this StackExchange site. I have an experimental setup with three inputs - two from a laser distance sensor to measure planar distance and one digital input from a set of callipers.

All sensors readings fluctuate over a small range (which is acceptable for my use case). Is it possible to have the Arduino record all inputs for a given period of time and output only the mean value for each sensor?

title: Return mean of observations for a given sample time

Answers: 1

body:
I have this:

    int readElSens() {
      long sum = 0;
      int n = 0;
      long start_time = millis();
      while(millis() - start_time < 400) {
        sum += analogRead(ELSENS_PIN);
        n++;
      }
      return sum / n;
    }


body:
I recently used the Ardunio board and powered with the AVR pocket programmer along with the AVR ISP cable and it worked just fine and no issues were experienced. However now that i switch back to the default method of powering Ardunio board with USB, getting this error while trying to upload the sketch.

There are forums available on Arduino platform but no definitive resolution.

The board is recognized by the IDE.

[![Board ID Information][1]][1]

[![Snap Shot of the ERROR][2]][2]

  [1]: https://i.stack.imgur.com/gy982.png
  [2]: https://i.stack.imgur.com/aJXb1.png

title: Getting error while uploading a sketch through Ardunio IDE

Answers: 1

body:
Reinstall the bootloader using your ISP programmer.

Installing a sketch using ISP first wipes the chip clean, and that includes the bootloader. Without the bootloader the USB interface won't be able to communicate with the main MCU.


body:
As far as I understand, `yield()` is used when you have long code (e.g. loop) so the background processing required by the esp8266 is not suspended for long time.

I have application where some sound should be running all the time and in the same time the program has to do other things which may includes long loops (that I call `yield()` inside them). Those long loops cause the sound to be discontinues.

What is the best idiomatic way of imitating the `yield()` function in my program so I do some thing like this:

    for(int i=0;i<10000;++i){
        yield();
        customeYield();
        someFunction(i);
    }
Where `customeYield()` contains the necessary instruction for playing the sound. It is exactly like this (I am using ESP8266Audio):

    if (mp3_->isRunning()) {
        if (!mp3_->loop()) {
            mp3_->stop();
            return true;
        }
        return false;
    }
    return true;

Of course, I can just call it like I did (making it global or something). However, I was wondering if there is a standard way for such a task.

title: Custom function like yield

Answers: 1

body:
Without any hint, what you are actually doing in your long loops, it is difficult to say, what way would be the best for your case. I don't believe, there is a standard way of doing this, but there are basically only two ways of multitasking on a microcontroller:

 1. **Interrupt driven:** You can set a timer interrupt, that occurs regularly to call the `AudioGenerator::loop()` function (which fills the buffer with the next data).
 2. **Non-blocking code:** If you are using non-blocking code, you can first do one thing and then do another in sequence, so fast, that both codes are executed often enough. Thats exactly what the library you use is designed for (according to the README file).

If you are using more than one of these long loops in your `loop()` function, you may consider doing things with a finite state machine (FSM), so that you don't have to always add the `AudioGenerator::loop()` function to your long loops, but only once for the normal `loop()` function.


body:
I'm trying to learn how to program a MC, so maybe I didn't know much about a MC. I tried to test interrupt pin of ATtiny85 with this simple code

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

    void setup()
    {
      GIMSK = 0b00100000;
      PCMSK = 0b00000001;
      sei();
      DDRB = 0b00010000;
    }

    void loop()
    {
      PORTB = 0b00010000;
      _delay_ms(500);
      PORTB = 0b00000000;
      _delay_ms(500);
    }

    ISR(PCINT0_vect)
    {
      PORTB = 0b00010000;
      _delay_ms(100);
      PORTB = 0b00000000;
      _delay_ms(100);
      PORTB = 0b00010000;
      _delay_ms(100);
      PORTB = 0b00000000;
      _delay_ms(100);
      PORTB = 0b00010000;
      _delay_ms(100);
      PORTB = 0b00000000;
      _delay_ms(100);
      PORTB = 0b00010000;
      _delay_ms(100);
      PORTB = 0b00000000;
      _delay_ms(100);
      PORTB = 0b00010000;
      _delay_ms(100);
      PORTB = 0b00000000;
      _delay_ms(100);
      PORTB = 0b00010000;
      _delay_ms(100);
      PORTB = 0b00000000;
      _delay_ms(100);
      PORTB = 0b00010000;
      _delay_ms(100);
      PORTB = 0b00000000;
      _delay_ms(100);
      PORTB = 0b00010000;
      _delay_ms(100);
      PORTB = 0b00000000;
      _delay_ms(100);
      PORTB = 0b00010000;
      _delay_ms(100);
      PORTB = 0b00000000;
      _delay_ms(100);
      PORTB = 0b00010000;
      _delay_ms(100);
      PORTB = 0b00000000;
      _delay_ms(100);

    }
This is just a blink code with an interrupt to make the LED blink faster 10 times. My question is why sometimes the LED blink faster many times with the interrupt pin is not connected to anything (open)? Didn't it have internal pull up or should I use external pull up in my circuit?

Thank you

title: interrupt pin of attiny85 unstable

Answers: 2

body:
The internal pullup is only activated, if you activate it in your code. To so, you have to write a `1` to the corresponding bit in the `PORTB` register, while the `DDRB` register is set for the pin to be an input.

So you the interrupt gets triggered randomly, because the pin was floating.

Since you are currently always write to the whole `PORTB`, you have to change the last bit to `1` on every `PORTB` write. Or you can write a `1` to it in `setup()` and only change the one output bit in `PORTB` by using

    PORTB ^= 0b00010000;

This will toggle only your output pin.

body:
More than an answer, these are some comments and suggestions on your
program, that I hope will help you write cleaner code:

1. Since you seem to be avoiding using the Arduino core library, you may
   as well write your own `main()` instead of relying on the one from
   the core. This way you have a plain C program that can be compiled
   either within or outside of the Arduino framework.

2. Instead of opaque constants, like `0b00100000`, use the bit names.
   These names are defined in the datasheet and are provided by the
   avr-libc. They are normally used with the `_BV()` macro, which
   expands to `(1<<(x))`.

3. For those of us who do not have the full datasheet in our head, a
   comment or two stating what each bit does is helpful.

4. To change only one bit from a port, use the syntax `PORTB |= ...;`
   or `PORTB &= ...`. The compiler is smart enough to turn this into
   single assembly instructions, namely `sbi` and `cbi`.

5. Rather than repeating ten times the same lines, use a loop.

Applying these suggestions, your program would like like;

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

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

    ISR(PCINT0_vect)
    {
        for (int i = 0; i < 10; i++) {
            PORTB |= _BV(PB4);
            _delay_ms(100);
            PORTB &= ~_BV(PB4);
            _delay_ms(100);
        }
    }

    int main(void)
    {
        PORTB = _BV(PB0);     // internal pullup on PB0
        GIMSK = _BV(PCIE);    // enable pin change interrupt
        PCMSK = _BV(PCINT0);  // sense pin change on PCINT0 = PB0
        DDRB  = _BV(PB4);     // pin PB4 as output
        for (;;) {
            PORTB |= _BV(PB4);
            _delay_ms(500);
            PORTB &= ~_BV(PB4);
            _delay_ms(500);
        }
    }


body:
Forgive me if this is a really dumb question but I am new to IOT and hardware in general.

I have a Huzzah Feather ESP8266 and I am trying to make a bathroom occupancy sensor.  I am using a standard reed switch door sensor (example [here](https://www.sparkfun.com/products/13247)).

Ultimately what I want this device to do is:

 1. The plan is to wake the device from deep sleep when the door is closed, according to the documentation GPIO16 needs to be connected to RST to send a wake signal.

 2. Once awoken check the reed switch and send a message to Azure IoT hub that says the `bathroom is occupied` if door is closed.
 3. Put the device into deep sleep, waking every 30 seconds.
 4. Every time the device wakes check the switch, once the door is opened I send a message to Azure that the `bathroom is not occupied` and then put into `deepSleep(0)` (i.e asleep until the door is closed again, then the process repeats)

**Right now this all works but in the opposite. I can wake the device when the door is opened, the message sends successfully to Azure.**

From my super limited understanding of this it seems like what I want to do should be possible.  I imagine I am missing something very simple, but I have hit a wall here.

I dont know how to make wiring diagrams so hopefully a description of my setup will suffice:

 * GPIO 16: Door sensor wire #2
 * RST: GPIO 16
 * GND: Door sensor wire #2

Simplified code sample:

    void setup()
    {
     initSerial(); //inits serial
        initWifi(); //initis wifi
     door_open(); //sends message
    }

 void door_open() {
   IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, HTTP_Protocol);

   if (iotHubClientHandle == NULL)
   {
  Serial.print("Failed on IoTHubClient_LL_Create\r\n");
   }
   else
   {
  // Because it can poll "after 9 seconds" polls will happen
  // effectively at ~10 seconds.
  // Note that for scalabilty, the default value of minimumPollingTime
  // is 25 minutes. For more information, see:
  // https://azure.microsoft.com/documentation/articles/iot-hub-devguide/#messaging
  unsigned int minimumPollingTime = 9;

  if (IoTHubClient_LL_SetOption(iotHubClientHandle, "MinimumPollingTime", &minimumPollingTime) != IOTHUB_CLIENT_OK)
  {
    Serial.print("failure to set option \"MinimumPollingTime\"\r\n");
  }

  if (IoTHubClient_LL_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
  {
    Serial.printf("failure to set option \"TrustedCerts\"\r\n");
  }

  if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, IoTHubMessage, NULL) != IOTHUB_CLIENT_OK)
  {
    Serial.print("unable to IoTHubClient_SetMessageCallback\r\n");
  }

  IOTHUB_MESSAGE_HANDLE messageHandle;
  if(digitalRead(DOOR) == LOW)
  {
    messageHandle = IoTHubMessage_CreateFromString("closed");
    Serial.println("Door closed");
  }
  else
  {
    messageHandle = IoTHubMessage_CreateFromString("open");
    Serial.println("Door Open");
  }

  if (messageHandle == NULL)
  {
    Serial.print("unable to create a new IoTHubMessage\r\n");
  }
  else
  {
    MAP_HANDLE propMap = IoTHubMessage_Properties(messageHandle);

    if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, (void*)1) != IOTHUB_CLIENT_OK)
    {
   Serial.print("failed to hand over the message to IoTHubClient");
    }
    else
    {
   Serial.print("IoTHubClient accepted the message for delivery\r\n");
    }
    IoTHubMessage_Destroy(messageHandle);
  }

  while (1)
  {
    IoTHubClient_LL_DoWork(iotHubClientHandle);
    ThreadAPI_Sleep(100);
  }
   }
 }

**To clarify:**  Right now my device will wake when the door sensors magnetic parts are separated.  I want the device to wake when the circuit is complete (i.e the sensors are _together_).

title: Wake Huzzah Feather ESP8266 With Reed Switch

Answers: 2

body:
The RST (reset) pin of the ESP works as the reset pin of any other microcontroller. If you pull it to LOW long enough (the threshold is surely listed in the datasheet), the whole microcontroller will reset as if you had cut and reestablished the power supply. So it will not wake it from sleep, but reset it completely.

It is correct, that you can use GPIO16 connected to RST, to let the ESP reset itself from a deep sleep. This seems to be an internal hardware functionality, that is distinct from the normal IO hardware. But you cannot use the same pin for some other functionality at the same time. Your reed switch is closed, if the door is closed. So it gives a LOW level to GPIO16 and RST, holding it in reset state. In this state no code is executed, thus you never get a message, that the door is closed. When you then open the door, the switch opens too. Since the RST pin isn't pulled to LOW anymore, the ESP can boot and execute your code. The door is open, so you get the corresponding message.

So you have to use a different pin for the reed switch.

body:
I would get an NC or NO reed switch, the opposite of whatever you have now that's backwards. I would then get rid of all the sleep wakeup stuff and turn the unit on through the reed switch, so it has power when the door is closed, if that's more common than it being open. When closed (powered), the MCU sends a ping on boot to a server that says "hey i closed", and go to deep sleep for 10 seconds.

Once re-awaking, send out a ping that says "I'm still busy". The server needs a tiny bit of smarts, a time-out feature that sets the door state as open 12 seconds after the last ping (10s + some accounting for wifi delays).

This setup uses NO standby power, and only a tiny amount of battery-killing on-time, so it should last a lot longer than trying to sleep and externally wakeup.

For added efficiency, consider building an ESPNOW router with two more ESP8266s. Once you have that ESPNOW router up and running, you can fire off a ping in about 200ms (from a cold/warm boot) instead of 2000ms with wifi, and go back to sleep. This extends your battery life ~10x, at the cost of running two more ESPs 24/7 where power is easily available.


body:
Portable 5V power for my projects - I was about to get the necessary parts to wire up an OEM LiPo battery (3.7V battery, boost circuit, charging circuit) when I took a peak at pre-built "power banks".  From all the sources I see the LiPo batteries alone cost more than the power bank, at much lower capacity.  For reference:

 - a 10400 mAh power pack (max output 3A @ 5V) is 26$ on Amazon
 - a 10000 mAh power pack (max output 2.1A @ 5V) is 9$ on Hobby King
 - a 2500 mAh LiPo is 17$ on Amazon
 - a 5000 mAh Lipo is 8$ on Hobby King

The power packs already have charging and voltage regulation circuitry! The price difference makes me think I am missing something.

Reading around I notice issues with power packs auto-shutdown at low current draws. But other than this power packs seem cost optimal and technically equivalent - at least within the output amperage range of the power banks.

Questions:

 - Are there any technical differences in output voltage, lifetime, or otherwise I am missing here?
 - Are there any "surprises" I'm going to face by using a power pack?
 - Can you recommend a solid power pack that doesn't shut down at arduino level draws. (My app will draw 800mA @ 5V max, but during sleep, the draw of an Arduino Nano)

Thanks!

title: LiPo + charge/boost circuit vs pre-built "power bank" - contrasting portable power sources

Answers: 1

body:
The thing to remember with power banks bought on places like eBay and Amazon is:

* **THEY LIE ABOUT THE CAPACITY**

A typical power bank you would expect to get around 3600mAh from, even though it may say 10000mAh, 50000mAh, 1,000,000,000,000mAh, etc.

The only technical difference between rolling your own circuit and a power bank is the low-current switch-off that *many* (but not all) of them have.  That switch-off is fine if you are always drawing a good amount of current, but once your device goes to sleep and the current drops right down you'll find the power bank will switch off and your device will never wake up again.

However, with rolling your own system you know what you are getting. You know the capacity of your battery.

One further thing to consider: Do you *really* need 5V? The majority of electronics run from 3.3V nowadays, and the Arduino is no different. There are Arduino boards designed to run from 3.3V, and even 5V boards can be tweaked to run at 3.3V (albeit slower than normal).

So the ideal solution would be:

* A single-cell Li-Poly / Li-Ion giving nominal 3.7V
* A Li-Ion charger circuit
* A low-dropout or switching regulator with max 400mV dropout.

And no boost circuit needed. Also, no logic level shifting when communicating with 3.3V devices.


body:
I had been using Arduino 1.0.5 on my Pi, and in September last year downloaded `arduino-1.8.4-linux32.tar.xz` (which I have since updated).

I have been successfully using 1.8.5, but just noticed it seems to have been `/home/pi/.arduino15` for preferences and packages.

I probably did this inadvertently when I was briefly running both 1.8.4 and 1.0.5 (which is long gone). I have `/home/pi/.arduino` but this only contains `preferences.txt` and has not been used since September.

There seems to be no  way of changing this to the normal directory; where is this configured?

title: How to configure location of preferences

Answers: 1

body:
Since the introduction of many enhancements in the IDE, such as the Boards Manager, and the Arduino Builder system, it was decided that this would break backwards compatibility with older versions of the IDE.  In version 1.5.0 of the IDE it was therefore decided that the location of all the Arduino data files (of which there are now many, not just a `preferences.txt` file) should be moved to a new location, and `.arduino15` was chosen to reflect the current version.

Since then a *version number war* broke out between the two Arduino factions, which was then subsequently resolved, and we ended up with the 1.8.x group of versions. These, since they haven't introduced anything drastic to the underlying system since 1.5.x, haven't needed to change the location of the data files (indeed, to do so would be undesirable), so it has remained as `.arduino15`.

I don't believe it's possible to change the preferences location, since the only place would be in preferences, and it would need to load the preferences to know where to load the preferences from.

If you *really* need to access the `preferences.txt` file yourself as `~/.arduino/preferences.txt` (why would you?) then you can just delete the old `.arduino` directory and create a link to the new one:

    $ rm -rf .arduino
    $ ln -s /home/pi/.arduino15 .arduino

----
Update:

There is a command-line argument to the Arduino IDE that lets you set the location of the preferences.txt file (detailed [here](https://github.com/arduino/Arduino/blob/master/build/shared/manpage.adoc)):

    $ arduino --preferences-file /home/pi/.arduino/preferences.txt

However what that will do with an old preferences.txt file is anyone's guess.


body:
I have an Arduino UNO with 3 switches attached (2 limit switches, 1 activation switch). I'm trying to make the activation switch turn the motor forwards once hit, then wait for any of the limit switches to be hit and stop the motor. The next step is to wait for the activation switch to be hit again and turn the motor in the opposite direction and wait for the limit switch to be hit and stop the motor.

But the issue I'm facing right now is when i press the activation switch the arduino board and H bridge board restart. The LED's turn on and off and the code restarts. And nothing happens. I know all the switches and motor is working because i have tested them by simplifying the code with just the functions.

(edit) Here is a picture of the schematic: [![Schematic View][1]][1]

Can someone please review my code below to see if my logic is correct.

    const byte  frontButtonPin = 2;
    const byte  backButtonPin = 4;
    const byte  onOffButtonPin = 11;
    const int   motorPin =  8;
    const int   motorPin2 =  7;

    boolean  frontButtonState = 0;
    boolean  backButtonState = 0;
    boolean  onOffButtonState = 0;

    /**
        setup inputs for switches and outs for motor pins
        serial begin to read the switches to test for errors
    */
    void setup() {
      // initialize the pin as an inputs:
      pinMode(motorPin, OUTPUT);
      pinMode(motorPin2, OUTPUT);
      // initialize the pushbutton pin as an input:
      pinMode(frontButtonPin, INPUT);
      pinMode(backButtonPin, INPUT);
      pinMode(onOffButtonPin, INPUT);
      Serial.begin(9600);
    }

    /**
       this function turns motor foward
    */
    void drawMovesForward() {
      // turn motor foward:
      digitalWrite(motorPin, LOW);
      digitalWrite(motorPin2, HIGH);
    }

    /**
       this function turns motor backwards
    */
    void drawMovesBackward() {
      // turn motor in other direction:
      digitalWrite(motorPin, HIGH);
      digitalWrite(motorPin2, LOW);
    }

    /**
       Stop the motor form moving
    */
    void stopDrawFromMoving() {
      digitalWrite(motorPin, LOW);
      digitalWrite(motorPin2, LOW);

    }

    /**

    */
    void loop() {

      frontButtonState = digitalRead(frontButtonPin);
      backButtonState  = digitalRead(backButtonPin);
      onOffButtonState = digitalRead(onOffButtonPin);

      if (onOffButtonState == HIGH) {
        if ( frontButtonState == LOW ) {
          drawMovesForward();

        }

        else if (backButtonState == LOW ) {
          drawMovesBackward();
        }

      }
      else {
        if ( frontButtonState == HIGH ) {
          stopDrawFromMoving();
        }

        else if (backButtonState == HIGH ) {
          stopDrawFromMoving();
        }
      }
    }

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

title: Stopping / starting DC motor with Limit Switches and on/off button

Answers: 4

body:
**Check your switches have pull-up resistors**

It would be helpful if your question included a schematic. Do you have pullup resistors in line with your activation and limit switches? If not, you might find the input is "floating" - that is, it will randomly return either HIGH or LOW. This would possibly cause the motor to go forwards and backwards, but because the loop is possibly occurring hundreds of times per second, you might not see anything moving. You need pull-up or pull-down resistors in the circuit so the Arduino can see a definite LOW or HIGH. See https://www.arduino.cc/en/Tutorial/Button for a tutorial with a resistor, or even better, use https://www.arduino.cc/en/Tutorial/InputPullupSerial and use the existing onboard pullup resistors on the Arduino, as suggested by [Juraj][1] below.

**Potential Logic Error**

There might be a logic error in this part of the code:

      if (onOffButtonState == HIGH) {
        if ( frontButtonState == LOW ) {
          drawMovesForward();
        }
        else if (backButtonState == LOW ) {
          drawMovesBackward();
        }
      }
      else {
        if ( frontButtonState == HIGH ) {
          stopDrawFromMoving();
        }
        else if (backButtonState == HIGH ) {
          stopDrawFromMoving();
        }
      }

Loop #1: Let's say the *onOffButtonState* is HIGH (someone has pressed the switch to ON). The drawer is closed, so the front limit switch is depressed, so *frontButtonState* is HIGH. So the program will execute **stopDrawFromMoving**, and do nothing. Currently you are saying nothing is happening, so this might be your issue.

What you will probably need to do is use flags and while loops. For example:

At the start of the loop() declare this

    drawerMovingOutFlag = 1;

Then change the loop to contain:

    if (onOffButtonState == HIGH) {
        if ( frontButtonState == HIGH ) {
            while(drawerMovingOutFlag == 1)
                drawMovesForward();
                if ( backButtonState == HIGH ) {
                    drawerMovingOutFlag = 0;
                    stopDrawFromMoving()
                }
            }
        }
        else ...

I'll let you do the rest!

  [1]: https://arduino.stackexchange.com/users/37622/juraj

body:
I actually had the right code all along but I just had to add delays when reading the limit switches and detecting the activation switches. Here is one of the original programs i wrote that i threw out thinking it doesnt work, but once the delays were added it works fine.

    // constants won't change. They're used here to set pin numbers:
    const int buttonPin = 4;     // the number of the pushbutton pin
    const int buttonPin3 = 11;     // the number of the pushbutton pin
    const int buttonPin2 = 2;     // the number of the pushbutton pin
    const int motorPin =  8;      // the number of the LED pin
    const int motorPin2 =  7;      // the number of the LED pin

    // variables will change:
    boolean buttonState = 0;         // variable for reading the pushbutton status
    boolean buttonState2 = 0;         // variable for reading the pushbutton status
    boolean buttonState3 = 0;   // variable for reading the pushbutton status

    int drawPosition = 2;  // Tells progam what position the draw is in

    /**
     *  setup inputs for switches and outs for motor pins
     *  serial begin to read the switches to test for errors
     */
    void setup() {
        // initialize the pin as an inputs:
        pinMode(motorPin, OUTPUT);
        pinMode(motorPin2, OUTPUT);
        // initialize the pushbutton pin as an input:
        pinMode(buttonPin, INPUT);
        pinMode(buttonPin2, INPUT);
        pinMode(buttonPin3, INPUT);
        Serial.begin(9600);
    }

    /**
     * this function turns motor foward
     */
    void drawForward() {
         // turn motor foward:
         digitalWrite(motorPin, LOW);
         digitalWrite(motorPin2, HIGH);
    }

    /**
     * this function turns motor backwards
     */
    void drawBackward() {
         // turn motor in other direction:
         digitalWrite(motorPin, HIGH);
         digitalWrite(motorPin2, LOW);
    }

    /**
     * Stop the motor form moving
     */
    void stopDrawFromMoving() {
      digitalWrite(motorPin, LOW);
      digitalWrite(motorPin2, LOW);

    }

    /**
     *
     */
    void loop() {
       // read the state of the pushbutton value:
       buttonState = digitalRead(buttonPin);
       buttonState2 = digitalRead(buttonPin2);
       buttonState3 = digitalRead(buttonPin3);

       // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
       if (buttonState == HIGH) {
          drawPosition = 2;
          Serial.println(F("Front button state is high draw is open"));
          stopDrawFromMoving();
       }else if (buttonState2 == HIGH) {
          drawPosition = 1;
          stopDrawFromMoving();
      }

      if (buttonState3 == HIGH) {
        if( drawPosition  == 1 ){
          drawBackward();
          delay(100);
          drawPosition = 2;
          delay(100);
        }else if (drawPosition == 2 ) {
          delay(100);
          drawForward();
          delay(100);
          drawPosition = 1;
        }

      }
    }

body:
I know this was opened years ago now but I just wanted to add some clarification. When I started this project and created this question I had 0 understanding of software development and didn't understand the code I was writing at the time. Now 3 years later I have revised this project multiple times.

The logic for a project like this is pretty simple, but if you're new to programming and trying to get into the STEM field with Arduino school projects and such, here is what my code now looks like for this same project:
https://github.com/LeehamElectronics/Automated-Cabinet

I have tried to comment it as best I could to help other students understand it. The project is simply a timber cabinet that has an electrically automated draw inside that can be opened and closed at will.

If you are stuck with a similar problem with your own project, I would suggest that you watch a free YouTube video course for C++ programing or even a Arduino programming video course. Even just a few hours of doing that will be enough to get started. That's the one thing I wish someone told me to do when I was starting off 3 years ago, I was wasting hours and hours debugging code that I didn't understand because I just jumped straight into Arduino with little understanding of coding.

I hope this comment helps someone else out there in a similar situation to mine 3 years ago.

Cheers

edit: the answers given about debouncing and pull-up resistors are also important in these types of projects.

body:
That is an excellent project. Great work.

Some suggestions for improvement. You could use a [`enum class byte`][1] instead of a `String` for the drawer position and the drawer moving direction:

```cpp
/* Allows the program to keep track of the last known position of the drawer */
enum class DrawerPositions : byte
{
  Closed,
  Open
} drawerPosition = DrawerPositions::Closed;

/* Keep track of what direction the drawer is moving, can one of the following:  Null | Closing | Opening */
enum class DrawerMovingDirections : byte
{
  Null,
  Closing,
  Opening
} drawerMovingDirection = DrawerMovingDirections::Null;
...
if (drawerPosition == DrawerPositions::Closed)
...
else if (drawerPosition == DrawerPositions::Open)
...
if (drawerMovingDirection == DrawerMovingDirections::Opening)
...
```

It would also be a good idea to add debouncing for all the switch inputs. There are many debouncing algorithms on the internet, but here is a very [simple debouncer][2] I put on GitHub which could be implemented something like this:

```cpp
#include "Debouncer.h"
...
void loop()
{
  static Debouncer limitSwitch0(limitSwitchPin0);
  static Debouncer limitSwitch1(limitSwitchPin1);
  static Debouncer manualToggleButton(manualToggleButtonPin);

  limitSwitch0.Update();
  limitSwitch1.Update();
  manualToggleButton.Update();

  if (drawerIsMoving == true)
  {
    if (drawerMovingDirection == DrawerMovingDirections::Opening)
    {
      if (limitSwitch0.Output() == LOW)  // Get the debounced output of the switch.
      {
        drawerPosition = DrawerPositions::Open;
  ...
  if(manualToggleButton.Rise())   // For rising edge trigger.
  //if(manualToggleButton.Fall())  // For falling edge trigger.
  {
    ...
  }
  ...
}
```

Here is a [debounce demo][3] I put on Wokwi.

  [1]: https://hackaday.com/2017/05/05/using-modern-c-techniques-with-arduino/
  [2]: https://github.com/TimMathias/Arduino-Debouncer
  [3]: https://wokwi.com/arduino/projects/302766933165474312


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

    #include <TinyGPS++.h>
    #include <SoftwareSerial.h>
    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266HTTPClient.h>
    #include <ESP8266WebServer.h>
    static const int RXPin = 4, TXPin = 5;
    static const uint32_t GPSBaud = 9600;

    TinyGPSPlus gps;
    SoftwareSerial ss(RXPin, TXPin);
    float temp1, temp2;

    const char* ssid = "LYN TECH";
    const char* password = "pass word";
    const char* host = "your host name";
    const int trigPin = 2; //D4
    const int echoPin = 0; //D3
    long duration;
    int distance;
    int t = 27;

    void setup()
    {
        Serial.begin(115200);
        Serial.println();
        ss.begin(GPSBaud);

        pinMode(trigPin, OUTPUT);
        pinMode(echoPin, INPUT);
        Serial.begin(115200);
        delay(100);
        //Serial.print("Connected to..");
        WiFi.begin(ssid, password);
        while (WiFi.status() != WL_CONNECTED) {
            delay(500);
            Serial.print(".");
        }
    }

    void checkGPS()
    {
        if (gps.charsProcessed() < 10) {
            Serial.println(F("No GPS detected: check wiring."));
        }
    }

    void loop()
    {

        while (ss.available() > 0) {
            // sketch displays information every time a new sentence is correctly encoded.
            if (gps.encode(ss.read()))
                if (gps.location.isValid()) {

                    float latitude = (gps.location.lat()); //Storing the Lat. and Lon.
                    temp1 = latitude;
                    delay(2000);
                    float longitude = (gps.location.lng());
                    temp2 = longitude;
                    delay(2000);

                    Serial.print("LAT:  ");
                    Serial.println(latitude, 6); // float to x decimal places

                    Serial.print("LONG: ");
                    Serial.println(longitude, 6);
                }
        }

        WiFiClient client;
        const int httpPort = 80;
        if (!client.connect(host, httpPort)) {
            Serial.println("Connection failed");
            delay(1000);
            return;
        }

        digitalWrite(trigPin, LOW);
        delayMicroseconds(2);
        digitalWrite(trigPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(trigPin, LOW);
        distance = duration * 0.034 / 2;
        Serial.print("Distance: ");
        Serial.println(distance);
        Serial.println(WiFi.localIP());
        String url = "your url.php?dist=" + String(distance) + "&lat=" + String(temp1, 6) + "&lng=" + String(temp2, 6);
        client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                    "Host: " + host + "\r\n" +
                    "Connection:close\r\n\r\n");
    }

title: GPS is working but Distance is always showing 0. Can't calculate Distance in this code

Answers: 0


body:
I have no free pin on my ESP-12 but GPIO16 and TxD (GPIO1). I use [Neo Pixel Library](https://github.com/adafruit/Adafruit_NeoPixel) and this design:
[![enter image description here][1]][1]

* GPIO16 powers it on/off
* TxD uses to handle single-wire-based for LEDs (GPIO1)

It works but it has one issue. I use USB <> TTL converter to program my ESP, it just worked for 1 2 times and after that burned the converter! I'm afraid there's something wrong with my design. Any better idea to use GPIO16 and TxD to do that? I need to power down LEDs when I don't need them to save power.

  [1]: https://i.stack.imgur.com/4rOd4.png

title: Using TxD pin and NeoPixel library for RGB LEDs

Answers: 0


body:
I have DHT22 sensor attached to an ESP8266. When running a sketch that read the sensor values, it suffer from frequent hangs (something like each 1 second).

All outputs are stopped (Sound from speaker or even the Serial output) during those hangs.

Here is a small Sketch to reproduce:

    #include "DHT.h"
    DHT dht(D1,DHT22);
    void setup(){
      Serial.begin(115200);
    }
    void loop(){
      Serial.println(dht.readTemperature(true));
      Serial.println(dht.readHumidity());
      delay(1);
    }

P.S. it is not about the small `delay(1)`. Even if I read the sensor values each 1 second, this problem will occur. To make sure, you may run this example:

    #include "DHT.h"
    DHT dht(D1,DHT22);

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

    unsigned long last = 0UL;
    void loop(){
      if(millis() - last > 1000){
          Serial.println("#########" + String(dht.readTemperature(true)));
          Serial.println("#########" + String(dht.readHumidity()));
          last = millis();
      }
      Serial.println(String(rand()));
      delay(10);
    }
After flashing it, opens serial monitor and you can see clearly the hangs (I put random number printing so your eyes can not cheat you by an cashed old value;) )

title: ESP8266 and DHT22 frequent hangs

Answers: 0


body:
Today i bought my second NANO(First one was made of Gravitech).I have some doubts that if it is a counterfeit product.I have noticed some points & they are as follows.

1)No "NANO" printed on the top of the board.

2)The atmega328p is in MLF package.

3)A diode soldered on the back side of a board is not properly positioned.

4)No version is printed anywhere.

5)The word "ICSP" not printed near the ICSP header.

6)No pin marking(white dot) for ICSP pin#1.

The seller is a very reputable one in India.That's why i can't be 100% sure if it is a counterfeit product.
I am attaching some pics.Please take a look & give your valuable feedback.

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

[enter image description here][2]

[![enter image description here][3]][3]

[![enter image description here][4]][4]

[![enter image description here][5]][5]

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

  [1]: https://i.stack.imgur.com/zVtdt.jpg
  [2]: https://i.stack.imgur.com/x44qY.jpg
  [3]: https://i.stack.imgur.com/jD5Q1.jpg
  [4]: https://i.stack.imgur.com/0x2ab.jpg
  [5]: https://i.stack.imgur.com/2I1op.jpg
  [6]: https://i.stack.imgur.com/gndfr.jpg

title: Is this Arduino NANO counterfeit?

Answers: 0


body:
I'm a C++ / Arduino newbie, trying to build a custom library for the first time. I created a unit called `CDSensors.cpp`, which has two methods, `SetupSensor` and `ReadSensors`. The sensor is a SparkFun accelerometer/magnetometer.

If there are any errors in the settings, the sensor returns all zeros for compass and accelerometer. If there is no pointer or other connection between the `SetupSensor` and `ReadSensor` methods, the sensor returns all zeros as if it hasn't been setup.

So I'm trying to pass a reference to the sensor library between the methods as shown with the Limu object in the code below. I now get mag data but the accelerometer returns all zeros so something in my object references is messing with the sensor setup? (the accelerometer works ok in the SparkFun demo code, on which my code is based).

Main.ino

    #include <CDSensors.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SparkFunMPU9250-DMP.h>

    CDSensors* LSensors = &CDSensors     (0);
    CDSerialPrint* LSerialPrint = &CDSerialPrint (0);
    MPU9250_DMP Limu = MPU9250_DMP ();
    unsigned long LTimeNow = 0;

    struct meas {
      int BUx;
      int acc_x
    };

    struct meas r;

    void setup() {
      LSensors->SetupSensors (Limu);
    }

    void loop() {
      LSensors->ReadSensors  (Limu, LTimeNow, r.BUx, r.acc_x);
      Serial.print((int) (r.BUx) );
      Serial.print((int) (r.acc_x) );
    }

CDSensors.h

 #ifndef CDSensors_h_h
 #define CDSensors_h
 #include <Wire.h>
 #include <SPI.h>
 #include <SparkFunMPU9250-DMP.h>

 class CDSensors {
   public:
  CDSensors(int);
  static void SetupSensors(MPU9250_DMP *imu);
  void ReadSensors (MPU9250_DMP *imu, unsigned long& TimeNow, int&     BUx,int& BUy,int& BUz,int& acc_x,int& acc_y,int& acc_z,int& a0,int& a1,int& a2,int& a3 );
   private:
  int value;
 };
 #endif

CDSensors.cpp

    #include <Wire.h>
    #include <SPI.h>
    #include <SparkFunMPU9250-DMP.h>
    #include "CDSensors.h"

    //MPU9250_DMP imu;
    boolean       MPU9250_found = false;
    unsigned long TimeNow = 0;
    CDSensors::CDSensors(int givenValue) {
      value = givenValue;
    }

    static void CDSensors::SetupSensors(MPU9250_DMP imu) {
      if (imu.begin() != INV_SUCCESS) {
        while (1) {
          Serial.println("No MPU-9250 found, Check connections");
          delay(5000);
        }
      }
      imu.setSensors(INV_XYZ_ACCEL | INV_XYZ_GYRO | INV_XYZ_COMPASS);
      imu.setGyroFSR(2000);
      imu.setAccelFSR(2);
      imu.setLPF(188);
      imu.setSampleRate(100);
      imu.setCompassSampleRate(100);
    }

    void CDSensors::ReadSensors(MPU9250_DMP imu, unsigned long& TimeNow, int& BUx, int& acc_x) {
      TimeNow = millis();
      if (imu.dataReady()) {
        imu.update(UPDATE_ACCEL | UPDATE_GYRO | UPDATE_COMPASS);
      }
      BUx = imu.calcMag(imu.mx);
      acc_x = imu.calcAccel(imu.ax);
    }

title: Passing reference to hardware between methods in custom class

Answers: 1

body:
I don't think you are creating instances of these classes correctly. Instead of:

    CDSensors*     LSensors      = &CDSensors     (0);
    CDSerialPrint* LSerialPrint  = &CDSerialPrint (0);
    MPU9250_DMP   Limu = MPU9250_DMP ();

How about:

    CDSensors LSensors (0);
    CDSerialPrint LSerialPrint (0);
    MPU9250_DMP Limu;

I can't get your code to compile, but what I suggest looks a lot simpler.

---

Is your intention here:

    if (imu.begin() != INV_SUCCESS)
      imu.setSensors(INV_XYZ_ACCEL | INV_XYZ_GYRO | INV_XYZ_COMPASS);
      imu.setGyroFSR(2000);
      imu.setAccelFSR(2);
      imu.setLPF(188);
      imu.setSampleRate(100);
      imu.setCompassSampleRate(100);

.. to really be:

    if (imu.begin() != INV_SUCCESS)
      {
      imu.setSensors(INV_XYZ_ACCEL | INV_XYZ_GYRO | INV_XYZ_COMPASS);
      imu.setGyroFSR(2000);
      imu.setAccelFSR(2);
      imu.setLPF(188);
      imu.setSampleRate(100);
      imu.setCompassSampleRate(100);
      }

The indentation suggests so.

---

> if I understood correctly the class is created on startup with
>
>            CDSensors* LSensors = &CDSensors (0);
>
>  and is then persistent.

 `LSensors` is a persistent *pointer* but `CDSensors (0)` is a temporary object created for the purpose of doing an assignment. For example:

    int foo = 2 + 3;

Now the compiler calculates 2 + 3 (giving 5), assigns that to foo, and then discards the temporarily-calculated 5 used to do the assignment.

In your case `CDSensors (0)` calls the constructor for CDSensors, creating a temporary object. Then the "&" operator takes its address (somewhere on the stack I would guess). This address is copied into LSensors. Then the object is destroyed because its lifetime is over. The compiler even warns you this is happening:

     CDSensors*     LSensors      = &CDSensors     (0);
                                                     ^
    sketch_may07a:5: error: taking address of temporary [-fpermissive]

That means the pointer is now invalid because the underlying object (that it is pointing to) has now been discarded.

---

I've even seen people do something like this quite a bit:

         CDSensors LSensors = CDSensors (0);

This isn't so bad because pointers aren't involved, but it still involves making a temporary instance of the class, then *copying* that into LSensors, and discarding the original one.

*This* is how to make a new instance of a class:

     CDSensors LSensors (0);   // the actual class, not a pointer

Or if you want a pointer:

     CDSensors * pLSensors;  // a pointer to the class (initially NULL)

Then in `setup` you create the instance:

    pLSensors = new CDSensors (0);


body:
How come I never see any Arduino Library expose some of it's internal variables as public in the header file? I only see functions which are declared as public, while every variable is declared private.

Background: I want to write my first Arduino library. And I thought of making some variables of this library public, so that I don't have to call a function later on when I import the library.

E.g. I want:

    #include MyLibrary
    ...
    MyLibrary instance();
    instance.avariable = 12345;
instead of:

    #include MyLibrary
    ...
    MyLibrary instance();
    instance.setVariable(12345);

title: Arduino Libraries: Declaring variables as public?

Answers: 2

body:
Classes are used to hide away the complexity of a certain task. The user of the class should not worry about how the library exactly works in the inside, but instead only worry about how it should be used. In many cases directly writing to a member variable can be not only convenient, but hurtful if a wrong value is set. If you instead use a function to set the variable, the author can add code to prevent wrong values from actually being written to the variable. Also there might be some other logic involved, that is not triggered, if you write directly to the variable. So - for the ease of use - the users might want the library to be responsible for this, not themselves.

If you write a library, you have thought about how it should be used. Hiding other ways away is a common way of leading the user through the usage. Ways of usage, that don't go along with the purpose of the library can be hided away to make the correct way clearer. A manufacturer of a saw doesn't give the user instructions how to use the wrong side of the blade, because it doesn't help you with sawing.

This does not mean, that you shouldn't make variables public at all, but only if it makes sense. For example: If you are defining a class, that just represents a point in a coordinate system without hooks to other code, it is totally OK to make the coordinates public. But if you defined the class, so that the point is directly shown on a display, you might want to change the position on the display, whenever one of the coordinates is changed. In this case you can use a set-function to trigger the display update, when a new value was given for the variable.

body:
The Arduino ecosystem is meant mostly for beginners. This often means that people with very little knowledge will be using it and will often try random things to make stuff work. (and once they found something that works will teach it to the next guy that has the dame problem).

Disallowing things that would easily break the invariants of the library from the outset reduces the amount of support you need to give to people that inadvertently break the library by randomly changing some variable.


body:
I am having a bit of trouble loading values stored on an SD card and assigning them to variables within my program. I can achieve this as one big block of data, but would much prefer them to be saved to variables whilst in a loop or some other process.

My txt file has the following 6 ints & floats values, which are displayed vertically in the file:

2
0.003200
312
1
0.720000
8

Each of these values I want assigned to variables data1,....2,3,4,5,6. Unfortunately, the code I use below will never achieve this, but I am clueless as to any theory to solve this problem. Thanks in advance.

    myFile = SD.open("test.txt", FILE_READ);
        if (myFile) {
        while (myFile.available()) {
            data = myFile.read();
        }
    myFile.close();
    }
    else {
        Serial.println("Read Error");
    }

title: Arduino: load variables with values read from SD card

Answers: 1

body:
File implements [Stream][1] just like Serial. so you can use parseInt and parseFloat

    int n = File.parseInt();
    float x = File.parseFloat();
    Serial.println(n);
    Serial.println(x, 6);

  [1]: http://arduino.cc/reference/en/language/functions/communication/stream


body:
Sorry for doing this, I really don't know where to post beacuse this is both Android Studio code and Arduino code so I've posted to both sites.

I want to create a project of using controlling pan-tilt (2 servos combined) using the accelerometer and gyroscope data in smartphone. Creating Android app and sending the accelerometer and gryroscope data to Arduino so that the pan-tilt can determine its location.

My problem is when I connect the Android app to Arduino, no data is shown in serial monitor of Arduino and the pan-tilt is not locating the smartphone.
Please help me to solve this problem.

This *MainActivity* is the class to identify the data of accelerometer and gyrscope.

MainActivity:

    public class MainActivity extends AppCompatActivity implements SensorEventListener{

        private final String TAG = "MainActivity";//log our activity

        SensorManager sm;//define sensor manager
        Sensor accelerometer, gyrometer;//define accelerometer

        TextView xValue, yValue, zValue, xGyroValue, yGyroValue, zGyroValue;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            xValue = (TextView)findViewById(R.id.xValue);
            yValue = (TextView)findViewById(R.id.yValue);
            zValue = (TextView)findViewById(R.id.zValue);

            xGyroValue = (TextView)findViewById(R.id.xGyroValue);
            yGyroValue = (TextView)findViewById(R.id.yGyroValue);
            zGyroValue = (TextView)findViewById(R.id.zGyroValue);

            Log.d(TAG, "onCreate: Initializing Sensor Services");

            sm =(SensorManager) getSystemService(Context.SENSOR_SERVICE);//permission to use the sensor

            accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
            if (accelerometer != null) {

                sm.registerListener(MainActivity.this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
                Log.d(TAG, "onCreate: Registered accelerometer listerner");
            }else {

                xValue.setText("accelerometer is not supported");
                yValue.setText("accelerometer is not supported");
                zValue.setText("accelerometer is not supported");
            }
            gyrometer = sm.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
            if (gyrometer != null) {

                sm.registerListener(MainActivity.this, gyrometer, SensorManager.SENSOR_DELAY_NORMAL);
                Log.d(TAG, "onCreate: Registered gyrometer listerner");
            }else {

                xGyroValue.setText("gyrometer is not supported");
                yGyroValue.setText("gyrometer is not supported");
                zGyroValue.setText("gyrometer is not supported");
            }
        }

        public void connect(View v){

            DataSender dataSender = new DataSender();
            dataSender.execute((String) xValue.getText(), toString());
            dataSender.execute((String) yValue.getText(), toString());
            dataSender.execute((String) zValue.getText(), toString());
            dataSender.execute((String) xGyroValue.getText(), toString());
            dataSender.execute((String) yGyroValue.getText(), toString());
            dataSender.execute((String) zGyroValue.getText(), toString());

        }

        @Override
        public void onSensorChanged(SensorEvent sensorEvent) {
            Sensor sensor = sensorEvent.sensor;
            if(sensor.getType() == Sensor.TYPE_ACCELEROMETER){

                Log.d(TAG, "onSensorChanged: X: " + sensorEvent.values[0] + "Y: " + sensorEvent.values[1] + "Z:" + sensorEvent.values[2]);

                xValue.setText("xValue:   " + sensorEvent.values[0]);
                yValue.setText("yValue:   " + sensorEvent.values[1]);
                zValue.setText("zValue:   " + sensorEvent.values[2]);
            }else if (sensor.getType() == Sensor.TYPE_GYROSCOPE){

                xGyroValue.setText("xGyroValue:   " + sensorEvent.values[0]);
                yGyroValue.setText("yGyroValue:   " + sensorEvent.values[1]);
                zGyroValue.setText("zGyroValue:   " + sensorEvent.values[2]);

            }

        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {

        }
    }

This DataSender is the class for sending the data to Arduino.

DataSender:

    public class DataSender extends AsyncTask<String, Void, Void> {

        Socket s;
        DataOutputStream dos;
        PrintWriter pw;

        @Override
        protected Void doInBackground(String... voids) {

            String data = voids[0];

            try {
                s = new Socket("192.168.1.100",80);
                pw = new PrintWriter(s.getOutputStream());
                pw.write(data);
                pw.flush();
                pw.close();
                s.close();

            } catch (IOException e){
                e.printStackTrace();
            }

            return null;
        }
    }

This is code that are uploaded in wifi module (esp8266-01) that are connected in Arduino.

Arduino code:

    #include <SoftwareSerial.h>
    #include <Servo.h>

    #define DEBUG true

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

    char tiltChannel=0, panChannel=1;

    //These are the objects for each servo.
    Servo servoTilt, servoPan;

    //This is a character that will hold data from the Serial port.
    char serialChar=0;

    // Center servos
    int tiltVal = 90;
    int panVal =90;

    //smaartphone value
    String inText;
    float value0, value1, value2;

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

      servoTilt.attach(2);  //The Tilt servo is attached to pin 2.
      servoPan.attach(3);   //The Pan servo is attached to pin 3.
      servoTilt.write(90);  //Initially put the servos both
      servoPan.write(90);      //at 90 degress.

      Serial.begin(9600); //for monitoring purposes
      esp8266.begin(9600);

      //sendCommand("AT+CIFS+RST\r\n", 2000, DEBUG); // reset module
      sendCommand("AT+IPR=9600\r\n", 1000, DEBUG);
      sendCommand("AT+CWMODE=1\r\n", 1000, DEBUG); // configure as access point
      sendCommand("AT+CWJAP=\"EceConnect\",\"1234\"\r\n", 3000, DEBUG); //connec to
    a network with name EceConnect with password 1234
      delay(1000);
      sendCommand("AT+CIFSR\r\n", 1000, DEBUG); // get ip address
      sendCommand("AT+CIPSTA=\"192.168.1.100\"\r\n", 1000, DEBUG);
      sendCommand("AT+CIPMUX=1\r\n", 1000, DEBUG); // configure for multiple
    connections
      sendCommand("AT+CIPSERVER=1,80\r\n", 1000, DEBUG); // turn on server on port
    80
      Serial.println("Server Ready");

      Serial.println("Android Sensor Type No: ");
      Serial.println("1- ACCELEROMETER  (m/s^2 - X,Y,Z)");
      Serial.println("2- GYROSCOPE (rad/s - X,Y,Z)");
      Serial.flush();

    }

    void loop() { // run over and over

      Serial.flush();
      int inCommand = 0;
      int sensorType = 0;
      unsigned long logCount = 0L;

      if (Serial.available() < 1) return; // if serial empty, return to loop().

        char getChar = ' ';
        if (esp8266.available()) {
          if (esp8266.find("+IPD,0,")) {
            delay(10);
            esp8266.find(":");
            delay(10);
            char letter = esp8266.read();
            Serial.print(letter); //for monitoring purposes
            //Gets the value/char from android app
          }
        }

        // parse incoming command start flag

        if (getChar != serialChar) return; // if no command start flag, return to
    loop().

        // parse incoming pin# and value
        sensorType = Serial.parseInt(); // read sensor typr
        logCount = Serial.parseInt();  // read total logged sensor readings
        value0 = Serial.parseFloat();  // 1st sensor value
        value1 = Serial.parseFloat();  // 2rd sensor value if exists
        value2 = Serial.parseFloat();  // 3rd sensor value if exists

        // send smartphone readings to serial monitor/terminal
        if (DEBUG) {
          Serial.print("Sensor type: ");
          Serial.println(sensorType);
          Serial.print("Sensor log#: ");
          Serial.println(logCount);
          Serial.print("Val[0]: ");
          Serial.println(value0);
          Serial.print("Val[1]: ");
          Serial.println(value1);
          Serial.print("Val[2]: ");
          Serial.println(value2);
          Serial.println("-----------------------");
          delay(10);
        }

        // Check sensor type. If not for  Accelerometer (#1) then ignore readings
        // sensorType 1 is the Accelerometer sensor

      if (sensorType !=1) return;

      panVal = value0; // value0 = X sensor reading
      tiltVal = value1;  // value1 = Y sensor reading

      tiltVal = map(tiltVal, 10, -10, 0, 179);   // Map Accelerometer Y value to
    tilt servo angle.
      servoTilt.write(tiltVal);
      delay(10);

      panVal = map(panVal, -10, 10, 0, 179);  // Map Accelerometer X value to pan
    servo angle.
      servoPan.write(panVal);
      delay(10);
    }

    String sendCommand(String command, const int timeout, boolean debug) {
      String response = "";
      esp8266.print(command); // send the read character to the esp8266
      long int time = millis();
      while ((time + timeout) > millis()) {
        while (esp8266.available()) {
          // The esp has data so display its output to the serial window
          char c = esp8266.read(); // read the next character.
          response += c;
        }
      }

      if (debug) {
        Serial.print(response);
      }
      return response;
    }

title: Problem connecting Android app to Arduino

Answers: 1

body:
In the `loop` function you have a line

    If (Serial.available() < 1) return;

This prevents further code to be processed if there is nothing in the hardware serial buffer. Think about that.


body:
I need to check if the code burned on the some Arduino is the same one as I have.
I know how to get the hex file from the Arduino. My question is what influence the hex code? Board Type? Microprocessor type? avrdude version? anything else?

title: compare two hex files

Answers: 1

body:
The lines in a typical hex file include a VLI (variable length indicator). The hex files output from the IDE might have different lengths than those produced by avrdude. As a simple example:

File 1:

    03ABC
    03DEF

File 2:

    06ABCDEF

Those files will compare differently to each other but convey the same information, split differently between lines.

To do a genuine comparison you would need to account for that.

> Board Type?

Different boards, but with the same processor, might have identical files.

> Microprocessor type?

Different processor would almost certainly have different hex files.

> avrdude version?

Probably not, however see my comments above about the VLIs.

> anything else?

As I said, the compiler may generate lines with (say) 16 bytes per line, but avrdude might read back lines with 32 bytes per line. Thus they would look different but convey the same hex codes, once you allow for that.


body:
I have been trying to achieve this for a long time using the ITD method and have gone through various articles on the net.

I want to know if its possible to actually achieve sound localization using an Arduino Uno and two MEMS mics with a high gain (https://www.sparkfun.com/products/9868).

I have been trying this on MATLAB using the a=arduino() command and readVoltage command but the main issue I face is that for a particular sound (clapping for instance) the time difference between the two mics is not always the same which results in different direction predictions.

We managed to increase the low resolution of the Arduino by removing unnecessary operations. Now we are able to get an array of size 750 for 10 secs giving a resolution of 0.01 secs. I am not sure if that is enough.

I basically have 3 arrays, one storing the sampling times, and the other two storing the amplitudes of the two analog inputs at that particular time in the first array.

Now I look for a peak in one and then the corresponding near peak in the second one and then compute the time difference. After this I can compute the angle using the speed of sound and the distance between the mics.

Please let me know how I can make this work or where I am going wrong.

title: Sound localization using two mics, Arduino Uno on MATLAB

Answers: 2

body:
Let's assume a microphone distance of 0.5m (which may be just small enough for you). Sound travels with about 300m/s in normal conditions. Let's also say, that you want at least a precision in the angle measurement of 15°.

As stated in the project Mikael linked, it is important that the distance to the sound source is big enough (so that the waves can be seen as planar). Then you have the following situation:
[![enter image description here][1]][1]

We are interested in the difference in distance, that the waves have to travel to the two microphones. It can be calculated by `delta s = d * sin(alpha)`. With `15°` we get `delta s = 0.13m`. The time difference is calculated by `delta t = delta s/v`, where `v` is the speed of sound. We get `delta t = 0.43ms` which equates to `2.32kHz` sampling frequency. Since we use two microphones that must be sampled sequentially, the sampling frequency must be doubled. In the end we have a sampling frequency of `4.64kHz`. So your sampling time of `0.01s` wouldn't be enough for that.

The largest time difference in this setup (with the sound source in line with the microphones) would be `1.6ms`, so your sampling time would be too big even for this.

Regarding the transmission with a baudrate of say 115200 baud this shouldn't be a problem.

But the actual speed of your setup highly depends on your code, which you haven't shown. Maybe [this forum post][2] can help you going further.

  [1]: https://i.stack.imgur.com/QBtzN.png
  [2]: http://forum.arduino.cc/index.php/topic,6549.0.html

body:
You should use the Arduino interrupt function.
This will get it to 4 micros. You cannot use delay on Arduino counting in micros that is needed.
You can have ca 10 cm between mics doing as follows:

You may use accelerometer instead of mic.
Serial read, don't work, too slow. Use ISR..together with Arduino clock is 16 MHz.
Gives a error in +- 10 micros.
Given that it's possible to get the angle within 0.5 degrees if using Sine/Cosine. But, the trigg appear at different places on the waves sinus, giving you extra errors at low freq.

Don't give up.  This works:

1. Attach interrupt (ISR) on 2 pins. Make all variable used in ISR volatile.
2. Use internal clock with micros() to stop at interrupt, flag a variable true if rising/falling/change.
3. Use the time difference from trigs for calculations.
4. Calculations do in loop, not ISR calculate using radians.
5. Don't try to read or write anything while in ISR or before calculations, that mess up the clock!
6. Use 11500 baudrate.
7. If in loop or ISR = true then disable interrupt by state variable.


body:
I am trying to load some variables from an SD card on the start up of my arduino Uno. I have been given some advice but am unable to communicate at the same hours. Using this advice, I have the following edited code, but it doesn't work and I believe that it's my implementation that is the problem. All help would be greatly appreciated.

    myFile = SD.open("test.txt", FILE_READ);
        if (myFile) {
            while (myFile.available()) {
                myFile.read();

                km = myFile.parseInt();
                kmTemp = myFile.parseFloat();
                kmrevs = myFile.parseInt();
                miles = myFile.parseInt();
                milesTemp = myFile.parseFloat();
                milesrevs = myFile.parseInt();

                }
            myFile.close();
            }
        else {
            Serial.println("Read Error");
        }

title: Arduino variables loaded from SD card

Answers: 1

body:
in you [previous question][1], where I answered, you had no commas or new-lines in the example file content. the parseInt and parseFloat ignores only spaces by default.

remove the commas or read them or ignore them with parseInt parameter SKIP_ALL

    km = myFile.parseInt(SKIP_ALL);

  [1]: https://arduino.stackexchange.com/questions/52480/arduino-load-variables-with-values-read-from-sd-card


body:
If I were to increase the of the buffer array from 64 to say 512 will this bring any long term problem in the Arduino Uno.

Changing from this:

    #ifndef _SS_MAX_RX_BUFF
    #define _SS_MAX_RX_BUFF 64 // RX buffer size
    #endif

to this:

    #ifndef _SS_MAX_RX_BUFF
    #define _SS_MAX_RX_BUFF 512 // RX buffer size
    #endif

This is the header file of the software serial.

title: Can increasing the size of the software RX buffer cause problem in Arduino Uno

Answers: 2

body:
The buffer is in the UNO's limited (2K) RAM; you'd be using 1/4 of it for the input buffer. If your app is small enough and simple enough (limited call depth, specifcally), there may still be enough RAM for your app to run successfully. If you have lots of globals (remember to include libraries when you're considering RAM use), allocate much memory from the heap (with `new` or `malloc()`) or have a complex call structure such that funcA() calls funcB() calls funcC() calls ... (etc) so that many functions' stack-frames remain allocated at once - at any point in your program - your program could suffer a stack-collision: the call-stack descends low enough that it can overwrite, or get over-written by, your heap or global data.

Why do you want so large an input buffer? Will data be coming in a high rate or in large bursts, while processing of the data will be infrequent or occur at irregular times? Given the limited RAM in the UNO, running complex programs on one can require something of a balancing act in how you use resources.

Update:

> i was performing some AT commands with software serial and buffer limitation generated junk value

Other reasons why SoftwareSerial might return bad data are:

 - Using too high a baud rate (9600 baud seems to be about the max);
 - Code that turns the interrupts off too often or for too long;
 - Other devices creating too many interupts (perhaps a built-in timer running at a high rate).

The replies to most devices' AT commands that I know of are short enough to not require a huge receive buffer. Asking for list of WiFi SSIDs from an ESP8266 could generate a large reply but most responses should not overflow a more modest buffer.

body: Most arduino modules have 2k ram. So think about that. Whether you need more buffer or more working space. Keep in mind that other libraries are also using the same ram.


body:
Here's the code:

https://pastebin.com/ypWe4NZw

This is the output when I compile:

Sketch uses 13086 bytes (42%) of program storage space. Maximum is 30720 bytes.
Global variables use 1456 bytes (71%) of dynamic memory, leaving 592 bytes for local variables. Maximum is 2048 bytes.

Everything runs smoothly until getNextFood(), Line 194.  I try to make a LinkedList of integers from 0 to 255 (since I am using a 16x16 LED grid).  However, my list only fills up to about 39, then the rest are set to zero.  I suspected that I was out of memory, so I tried optimizing a few things and was able to get to 42.  I changed all the ints to bytes in the getNextFood function and got up to 61, but that broke my program somehow (inf loop).

Any suggestions on how to fix this?  If I can get this list to fit, the program is basically done, I have nothing else to add assuming it works as intended.

Also, why I am running out of RAM in the first place?  Can someone explain which parts of the program are gobbling up those bytes during runtime (because I would expect the integer list to take up around 512 bytes leaving 80 bytes left, so why I am getting cut off around 40 integers or 80 bytes?)

Thanks.

Edit1:  People have pointed out that linked lists take up a lot of space.  I am using this library because the way the program is designed, I needed to make an array that could change size.  I needed to be able to add and remove elements.  Maybe there is a better way to do it, I don't know.  I thought about making a single 16x16 array for the whole thing and using a different number for each type of piece.  I don't know how I would do the snake movement in that case though, because each piece is "connected" to the one in front of it.
If anyone knows of a similar library that would save space I'd be happy to try it.  Also there might be a way for me to avoid using the tempSnake list.

Edit2:  Per Paul's suggestion, I rewrote the code using a single 16x16 array to represent the entire game board, removing the need for LinkedList.  However, it seems I am still falling short, unless there is something else wrong with my code.  The program resets when I try to generate the food tiles.
https://pastebin.com/ZU4hX477

title: Need help optimizing snake game code for Arduino Nano

Answers: 1

body:
16x16 = 256

So there are 256 possible places to put a piece of snake.
The max length of the snake will be 256 (fill the board completely).

So if we take an array of bytes (0-255) that is 256 bytes long we could completely map the snake.

Every step you move (unless if the snake just ate some food) you put it's head forward one step, and remove the last part.

So if we make the new head the value of "snakeLength" and do each piece of the body -1 every round. We will get this "decaying" effect.

For example:

    [ 6][5][4] (all -1, head down) [ 5][4][3]
    [ 0][0][3]                     [ 6][0][2]
    [ 0][1][2]                     [ 0][0][1]

This probably isn't the most efficient method (especially not if you scale it up), but in this case the logic would be very easy.

If the head collides with a position that is not 0, it'll be game over. For the food/apple you could use an x/y value.

If a space is not 0, do it -1.

The upside of this is that you don't allocate memory runtime and you know exactly how many you use.
This setup should also make it easier for you to avoid "copying" the whole list all the time, you can basically loop through the array and do -1 for all but those who are 0.


body:
I'm using a RedBear Duo to read the Serial writes from a RedBear Nano v2. Basically, I use a digital pin of the Duo to raise an interrupt on the Nano. Once, the nano catches the interrupt it writes on its Serial.

You can find a minimum working example below:

### RedBear Duo

    #include <Wire.h>

    /*BLE and WiFi setup*/
    #if defined(ARDUINO)
    SYSTEM_MODE(MANUAL);
    #endif

    char incomingByte;   // for incoming serial data

    void setup() {
        Serial1.begin(115200);     // opens serial port, sets data rate to 9600 bps
        delay(500);
        Serial1.println("Begin!");
        Serial2.begin(115200);

        pinMode(D5, OUTPUT);
    }

    void readSerial() {
        while (Serial2.available() > 0) {
            incomingByte = Serial2.read();
            Serial1.print(incomingByte);
        }
        Serial1.println(" ");

    }

    void loop() {
        digitalWrite(D5, HIGH);
        readSerial();
        delay(2);     // Here's the delay I'm talking about
        digitalWrite(D5, LOW);
        delay(1000);
    }

### RedBear Nano

    uint8_t fire;
    void task_handle(void) {
        fire = 1;
    }

    void setup() {
        Serial.begin(115200);
        fire = 0;
        pinMode(D4, INPUT);
        attachInterrupt(D4, task_handle, RISING);
    }

    void loop() {
        if (fire == 1) {
            fire = 0;
            Serial.write("hello ");
            // Serial.println("fire");
            digitalWrite(D13, HIGH);
        }
        delay(150);
    }

I found this question (https://electronics.stackexchange.com/questions/28739/arduino-delay-of-1ms-necessary-between-serial-read-and-serial-write), and I understood that the problem might be the fact that it takes a while to empty the Serial buffer.

However, I tried to bring the baudrate at 500000 (more than 3x) and still if I change the delay to delay(1), the code is not printing what it has received on the Serial.

I'm trying to understand what is really going on and why I need this delay(2).

Thanks a lot in advance!

title: Strage delay needed after Serial.read()

Answers: 2

body:
Try this code: first delay produces 1ms pulse on pin D5. Without this delay the pulse could be too short for the nano to catch it (you can use delayUs and try finding the shortest interval that produces reliable result). We know that after this pulse, nano sends some data. So wait 100ms to collect it. If you call readSerial right after the pulse was sent, you won't get anything, because you need to wait at least for single byte transmission

    void loop() {
        digitalWrite(D5, HIGH);
        delay(1);
        digitalWrite(D5, LOW);

        delay(100);
        readSerial();

        delay(1000);
    }

body:
This line is wrong:

    attachInterrupt(D4, task_handle, RISING);

It should be:

    attachInterrupt (digitalPinToInterrupt (4), task_handle, RISING);

In any case, attachInterrupt does not apply to D4, it is for D2 and D3 on the Atmega328P.

Note that the pin number is 4, not D4.


body:
I would like to have an arduino board act as a human interface device that can send analog inputs like joysticks.

As it currently stands I see two aproaches to this issue:

1. Use the arduino hid library and program all the reports in myself. This should be fairly simple but I can't seem to find any recourses that I actually understand. I get the idea of reports but I dont get how the report format is described to the OS. I also dont understand how drivers on the pc side of things play into this whole equation.

2. Write some software that makes a serial connection with the arduino and uses java's robot functionality (or similar) to controll a joystick, if even possible. This method would be much easier but would feel overall less polished.

Thank you for your help in advance!

title: Using an Arduino as a Human Interface Device that sends analog inputs

Answers: 1

body: https://github.com/MHeironimus/ArduinoJoystickLibrary does my first aproach. The limitations one what board it can be will not be an issue because I have an extra 32u4 board.


body:
Can anyone figure it out for me? I am new to arduino and 1sheeld, Completely beginner. In my project(Smart Cane For Blind) has currently two part. One is object’s distance detection by using ultrasonic sensor and another feature is Emergency feature. When the blind people lost his way he can press the push button to sent his location to his family member for help.

My problem is that when I integrate that two feature, The sensor part, the detection is too slow and weak.

    #define CUSTOM_SETTINGS
    #define INCLUDE_GPS_SHIELD
    #define INCLUDE_SMS_SHIELD
    #define INCLUDE_VIBRATION_SHIELD
    #define INCLUDE_PUSH_BUTTON_SHIELD
    #define INCLUDE_TERMINAL_SHIELD
    #define INCLUDE_MIC_SHIELD

    /* Include 1Sheeld library.*/
    #include <OneSheeld.h>
    #include <string.h>

    // Define Pins for Sensor 1
    #define trigPin1 4
    #define echoPin1 5

    //Define Pins for Sensor 2
    #define trigPin2 6
    #define echoPin2 7

    // Define Pin for VibMotor 1
    #define motorPin1 12

    // Define Pin for VibMotor 2
    #define motorPin2 13

    /* Define a boolean flag. */
    long duration, distance, UltraSensor, UltraSensorTwo;
    boolean isMessageSent = false;
    float lat;
    float lon;
    String Message;
    String Message1;
    String Message2;
    char latitude[10];
    char longitude[10];

    void setup()
    {
      /* Start communication.*/
      Serial.begin(9600);
      OneSheeld.begin();
    //  PushButton.setOnButtonStatusChange(&Emergency);

      pinMode(trigPin1, OUTPUT);
      pinMode(echoPin1, INPUT);

      pinMode(trigPin2, OUTPUT);
      pinMode(echoPin2, INPUT);

      pinMode(motorPin1, OUTPUT);
      pinMode(motorPin2, OUTPUT);
    }

    void SonarSensor(int trigPin, int echoPin)
    {
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      duration = pulseIn(echoPin, HIGH);
      distance = (duration / 2) / 29.1;
    }

    void SensorHandler() {

      SonarSensor(trigPin1, echoPin1);
      UltraSensor = distance;

      SonarSensor(trigPin2, echoPin2);
      UltraSensorTwo = distance;

      if (UltraSensor <= 60 && UltraSensor >= 45) // Checking the distance, you can change the value
      {
        digitalWrite(motorPin1, HIGH); // motor on
        delay(200);
        digitalWrite(motorPin1, LOW); // motor off
        delay(200);
      }
      else if(UltraSensor < 45 && UltraSensor >=30)
      {
        digitalWrite(motorPin1, HIGH); // when greater than 100cm
        delay(100);
        digitalWrite(motorPin1, LOW);
        delay(100);
      }
      else if(UltraSensor < 30)
      {
       digitalWrite(motorPin1, HIGH);
       delay(50);
       digitalWrite(motorPin1, LOW);
       delay(50);
      }
      else
      {
        digitalWrite(motorPin1, LOW);
      }

      Terminal.print("SensorOne: ");
      Terminal.println(UltraSensor);

        // For VibMotor Two

      if (UltraSensorTwo <= 60 && UltraSensorTwo >= 45) // Checking the distance, you can change the value
      {
        digitalWrite(motorPin2, HIGH); // motor on
        delay(200);
        digitalWrite(motorPin2, LOW); // motor off
        delay(200);
      }
      else if(UltraSensorTwo < 45 && UltraSensorTwo >=30)
      {
        digitalWrite(motorPin2, HIGH); // when greater than 100cm
        delay(100);
        digitalWrite(motorPin2, LOW);
        delay(100);
      }
      else if(UltraSensorTwo < 30)
      {
       digitalWrite(motorPin2, HIGH);
       delay(50);
       digitalWrite(motorPin2, LOW);
       delay(50);
      }
      else
      {
        digitalWrite(motorPin2, LOW);
      }

      Terminal.print("SensorTwo: ");
      Terminal.println(UltraSensorTwo);
    }

    void loop()
    {
    //    Terminal.println("Test");
    //    Emergency();

        SensorHandler();
        //delay(10);
        if (PushButton.isPressed())
      {
        Terminal.println("Button Pressed");
        //delay(100);
            lat = GPS.getLatitude();
            lon = GPS.getLongitude();
            Message1 = String(lat,8);
            Message2 = String(lon,8);

            Message = "I need Help! Google Maps - https://www.google.co.in/maps/place/" + Message1 + "," + Message2;
            Terminal.print("Message Sent");

    //        SMS.send("0819033655",Message);
        delay(3000);
      }
      delay(1000);
    }

The following code is after I fixed by learning BlinkWithoutDelay example but the vibration rate according to the distance seems not right. (When the object is closer, the vibration motor vibrate rate should be faster).

    #define CUSTOM_SETTINGS
    #define INCLUDE_GPS_SHIELD
    #define INCLUDE_SMS_SHIELD
    #define INCLUDE_VIBRATION_SHIELD
    #define INCLUDE_PUSH_BUTTON_SHIELD
    #define INCLUDE_TERMINAL_SHIELD
    #define INCLUDE_MIC_SHIELD

    /* Include 1Sheeld library.*/
    #include <OneSheeld.h>
    #include <string.h>

    // Define Pins for Sensor 1
    #define trigPin1 4
    #define echoPin1 5

    //Define Pins for Sensor 2
    #define trigPin2 6
    #define echoPin2 7

    // Define Pin for VibMotor 1
    #define motorPin1 12

    // Define Pin for VibMotor 2
    #define motorPin2 13

    /* Define a boolean flag. */
    long duration, distance, UltraSensor, UltraSensorTwo;
    //boolean isMessageSent = false;
    unsigned long previousMillis = 0;
    unsigned long interval = 1000;
    float lat;
    float lon;
    String Message;
    String Message1;
    String Message2;
    char latitude[10];
    char longitude[10];

    void setup()
    {
      /* Start communication.*/
      Serial.begin(9600);
      OneSheeld.begin();
      //  PushButton.setOnButtonStatusChange(&Emergency);

      pinMode(trigPin1, OUTPUT);
      pinMode(echoPin1, INPUT);

      pinMode(trigPin2, OUTPUT);
      pinMode(echoPin2, INPUT);

      pinMode(motorPin1, OUTPUT);
      pinMode(motorPin2, OUTPUT);
    }

    void SonarSensor(int trigPin, int echoPin)
    {
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      duration = pulseIn(echoPin, HIGH);
      distance = (duration / 2) / 29.1;
    }

    void SensorHandler() {

      SonarSensor(trigPin1, echoPin1);
      UltraSensor = distance;

      SonarSensor(trigPin2, echoPin2);
      UltraSensorTwo = distance;

      if (UltraSensor <= 60 && UltraSensor >= 45) // Checking the distance, you can change the value
      {
        digitalWrite(motorPin1, HIGH); // motor on
        delay(200);
        digitalWrite(motorPin1, LOW); // motor off
        delay(200);
      }
      else if (UltraSensor < 45 && UltraSensor >= 30)
      {
        digitalWrite(motorPin1, HIGH); // when greater than 100cm
        delay(100);
        digitalWrite(motorPin1, LOW);
        delay(100);
      }
      else if (UltraSensor < 30)
      {
        digitalWrite(motorPin1, HIGH);
        delay(50);
        digitalWrite(motorPin1, LOW);
        delay(50);
      }
      else
      {
        digitalWrite(motorPin1, LOW);
      }

      Terminal.print("SensorOne: ");
      Terminal.println(UltraSensor);

      // For VibMotor Two

      if (UltraSensorTwo <= 60 && UltraSensorTwo >= 45) // Checking the distance, you can change the value
      {
        digitalWrite(motorPin2, HIGH); // motor on
        delay(200);
        digitalWrite(motorPin2, LOW); // motor off
        delay(200);
      }
      else if (UltraSensorTwo < 45 && UltraSensorTwo >= 30)
      {
        digitalWrite(motorPin2, HIGH); // when greater than 100cm
        delay(100);
        digitalWrite(motorPin2, LOW);
        delay(100);
      }
      else if (UltraSensorTwo < 30)
      {
        digitalWrite(motorPin2, HIGH);
        delay(50);
        digitalWrite(motorPin2, LOW);
        delay(50);
      }
      else
      {
        digitalWrite(motorPin2, LOW);
      }

      Terminal.print("SensorTwo: ");
      Terminal.println(UltraSensorTwo);
    }

    void loop()
    {
      //    Terminal.println("Test");
      //    Emergency();
      unsigned long currentMillis = millis();
      if (currentMillis - previousMillis > interval)
      {
        previousMillis = currentMillis;
        SensorHandler();
      }
      if (PushButton.isPressed())
      {
        Terminal.println("Button Pressed");
        lat = GPS.getLatitude();
        lon = GPS.getLongitude();
        Message1 = String(lat, 8);
        Message2 = String(lon, 8);

        Message = "I need Help! Google Maps - https://www.google.co.in/maps/place/" + Message1 + "," + Message2;
        Terminal.print("Message Sent");

        //SMS.send("0819033655",Message);
        //delay(3000);
      }
      //delay(1000);
    }

title: sensor detection is too slow when another feature is added

Answers: 0


body:
I have a strange type of issue: the index of the array doesn't increment and when I print the value from the *serialdata[pointingfinger]* it just gives me an empty space.
This is a state machine (I guess) that should check what is the current char that's being written into the array and its position to avoid searching it later. When we have a finished line it changes the bigger state machine to another mode (that checks if four chars further is the command) when the processing is done it should get back getting the next line.

This is Arduino Leonardo and Serial is the USB and Serial1 is where I send and receive AT commands.

<!-- language-all: lang-cpp -->

    const long interval = 1000;
 static long currentMillis;

 char plussignpoint = 0; //To determine where is the + in +CCLK in the char array

 char serialdata[256] = ""; //Array to store the chars before parsing

 int rdpos = 0;

 int pointingfinger = 0;

 char timeen = 0;
 byte stat0 = 0;
 char futstat0 = 0;
 char searchcharpos = 0;

 char enabled = 0;

 char searchchartype = 0;

 char smsvalid = 0;

 void setup()
 {
   Serial.begin(9600);
   Serial1.begin(9600);
   Serial1.write("ATE0\r");
 }

 void loop() {
  if (millis() - currentMillis >= interval)
  {
    Serial1.print("AT+CCLK?\r"); //ask for the time

    enabled = 1;

    currentMillis = millis();
  }

  if (enabled == 1) {
    if (stat0 == 0) {
   if (Serial1.available () > 0) {
     pointingfinger++;
     serialdata[pointingfinger] = Serial1.read();
     if (serialdata[pointingfinger] == '+') {

    searchcharpos = pointingfinger;
    searchchartype = 1;
    futstat0 = 1;
     }
     else if (serialdata[pointingfinger] == '$') {
    if (smsvalid = 1) {
      searchcharpos = pointingfinger;
      searchchartype = 2;
      futstat0 = 2;
    }
    if (smsvalid = 0) {
      stat0 = futstat0;
      pointingfinger = 0;
    }
     }
     else if (serialdata[pointingfinger] == '\n') {
    stat0 = futstat0;
    pointingfinger = 0;
    enabled = 0;
     }
     else if (serialdata[pointingfinger] == '\r') {
    stat0 = futstat0;
    pointingfinger = 0;
    enabled = 0;
     }
     else {
    stat0 = 0;
    pointingfinger = 0;
     }
   }

   if (pointingfinger == 255) {
     pointingfinger = 0;
     enabled = 0;
   }

    }
  }
 }

**EDIT:** I forgot to include what AT commands it should parse:

    Arduino: AT+CCLK?

    SIM800H: +CCLK: "04/01/01,01:35:31+00"

             OK

title: Serial.read(); and state machine for AT commands

Answers: 1

body:
When checking value of `smsvalid` you use assignment operator `=` instead of comparison operator `==`.

                else if (serialdata[pointingfinger] == '$') {
                    if (smsvalid == 1) {
                        searchcharpos = pointingfinger;
                        searchchartype = 2;
                        futstat0 = 2;
                    }
                    if (smsvalid == 0) {
                        stat0 = futstat0;
                        pointingfinger = 0;
                    }
                }

And also you increment `pointingfinget` prior writing to `serialdata` buffer. This means that the first character will be written at index 1. So the first character serialdata will be zero, which means empty string.

          pointingfinger++;
          serialdata[pointingfinger] = Serial1.read();

There are many issues with your code, I pasted your code to [online gdb c++ compiler](https://onlinegdb.com/HJqeGtapf), so you can play with it and see what is going on.

Those AT state machines aren't easy to finetune on Arduino. I spent a lot of time debugging similar code and found out that the best way is to unit test all possible situations in visual studio or xcode. Arduino is just C++ and if you copy/paste some portions of your code to C++ IDE, after implementing few functions or classes it should work. For example, to make your code working in XCode, I had to implement some dummy Serial1 class and simplify the loop code:

    class _Serial1
    {
        std::string buffer{"OK\r\n"};
    public:
        int available()
        {
            return (int)buffer.size();
        }

        char read()
        {
            char c = buffer[0];
            buffer.erase(0, 1);
            return c;
        }
    } Serial1;

    void loop() {
        if (enabled == 1) {
            if (stat0 == 0) {
                if (Serial1.available () > 0) {
                    pointingfinger++;
                    serialdata[pointingfinger] = Serial1.read();
                    if (serialdata[pointingfinger] == '+') {

                        searchcharpos = pointingfinger;
                        searchchartype = 1;
                        futstat0 = 1;
                    }
                    else if (serialdata[pointingfinger] == '$') {
                        if (smsvalid == 1) {  // ==
                            searchcharpos = pointingfinger;
                            searchchartype = 2;
                            futstat0 = 2;
                        }
                        if (smsvalid == 0) { // ==
                            stat0 = futstat0;
                            pointingfinger = 0;
                        }
                    }
                    else if (serialdata[pointingfinger] == '\n') {
                        stat0 = futstat0;
                        pointingfinger = 0;
                        enabled = 0;
                    }
                    else if (serialdata[pointingfinger] == '\r') {
                        stat0 = futstat0;
                        pointingfinger = 0;
                        enabled = 0;
                    }
                    else {
                        stat0 = 0;
                        pointingfinger = 0;
                    }
                }

                if (pointingfinger == 255) {
                    pointingfinger = 0;
                    enabled = 0;
                }

            }
        }
    }

And the compiler immediatelly pointed me at the incorrect assignments and also I was able to debug the code step by step and see what is happening inside.

In my situation I was interfacing SIMCOM900 gprs module and I made a state machine that allows me to write code like this:

    virtual void Program()
    {
        switch (Pc())
        {
            case 0: _ASSERT(strlen(mApn)>0);
                    Stream() << "AT+CSTT=\"" << mApn << "\",\"\",\"\"\r\n";
                    break;
            case 1: Expect("OK\r\n");
                    if (Expect("+CME ERROR")) { Error("CME Error when attaching apn"); Return(false);}
                    if (Timeout(25000)) Return(false);
                break;
            case 2: Stream() << "AT+CIICR\r\n"; break;
            case 3: Expect("OK\r\n");
                    if (Timeout(15000)) Next(); break;
            case 4: Stream() << "AT+CIFSR\r\n"; break;
            case 5: if (ReadIpAddress()) Next();
                    if (Timeout(2000)) Return(false); break; // longer?
            default: Return(true);
        }
    }

Here is a bit older version of it:
https://gist.github.com/gabonator/88b80d9c6b16d699d6f4234ebc3a2587