body:
I have 8 sets of 8 push buttons. There is a Teensy and a demultiplexer. The demultiplexer has 8 outputs. When an output is selected it is pulled low. Each output is connected to a group of 8 push buttons. The 8 push buttons are then connected to 8 pullup inputs on the Teensy.

Each group of 8 push buttons is connected to a unique demultiplexer output, but all the push buttons are connected to the same 8 inputs on the Teensy. That is, push button #1 in group 1 shares a Teensy input with push button #1 in group 2. The push buttons are isolated from each other with diodes.

I'm using `bounce.h` for debouncing. It looks for rising and falling edges.

The problem is this:

- Push button #1 in group #1 is pressed, pulling that input low, causing a falling edge to be detected. This is good.
- The demultiplexer shifts to group #2, where the #1 button hasn't been pressed, and thus is high.
- Because both #1 buttons in group #1 and #2 share the same input line, the Teensy sees this change as a rising edge. This is undesired.

What is the better approach to this?

Thanks,

Dan

title: Avoiding false rising and falling edge when using demultiplexer

Answers: 2

body:
To do multiplexing with bounce.h you will need one bounce object *per button*. That's 64 bounce objects for an 8x8 matrix.

Then you only want to update the bounce objects *for the group you currently have active*.

That is:

1. Switch to group 1.
2. Update objects 1-8
3. Switch to group 2
4. Update objects 9-16
5. ... etc ...

You need one object per button so that the internal data can track the state of that specific button, and you only update the 8 objects for the currently selected group otherwise the objects that aren't associated with that group will get confused by incorrect data.

body:
> What is the better approach to this?

write your code so it debounces each pin / group of pins separately.

looks like your code used global / static variables.


body:
I had an Arduino UNO (ATmega168) standalone working, but I need more pins, and I decided to use the ATmega2560, I was searching for some schematics, and none of them shown an ATmega2560 standalone, only the full Arduino, with the FTDI, power transformers... etc integrated. So taking parts from those designs, I made this, but I don't know if it's enough or I need Something more:
[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/eQ5n1.png
Note: VCC2 is connected to 5V.

title: Arduino MEGA2560 Standalone

Answers: 2

body:
You need more decoupling capacitors - one per VCC and AVCC pin, plus a larger (10µF) for the whole chip.

You need a pullup resistor (and maybe button) on RESET.

body:
1. check the datasheet;

2. I would put a pull-up on the reset pin, plus a small capacitor;

3. crystal + capacitors as optional;

4. AVCC to VCC with filtering, if you need good analog performance;

5. separate Vbat domain, if it has one.

...


body:
I would like to use OTA in some of my less accessible esp's. I am using the examples/BasicOTA and BasicOTA_test. My esp is a -01 model with 1Mb of flash.

I upload the BasicOTA to my esp through the COM port, then upload the BasicOTA_test over WiFi.  Everything appears to go OK, but the test sketch doesn't run until I press reset on the esp.

If I upload BasicOTA over the com port then upload a simple blink sketch over WiFi without the OTA code, it uploads fine then runs without a reset.  But then, I can't upload over WiFi anymore.

If I have to hit reset every time I upload a new sketch that contains the OTA code, then why bother?

Tips would be appreciated.

title: ESP needs a reboot after wifi OTA flash

Answers: 2

body:
I've done some research and this appears to be a common problem while using OTA to update the ESP8266. In fact, this bug has been reported on their [GitHub][1] and it's due to the watchdog timer resetting after the ESP8266 is flashed via OTA.

It appears the problem can be solved by manually resetting (once) after you upload it via serial BEFORE you can upload it via OTA. After that, you shouldn't have any problems.

  [1]: https://github.com/esp8266/Arduino/issues/2478

body:
You can add `ESP.restart()` in the following line to make it restart.

    ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
    ESP.restart();
    });

Now you can upload code each time without hitting reset.


body:
I can't find any information that relates to my problem. The few things I did find confused me (I'm quite new to this).

I'm trying to flash 2 sequences of 4 lights at the same time. I can get 1 set flashing but I don't know how to run other sequences at the same time. My probably laughable attempt at the code is below:

    int led1 = D0;
    int led2 = D1;
    int led3 = D2;
    int led4 = D3;
    int led5 = D4;
    int led6 = D5;
    int led7 = D6;
    int led8 = D7;

    void setup() {
      setupPart1();
      pinMode(led1, OUTPUT);
      pinMode(led2, OUTPUT);
      pinMode(led3, OUTPUT);
      pinMode(led4, OUTPUT);
      setupPart2();
      pinMode(led5, OUTPUT);
      pinMode(led6, OUTPUT);
      pinMode(led7, OUTPUT);
      pinMode(led8, OUTPUT);
    }

    void loop() {
      loopPart1();
      digitalWrite(led1, HIGH);
      delay(500); // delayed for half a second
      digitalWrite(led1, LOW);
      digitalWrite(led2, HIGH);
      delay(500); // delayed for half a second
      digitalWrite(led2, LOW);
      digitalWrite(led3, HIGH);
      delay(500); // delayed for half a second
      digitalWrite(led3, LOW);
      digitalWrite(led4, HIGH);
      delay(500); // delayed for half a second
      digitalWrite(led4, LOW);
      loopPart2();
      digitalWrite(led5, HIGH);
      delay(500); // delayed for half a second
      digitalWrite(led5, LOW);
      digitalWrite(led6, HIGH);
      delay(500); // delayed for half a second
      digitalWrite(led6, LOW);
      digitalWrite(led7, HIGH);
      delay(500); // delayed for half a second
      digitalWrite(led7, LOW);
      digitalWrite(led8, HIGH);
      delay(500); // delayed for half a second
      digitalWrite(led8, LOW);
    }

title: Particle Spark (Arduino) How to flash 2 LED sequences at the same time?

Answers: 2

body:
I cover this exact question in my web page: <http://www.gammon.com.au/blink>

Example code that blinks two LEDs at different rates:

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

    // Which pins are connected to which LED
    const byte greenLED = 12;
    const byte redLED = 13;

    // Time periods of blinks in milliseconds (1000 to a second).
    const unsigned long greenLEDinterval = 500;
    const unsigned long redLEDinterval = 1000;

    // Variable holding the timer value so far. One for each "Timer"
    unsigned long greenLEDtimer;
    unsigned long redLEDtimer;

    void setup ()
      {
      pinMode (greenLED, OUTPUT);
      pinMode (redLED, OUTPUT);
      greenLEDtimer = millis ();
      redLEDtimer = millis ();
      }  // end of setup

    void toggleGreenLED ()
      {
       if (digitalRead (greenLED) == LOW)
          digitalWrite (greenLED, HIGH);
       else
          digitalWrite (greenLED, LOW);

      // remember when we toggled it
      greenLEDtimer = millis ();
      }  // end of toggleGreenLED

    void toggleRedLED ()
      {
       if (digitalRead (redLED) == LOW)
          digitalWrite (redLED, HIGH);
       else
          digitalWrite (redLED, LOW);

      // remember when we toggled it
      redLEDtimer = millis ();
      }  // end of toggleRedLED

    void loop ()
      {

      // Handling the blink of one LED.
      if ( (millis () - greenLEDtimer) >= greenLEDinterval)
         toggleGreenLED ();

      // The other LED is controlled the same way. Repeat for more LEDs
      if ( (millis () - redLEDtimer) >= redLEDinterval)
        toggleRedLED ();

    /* Other code that needs to execute goes here.
       It will be called many thousand times per second because the above code
       does not wait for the LED blink interval to finish. */

    }  // end of loop

body:
This kind of problem (doing several things in parallel) is frequent enough to merit a more elegant solution. While projects like this are excellent ([Tasks: A Time-Triggered Scheduler for Arduino][1]), I can't get it working.

I wrote this minimal self-contained example of how to do two things simultaneously. It will blink the built-in LED and write "*" to the serial monitor:

    --- Task Scheduler ---
    Runtime in SS:MMMM
    10:9 **********
    110:64 **********
    210:89 ***

This is the sketch. Study it and adapt it to your own problem:

    /*
     * Task Scheduler for Arduino/ESP2866 by Look Alterno - 2017/8/9.0
     * Show how to execute tasks at regular intervals without using delay() or interrupts.
     * For educational purposes only; not production ready.
     *
     * This sketch have two example tasks running:
     * - Task 1 blinks the builtin led every second
     * - Task 2 write lines with run time and one "*" every ten seconds in the Serial Monitor.
     * Tasks are run in sequence, so keep them short.
     * No interrupts are used; you have to call runTasks() in each loop() pass.
     */

    // Definition: Every task must receive nothing and return nothing.
    typedef void (*fcnptr)();
    //  Here we must declare our task functions (required by C)
    void fcnBlink();      // Task 1
    void fcnSerial();     // Task 2
    //  Add more tasks here.

    //  The interval between fcnBlink execution. Adjustable between 25 to 250 ms.
    //  LED still will blink every second at the same freq (250ms on, 750ms off).
    #define BLINK_LEN 25

    //  The task list
    struct {
     uint8_t  runnable;  // The task is runnable (true/false).
     uint32_t start;     // Next start time for the task (ms).
     uint32_t interval;  // Execution interval in ms.
     fcnptr fcn;          // Function to execute.
    } taskList[] = {
     {true, 0, BLINK_LEN,fcnBlink}, // Execute fcnBlink every 25 ms, blink LED every second
     {true, 0, 10000,    fcnSerial} // Execute fcnSerial every 10 seconds.
     // Here you can add other tasks.
    };
    // The number of task in our task list.
    const uint8_t nTasks = sizeof(taskList) / sizeof(taskList[0]);

    void setup() {
      // Just a standard setup. Nothing is required for task execution.
      Serial.begin(9600);
      while(!Serial) {};
      randomSeed(analogRead(A0));
      Serial.println("");
      Serial.println("--- Task Scheduler ---");
      Serial.println("Runtime in SS:MMMM");
      pinMode(LED_BUILTIN, OUTPUT);
    }

    void loop() {
      // Here you write your processing code (without using delay())
      // --- Start of your code.
      // Some random delays to simulate work
      // Just a bit less than half fcnBlink interval length.
      // You can change BLINK_LEN to test other scenarios.

      delay(random(1, BLINK_LEN / 2));

      // --- End of your code
      runTasks();  // At the end of the loop(), but can be anywhere.
    }

    /*
     * Check the task list and execute them.
     * Sequence of execution guaranteed: tasks could be delayed,
     * but not omitted or executed of order.
     */
    void runTasks() {
      uint32_t now = millis();
      for(uint8_t i=0; i < nTasks; i++) {
        if(taskList[i].runnable) {
          uint32_t diff = now - taskList[i].start; // ms since last execution.
          if(diff >= taskList[i].interval) {
            taskList[i].start = now; // Have to be the same for all task, to keep sync.
            taskList[i].fcn();
          }
        }
      }
    }

    /*
     * Blink the led.
     */
    void fcnBlink() {
      // Called every 25 milliseconds. Turn on the led in the
      // 10 first passes and turn off in the next 30.
      static uint8_t count = 0;
      count++;
      if(count <= 250 / BLINK_LEN) {
        digitalWrite(LED_BUILTIN, HIGH);
      } else {
        digitalWrite(LED_BUILTIN, LOW);
        if(count == 1000 / BLINK_LEN) {
          count = 0;
        }
      }
    }

    /*
     * Print run time (s) and a row of ten "*"
     */
    void fcnSerial() {
      static uint8_t count = 0;
      count++;
      // Print run time in seconds:miliseconds at the start of each line
      if (count == 1) {
        uint32_t now = millis();
        Serial.print(now/1000);
        Serial.print(":");
        Serial.print(now00);
        Serial.print(" ");
      }
      Serial.print("*");
      if(count == 10) {
        Serial.println();
        count = 0;
      }
    }

  [1]: https://chrisbarlow.wordpress.com/2016/04/27/tasks-a-time-triggered-scheduler-for-arduino/


body: I want to run more stepper motors and would like to know if there is a way to connect the Arduino and the ESP8266 NodeMCU together for more functioning.

title: Connecting Arduino to the ESP8266

Answers: 1

body:
Absolutely. I'll use the Arduino UNO and the ESP8266-01 WiFi module as an example:

<hr>

![ESP8266 to Arduino Uno][1]

 1. The ESP8266 works with 3.3V and not 5V, so you need to connect the 3v3 pin on the Arduino to the VCC and CH_PD pins on the ESP8266.
 2. Connect the GND pin on the Uno to the GND pin on the ESP.
 3. Connect the RESET pin on the Uno to GND. Grounding the RESET pin
    effectively causes your Arduino to work as a dumb USB to serial
    connector (which is what we want to talk to the ESP8266).
 4. Connect the CH_PD pin on the ESP8266 to the 3.3V line
 5. Connect the RXD pin on the Arduino Uno to the RX pin of the ESP8266.
 6. Connect the TXD pin on your Arduino Uno to the TX pin of the
    ESP8266.

Normally, when you want two things to communicate over serial, you'd connect the TX pin of one to the RX of the other (send --> receive). In this case, however, the Arduino isn't talking to the ESP8266; the computer is talking to the ESP8266 via the Arduino.

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


body:
First of all, I would like to apologize for posting this error once again to this community. However, I have been studying articles for last many days to resolve this error. Unfortunately, I did not get any solution which could resolve my problem.

Below is the error which I get when uploading a sketch (even the example sketch):

warning: espcomm_sync failed
error: espcomm_open failed
error: espcomm_upload_mem failed
error: espcomm_upload_mem failed

Here are the connections:
Vcc - 3.3V
RST - 3.3v
CH_PD - 3.3v
Tx - Rx
Rx - Tx
GPIO0 - GND
GND - GND

I tried various combinations like Tx to Tx, Rx to Rx, pulling off GPIO0. Pulling off reset and ch_pd. Supplying external power source, supplying power directly from Arduino using 3.3V. Supplying power from Arduino 5V using an LD33V regulator. I have even tried uploading the code using USB to TTL. But every time I get exactly the same error.

title: ESP8266 error: espcomm_upload_mem failed while uploading sketch

Answers: 2

body:
Well, first of all you should make sure that the voltage on both Tx and Rx pins of the ESP8266 is 3.3V (the Tx and Rx voltage on Arduino is 5V). Personally, I've never succeded in using an Arduino to program the ESP (even though there are plenty of examples of this setup in the web). After a while, I just gave up and bought a converter to do the job for me (it's totally worth it).

Even so, I got this error a few times. You must keep two things in mind:

1. In operation mode, the CH_PD pin must be connected to 3.3V, but it won't do any harm to let it connected during the flashing, so I just soldered a wire between these two pins to make things easier.

2. In flashing mode, GPIO0 must be connected to GND. It won't work otherwise. I strongly recommend you using a usb converter for this, and only connect it to your computer once GPIO0 has been set to GND. This has solved this issue for me, in fact I even soldered a switch on my converter between GPIO0 and GND.

Hope this answers your question.

EDIT: Here are some photos of the setup

[![ESP-01 with the wire soldered between CH_PD and VCC][1]][1]

[![USB to Serial converter for the ESP-01 (and a switch poorly soldered on the back)][2]][2]

  [1]: https://i.stack.imgur.com/GClra.jpg
  [2]: https://i.stack.imgur.com/a3bnv.jpg

body: Please verify you're choosing the right board -Generic ESP for ESP-01.


body: I have 11 Adafruit Feather 32u4 Bluefruit LE devices. I want to vibrate my devices using a signal through an app. Is there any signal (Code from app like 0x56-NeoPixel checking, 0x43-clear color) or any sketch? Please provide me.

title: How to vibrate Adafruit Feather 32u4 Bluefruit LE device?

Answers: 1

body:
The Adafruit Feather you are talking about is a small format Arduino compatible with BlueTooth Low Energy, USB and battery connector. It doesn't have any way to vibrate without adding external hardware.

[![Adafruit Feather][1]][1]

Now, having Bluetooth in the package means that it can comunicate with an Android Phone, and can send/receive commands, post results, anything you need.

We don't provide sketchs for particular projects. You must learn how to program Arduino and Android. Follow the examples and tutorials widely available in the Web.

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


body:
I am using the Leonardo board with the Adafruit Motor Shield v2, 2 steppers and the Yun Shield. The yun shield and steppers all run harmoniously, however, as soon as I do Bridge.begin() and anything that accesses the Yun shield Bridge library to access the console, the steppers stop running. Is this to be expected and are there any solutions?

Thanks

title: Adafruit Motor Shield and Bridge Library for Yun Shield

Answers: 1

body:
Looking at Bridge.begin() description [here](https://www.arduino.cc/en/Reference/YunBridgeBegin)
 you can see this is blocking function.

>begin() is a blocking function. Once you call Bridge.begin(), nothing else will happen in your sketch until it has completed. This process takes approximately three seconds.


body:
    #include<ESP8266WiFi.h>
    #include<SPI.h>
    #include "MFRC522.h"
    #define RST_PIN D3
    #define SS_PIN D4
    MFRC522 mfrc522(SS_PIN, RST_PIN);

    void setup() {
      Serial.begin(9600);
      SPI.begin();
      mfrc522.PCD_Init();
    }

    void loop() {
      if ( !mfrc522.PICC_IsNewCardPresent() ) {
        delay(50);
        return;
      }

      if ( !mfrc522.PICC_ReadCardSerial() ) {
        delay(50);
        return;
      }

      Serial.print(F("Card UID: "));
      dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
      Serial.println();
    }

    void dump_byte_array(byte *buffer, byte bufferSize) {
      for ( byte i = 0; i< bufferSize; i++ ) {
        Serial.print(buffer[i] < 0x10 ? " 0" : " ");
        Serial.print(buffer[i], HEX);
      }
    }

I am able to get the unique ID of the RFID tag & card. But now the problem is that how can I send the unique ID from ESP8266 to the firebase realtime database.

The hexadecimal values that are generated are they unique? or they are something else? Because in some youtube videos I saw people using only numbers as a unique ID from RFID to distinguish between 2 cards or tags.

The wifi connection and firebase auth all are set peoperly ony the unique id number is the problem.

title: Data from RC522 to firebase real time database

Answers: 1

body:
The "UID" of the card is supposed to be unique. Most RFID chips also have blocks of readable/writable space, but some systems do only use the UID from the chip as the complete identifier.

It may be that you come across RFID chips that have utilized random bytes as the UID, in which case there is a chance of duplication. Depending on the number of possible cards to be used in your system, this may or may not be a big worry for you. If it is a big worry, you may want to use the actual memory on the RFID chips to store your user's ID data.

Regarding HEX versus numbers -- Hexadecimal is just one way to represent numbers.
Your code:

    Serial.print(buffer[i], HEX);

tells the print command to take the byte at `buffer[i]` and print its value in Hexadecimal format. You could replace `HEX` by `DEC` to see the base-10 (decimal) value instead. The actual bits underneath would be the same -- it's just one way to display/represent the underlying number.

One byte (8 bits) of data can be represented in decimal as the numbers 0 through 255. The same byte can be represented in Hexadecimal as 0x00 through 0xFF. ('0x' is one way to denote that what follows are hexadecimal values.) Each 'digit' in hex represents 4 bits of data (0-15 in decimal), so 2 hex digits can represent 16^2 values (256 decimal), hence 0-255 as the 1-byte range of decimal values.

(That explanation assumes un-signed types.)


body:
Am working on a wearable using Arduino Micro and I am thinking it would be cool if I can trigger some events in my smartphone using Arduino. Say for example a button press in my wearable should trigger events like opening music player, reducing/increasing volume or opening some Android Apps.

Sorry for providing just a rough view of the idea. So I want to know to perform similar actions listed above, Do I need to create a Android app for it? I don't find any readymade app that fits my requirement. Or Is there any feasible way to achieve what I need without having to break my head with Android developing?

Thanks in advance.

title: Triggering actions in Android smartphone via Bluetooth from Arduino

Answers: 0


body:
I'm trying to make an interactive installation where I have 6 pressure pads that each control an Air Fan. The pressure sensors ideally will be on chairs.

I would like the changes in pressure to change the speed of the Air Fans.

What is the easiest way for me to do this? Can I do it with just an Arduino?

I haven't bought anything yet as I'm assessing what the best route is.

title: Using Multiple identical sensors - Beginner

Answers: 3

body:
If you mean [this][1] kind of sensor:

The sensor is a simple microswitch with mechanical pressure switching point, which means your Arduino just needs to monitor 6 digital inputs. That is entirely possible.

The sensors would have one side connected to ground, and the other to a GPIO pin on the Arduino, with a pull-up resistor to 5V. Your code should just check each of the 6 GPIO inputs. If the pressure sensor is tripped, the input would be `LOW`, otherwise `HIGH`.

  [1]: https://www.aventics.com/de/en/pneumatics-shop/series-pm1-pgr.256289

body:
Yes one Arduino have enough in and out-put to make your project fly.

The sensor that would detect pressure sensor is called "Force Sensitive Resistor".

Example: http://www.ladyada.net/make/midisense/forcesensors.html

They need some amplifier circuitry that could adapt the sensors low output signal to an Arduino analog input.

And to make six digital output that uses PWM to control the FAN's is also quite straight forward. but may also be subject to some driver circuit.

body:
> What is the easiest way for me to do this?

you have to figure out how those sensors output their pressure measurements. if it is analog, you will need 6 analog pins, or have to a way to mux 6 analog inputs.

if it is digital, you will have to figure out how - 6 parallel output or 6 serial output; 6 GPIO digital or 6 numerical digital, ......

basically, do your homework first so others can help you help you.


body:
I'm trying to control a series of LEDs using an IR remote. I have a problem when I try to play a sequence with the LEDs where they all light up in a line and turn off accordingly. I loop through the sequence and I am trying to make it so the instant I press a button on the remote it breaks out of that sequence. The issue lies in the Flash(); function, I think. What can I do?

    #include <boarddefs.h>
    #include <IRremote.h>
    #include <IRremoteInt.h>
    #include <ir_Lego_PF_BitStreamEncoder.h>

    int recvPin = 11;
    IRrecv irrecv(recvPin);
    decode_results results;

    #define BUTTON_ON 0xF076C13B    // codes for different buttons on the remote
    #define BUTTON_OFF 0xFF9186B7
    #define BUTTON_R 0xE5CFBD7F
    #define BUTTON_G 0x8C22657B
    #define BUTTON_B 0x2A89195F
    #define BUTTON_FLASH 0x35A9425F

    int rLED = 5;
    int gLED = 4;
    int bLED = 3;
    int stR = LOW;  // intital state of red LED
    int stG = LOW;  // intital state of green LED
    int stB = LOW;  // initial state of blue LED
    int flash = false;

    void setup() {
      Serial.begin(9600);   // Status message will be sent to PC at 9600 baud
      pinMode(rLED, OUTPUT);
      pinMode(gLED, OUTPUT);
      pinMode(bLED, OUTPUT);

      irrecv.enableIRIn();
    }

    void Flash() {    // flashing function
      while (flash == false) {
        digitalWrite(rLED, LOW);
        digitalWrite(gLED, LOW);
        digitalWrite(bLED, LOW);
        digitalWrite(rLED, HIGH);
        delay(75);
        digitalWrite(gLED, HIGH);
        delay(75);
        digitalWrite(bLED, HIGH);
        delay(75);
        digitalWrite(rLED, LOW);
        delay(75);
        digitalWrite(gLED, LOW);
        delay(75);
        digitalWrite(bLED, LOW);
        delay(75);
        stR = LOW;
        stG = LOW;
        stB = LOW;
        if (results.value == BUTTON_OFF)    // attempting to make it so when i press the OFF button on the remote,
        {                                   // the loop breaks/stops and I can go back to pressing any button on
          break;                            // the remote
        }
      }
    }

    void loop() {
      if (irrecv.decode(&results))
      {
        if (results.value == BUTTON_ON)
        {
          digitalWrite(rLED, HIGH);
          digitalWrite(gLED, HIGH);
          digitalWrite(bLED, HIGH);
          stR = HIGH;
          stG = HIGH;
          stB = HIGH;
        }
        if (results.value == BUTTON_OFF)
        {
          digitalWrite(rLED, LOW);
          digitalWrite(gLED, LOW);
          digitalWrite(bLED, LOW);
          stR = LOW;
          stG = LOW;
          stB = LOW;
        }
        if (results.value == BUTTON_R)
        {
          digitalWrite(rLED, !stR);
          stR = !stR;
        }
        if (results.value == BUTTON_G)
        {
          digitalWrite(gLED, !stG);
          stG = !stG;
        }
        if (results.value == BUTTON_B)
        {
          digitalWrite(bLED, !stB);
          stB = !stB;
        }
        if (results.value == BUTTON_FLASH)
        {
          Flash();    // calling flash func
        }
        irrecv.resume();
      }
    }

title: Breaking out of while loop using IR remote input

Answers: 1

body:
Replace delay with millis in `Flash()`.

You do this by making every delay it's own state and give each state a number. Then inside `flash` you check which state you are in to set the LEDs and how long you have been in it to trigger the next state.

    boolean flashing = false;
    int flashingState = -1;
    long nextFlashingState = 0;

    void Flash() {    // flashing function
      if(!flashing ){
        flashingState =-1;
        return;
      }

      long ms = millis();
      switch(flashingState ){
      case -1:
        flashingState =0;
        nextflashingState = ms+75; //init "timer"
        //fallthrough
      case 0:
        digitalWrite(rLED, LOW);
        digitalWrite(gLED, LOW);
        digitalWrite(bLED, LOW);
        digitalWrite(rLED, HIGH);
        if(nextflashingState < ms){
            flashingState =1;
            nextflashingState +=75;
        }
        break;
     case 1:
        digitalWrite(gLED, HIGH);
        if(nextflashingState < ms){
            flashingState = 2;
            nextflashingState +=75;
        }
        break;
     case 2:
        digitalWrite(bLED, HIGH);
        if(nextflashingState < ms){
            flashingState = 3;
            nextflashingState +=75;
        }
        break;
      case 3:
        digitalWrite(rLED, LOW);
        if(nextflashingState < ms){
            flashingState = 4;
            nextflashingState +=75;
        }
        break;
      case 4:
        digitalWrite(gLED, LOW);
        if(nextflashingState < ms){
            flashingState = 5;
            nextflashingState +=75;
        }
        break;
      case 5:
        digitalWrite(bLED, LOW);
        if(nextflashingState < ms){
            flashingState = 0;
            nextflashingState +=75;
        }
        break;
      }
    }

I used state `-1` as the init state to start the timer, the case block will fall through to the next case. The `millis()` function returns the number of milliseconds since the arduino booted up (it overflows every ~1.5 months). So when I start a timer I set the the `nextFlashingState` to the time when it should start the next state.

Then in loop you call it every time.

    void loop() {
      if (irrecv.decode(&results))
      {
        if (results.value == BUTTON_ON)
        {
          digitalWrite(rLED, HIGH);
          digitalWrite(gLED, HIGH);
          digitalWrite(bLED, HIGH);
          stR = HIGH;
          stG = HIGH;
          stB = HIGH;
        }
        if (results.value == BUTTON_OFF)
        {
            flashing =false;
          digitalWrite(rLED, LOW);
          digitalWrite(gLED, LOW);
          digitalWrite(bLED, LOW);
          stR = LOW;
          stG = LOW;
          stB = LOW;
        }
        if (results.value == BUTTON_R)
        {
          digitalWrite(rLED, !stR);
          stR = !stR;
        }
        if (results.value == BUTTON_G)
        {
          digitalWrite(gLED, !stG);
          stG = !stG;
        }
        if (results.value == BUTTON_B)
        {
          digitalWrite(bLED, !stB);
          stB = !stB;
        }
        if (results.value == BUTTON_FLASH)
        {
            flashing =true;
        }
        irrecv.resume();
      }

      Flash();
    }


body:
I have an ATMEGA 2560 platform running HIDUINO and a sketch based on the stock MIDI library. I'm intending to use it to convert Linear Timecode (LTC) to MTC. Got a long way through the project - LTC decoding working fine, timer configuration OK, and Midi output working fine. It's just that as soon as I try and generate MTC messages, they are being dropped before they land on the computer USB interface.

Equipment to hand: Macbook Pro running El Cap/Reaper and Protools., ATMEGA2560 MEGA R3 (With 16u2 for HIDUINO) and small audio interface circuit.

Using Timer 4 for LTC Decoding and Timer 5 for MTC generation (4 messages per LTC Frame).

Midi Monitor on the OSX box.

Sees Note on/Note off packets quite happily, but no MTC messages are registering.

I do note the TX LED is active during MTC Message generation, indicating that the sketch is actually generating messages and sending them to the 16u2 chip.

Specifically, my question is how do I get the MTC messages through HIDUINO into the computer?

https://pastebin.com/pAXyq04s

title: Midi Timecode Fails to Send

Answers: 2

body:
The HIDUINO library supports only some MIDI message correctly; most System Common and System Real-Time message are buggy, and SysEx messages are not handled at all.

Try some other library, e.g., [mocoLUFA](https://github.com/kuwatay/mocolufa).

body:
If you clone my fork of the code, I have got this working.
https://github.com/mwr9uk/mocolufa

I have generated a pull request to merge it with mainline.


body:
I have a bluetooth HM-10 configured in central mode. I have successfully connected it to another bluetooth device (a hexiwear bluetooth wearable). The problem now is that the hexiwear requires me to provide a 6 digit pin before it will bond with my HM-10.

Would anyone know the AT command that I could use to send the 6 digit pin from the HM-10 to the hexiwear?

Thank you.

title: Bluetooth HM-10 in central mode bonding with another bluetooth device

Answers: 1

body:
The manual for the HM-10 can be found [here](ftp://imall.iteadstudio.com/Modules/IM130614001_Serial_Port_BLE_Module_Master_Slave_HM-10/DS_IM130614001_Serial_Port_BLE_Module_Master_Slave_HM-10.pdf).

Page 11 has the AT command you are interested in: `AT+PIN`:

    AT+PIN123456
    OK+Set:123456

By default the PIN is `000000`.

(The manual is quite vague about the role of that command, so I assume since it is the only reference to PIN codes that it does what you require).


body:
I'm looking to read data from sensors using an ArduinoUNO in a greenhouse and then access the data wirelessly through a router. Hopefully through a webpage. No need for internet access, just local network access is good enough.

Preferably the only components involved would be the Arduino, the circuit, and a router with OpenWRT/DD-WRT to host the webpage and broadcast the network.

Pretty new to Arduinos in general, would this be possible? And how? The following 2 links from instructables.com seem to be the most relevant, can anyone give their input on how similar/different is this to my project?

http://www.instructables.com/id/PART-1-Send-Arduino-data-to-the-Web-PHP-MySQL-D3js/

http://www.instructables.com/id/Getting-Arduino-data-to-a-web-Page/

title: Broadcasting parallel data from Arduino using router

Answers: 1

body:
Use a NodeMCU (ESP8266 based) because it have WiFi included. It can work as a light web server. You can serve HTML, but not large files (like many .js).

Instead of HTML you can use [websockets][1] to get only data from NodeMCU and all the other files (html, js, images) from another bigger server. Websockets is fast, but you still have to deal with .html, .css, .js and other files in your webserver.

If you want something even easier and lighter, take a look at [MQTT][2], which was developed with IoT in mind.

There is lot of MQTT client for Android/Iphone/PC/Mac. You use your client to send data and commands to your NodeMCU. No need to program anything here; you simply construct a visual interface by adding controls (buttons, meters) to a blank slate. No brains job.

You will need a *broker*, a server that acts as a relay, receiving commands/data from your Android and resending it to your NodeMCU. And your NodeMCU can publish temp, humidity, light levels and other data to your broker. You can use multiple client at once. There is no limit.

Your broker can be an public Internet broker (many) or a private one in your LAN. There is many brokers available for different platforms. You can run one in your smartphone or any old PC. [Mosquitto][3] is a free one.

Depending on your configuration, you will be even able to access your green house from Internet and look at your girls from far away.

[![IoT][4]][4]

  [1]: https://en.wikipedia.org/wiki/WebSocket
  [2]: https://en.wikipedia.org/wiki/MQTT
  [3]: https://mosquitto.org/
  [4]: https://i.stack.imgur.com/8NRpJ.png


body:
i made a project with arduino in wich I used arduino to activate 18 n-ch mosfet with PWM. I used the softPWM library to use PWM in 18 output pins, I used a nano v3.

The question is about the maximum current a single pin (and a group) can handle. A raw info can be found here http://www.pighixxx.com/test/wp-content/uploads/2014/11/nano.png and it's a 20mA/pin and 200mA/group but it's not explained if that current is a peak current or an average current.

Increasing the load resistor will case a smaller peak current but will increase the time in wich the mosfet is resistive (hence it will heat up the mosfet). Considering that the pwm frequency is lower than the one defined by the resistor-mosfet, the average drained current is related to the PWM frequency and to the mosfet capacitor (NOT to the load resistor).

Is the current defined as maximum peak current or as continuous current (and which is a typical peak time for the CPU)?

Mr google gives me different and contradictory informations, i found people that uses PWM without load resistors and people that limit the peak current to 20mA. In my project i limited the maximum current to 50mA so I'm sure to have the worst performance i can have keeping the risk of burning my small friend.

Thanks

title: PWM output maximum current

Answers: 0


body:
My project is to have a 12V solar LED strip lighting system throughout my apartment. This has 6 individual lights, with 5 white and 1 RGB = 8 channels.

I've got the whole setup working on my breadboard. Now it's time to transfer it to a "live" setup. Since it's my first such project, I'm looking for any and all recommendations on cabling and connectors to deal with reliability, isolation, modularity, aesthetics and of course safety.

Schematically, it all looks something like this

    solar panel------\
                      charge controller--5v regulator--arduino--mosfets x 8--\__lights
    12v battery_fuse_/                  \____________________________________/

So I have questions such as:-

 1. should I use a prototype shield, or a discrete pcb?
 1. do the MOSFETs (RFP30N06LE) need a heatsink, and any recommended unit?
 1. what connectors are recommended?
 1. any suggestions on box/packaging for the above?
 1. wire gauge? Maximum run is 4m to the furthest light.

And any other hints, tips and suggestions greatly appreciated. Bonus appreciation for amazon links to the parts :-)

update
The breadboard is simply the mosfets, each with a current limiting resistor on the gate. The lights range from 8W to 40W. I will generally have them dimmed using PWM.

title: Advice on cabling, packaging and connectors for 12v light project

Answers: 1

body:
generic DC connector advice:

avoid the use of connectors which connect serially, like headphone jacks. you make strange combinations while plugging in

avoid connectors which do not latch, like headphone jacks

in a system like yours, with stages and signal processing in between, use different connectors for each phase, so you can not get it wrong

use connectors that can not be connected backwards for DC. I prefer:

Hopkins 47965 2-Pole Flat Extension for raw solar power.Not because    it's a great connector, but because it's common in low power solar

 - Anderson Power Poles for regulated DC power. you can secure them
   together with a tie wrap; you can't connect them backwards without
   doing things that are obviously counter intuitive.
 - Fuel injection    connectors from Autozone for signal wires. they got
   a million of    them, they are made for DC at useful current levels
 - Trailer    connectors for multiple lead serious power.
 - XLR connectors can be    found from 3 to 6 pins, and you can't jam a
   5 pin into a 6 pin, so    you can't cross connnect

keep things dummy proof.


body:
I want to calculate the displacement of the Arduino 101 board compared to the starting point (only in the x direction so far).

In below data I'm swinging the board multiple times in circles around my laptop and then putting it back at the origin a few seconds later.

Regardless if 1ms-100ms between the loops, the numbers show no sign of the board returning to the origin. I've calibrated the accelerometer x-axis as closely as possible.

[![Results from swinging][1]][1]

Am I doing something wrong in deriving the acceleration/velocity/distance, or is this the level of compounding error to expect?

If so, can combining gyro data correct acceleration (thought it mainly worked the other way around)?

I have a GPS meant for correcting position but was hoping any drift wouldn't be this quick.

EDIT: I was incorrect re. use of gyro data; the attitude of the board, which was not consistent in my swings, will effect the acceleration output. Gyro data can be used to calculate and "cancel out" this gravitational impact, and get a more accurate (linear) acceleration (http://www.cl.cam.ac.uk/research/dtg/www/files/publications/public/abr28/ojw28_thesis.pdf). Will report back in a few days.

Code:

    #include "CurieIMU.h"

    float gravity = 9.80665; // to convert G forces (1 m/s2 = 0.101972 g; 1 g = 9.80665 m/s2)
    long t1; // create object for first time reference, set time just before the loop later on

    // Variables that are dependent on value from last loop
    float vx, vy, vz;
    float imu_x, imu_y, imu_z;

    void setup() {
      Serial.begin(9600);
      while (!Serial);  // wait for serial to open

      Serial.println("Initializing IMU device...");
      CurieIMU.begin(); // start accelerometer / gyro
      CurieIMU.setAccelerometerRange(2);  // accelerometer range to 2G - might need to be greater later on (18 m/s2 highest possible now)

      /*

      // Auto-calibration to ensure accelerometer doesn't drift
      CurieIMU.autoCalibrateAccelerometerOffset(X_AXIS, 0); // 89.69999 creates both positive and negative spikes
      delay(1000);
      CurieIMU.autoCalibrateAccelerometerOffset(Y_AXIS, 0);
      delay(1000);
      CurieIMU.autoCalibrateAccelerometerOffset(Z_AXIS, 1);
      delay(1000);

      */

      // Hardcoded accelerometer offsets after testing
      CurieIMU.setAccelerometerOffset(X_AXIS,89);

      // Fetch the offsets from the IMU
      float x_offset = CurieIMU.getAccelerometerOffset(X_AXIS);
      float y_offset = CurieIMU.getAccelerometerOffset(Y_AXIS);
      float z_offset = CurieIMU.getAccelerometerOffset(Z_AXIS);

      Serial.println("Current x_offset, y offset, z offset");
      Serial.print(x_offset, 6);
      Serial.print("\t");
      Serial.print(y_offset, 6);
      Serial.print("\t");
      Serial.println(z_offset, 6);
      delay(5000);

      t1 = millis(); // set the first time reference

      Serial.println("ax_g (g), ax (m/s2), t1 (ms), t2 (ms), td (ms), tds (s), vx (m/s), imu_posx (m)");

    }

    void loop() {

      // Fetch G forces
      float ax_g, ay_g, az_g;   //scaled accelerometer values
      CurieIMU.readAccelerometerScaled(ax_g, ay_g, az_g); // read accelerometer measurements from device, scaled to the configured range

      // Convert G force to m/s2
      float ax = ax_g / gravity;
      float ay = ay_g / gravity;
      float az = az_g / gravity;

      // Calculate time since last loop
      long t2 = millis();
      float td = t2 - t1; // time delta in ms
      float tds = td / 1000; // delta in seconds for easier logic

      // Calculate current velocity: velocity (m/s) = velocity (m/s) + acceleration (m/s2) * deltaTime (s)
      vx = vx + ax * tds;
      vy = vy + ay * tds;
      vz = vz + az * tds;

      // Calculate position: position (m) = position (m) + velocity (m/s) * deltaTime (s)
      imu_x = imu_x + vx * tds;
      imu_y = imu_y + vy * tds;
      imu_z = imu_z + vz * tds;

      // Print the values
      Serial.print(ax_g, 6);
      Serial.print("\t");
      Serial.print(ax, 6);
      Serial.print("\t");
      Serial.print(t1);
      Serial.print("\t");
      Serial.print(t2);
      Serial.print("\t");
      Serial.print(td, 6);
      Serial.print("\t");
      Serial.print(tds, 6);
      Serial.print("\t");
      Serial.print(vx, 6);
      Serial.print("\t");
      Serial.println(imu_x, 6);

      // Reset start values for next loop
      t1 = millis();

      delay(1);

    }

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

title: Arduino 101 accelerometer drift or calculation error?

Answers: 1

body:
The Arduino 101 contains the Intel® Curie™ Module, this module contains an Inertial Measurements Unit or IMU for short among other sensors and peripherals [![Intel® Curie™ Module Block Diagram][1]][1]

The IMU of this module is Bosch BMI160 which is a low cost MEMS IMU, this IMUs typically suffer from systematic errors and random/stochastic errors, the following diagram summarize them:
[![enter image description here][2]][2]

If we take the bias error as an example of those errors, an uncompensated accelerometer bias introduces an error proportional to time (t) in the velocity and proportional to t^2 in the position. For example, consider a case where accelerometer bias is 10 m/s^2. If this bias offset is not removed from the measurements, it can generate a 500 m error in position after 10 seconds and 12.5 km error after 50 seconds. Let us back to our IMU, if we read the data sheet the Zero-g error "or bias" is 40mg for the 8g sensing accelerometer and Ta = 25 Celsius with normal VDD and the IC has been assembled on board. If we just consider this 40mg bias error "dropping other error sources" it is 0.392266 m/s^2 so after 10 seconds the position offset will be 1.96133 meter even if you don't move the Arduino.
I suggest you read "MEMS-Based Integrated Navigation" book [here][3] it will give you a good vision about MEMS based inertial sensors and basic navigation concepts.

  [1]: https://i.stack.imgur.com/UqoaL.png
  [2]: https://i.stack.imgur.com/gV9W1.png
  [3]: https://www.amazon.com/MEMS-Based-Integrated-Navigation-Technology-Applications/dp/1608070433


body:
Since I am an using I2C LCD backpack, I'm unable to call in for pinmode to set variables like `#define BACKLIGHT_PIN 13`. I know `lcd.setBacklight(HIGH);` and `lcd.setBacklight(LOW);` controls the I2C LCD backlight, but if I use delay in the loop it slows down the whole loop.

How do I flicker the LCD backlight without using delay? I tried for example to blink without delay, but I don't know how to assign a global variable to `lcd.setbacklight` so as to control it.

I want to use an if statement to warn the user that so and so has happened, eg:

    #include <Ticker.h>
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

    //Ticker flashBacklight(toggleBacklight, 100);
    // when I use ticker here am getting not declared in scope
    const int buttonPin = 3;
    int buttonState = 0;
    // pls declare flashBacklight, long flashBacklight = 100; ??
    // pls declare toggleBacklight

    void toggleBacklight() {
      // lcd.setBacklight(!lcd.getBacklight());
      // !lcd.getbacklight() spelling mistake ? or it is setbacklight?
    }

    void setup() {
      lcd.begin(20, 4);
      lcd.setBacklight(HIGH);
      pinMode(buttonPin, INPUT);
     }

    void loop() {
      buttonState = digitalRead(buttonPin);
      if (buttonState == HIGH) {
        // if button goes high the back light must keep on flashing until it's released
        flashBacklight.start();
        //flash the lcd backlight
      } else {
        flashBacklight.stop(); // Stop flashing the backlight
      }
      flashBlacklight.update();
    }

But delay slows down the whole loop, so how do I flash the backlight without it? Thank you.

title: How to flash/blink I2C LCD backlight without delay function?

Answers: 3

body:
You record the timestamp when you want the LED to turn off again and then check that against millis in the `loop()`

      if ( level 1 > level 0)
      {

         NewTone(4,1000,50); // initiate alarm
         blinking = true;
         lcd.setBacklight(HIGH);
         lcdToggleTime = millis();// this is a global
         lcdOn = true;
      }else {
         blinking = false;
         lcd.setBacklight(LOW);
      }

      //at the start or end of loop(); make sure it's always checked.
    if(blinking){
          if(millis() - lcdToggleTime>+100) {
             if(lcdOn)
                 lcd.setBacklight(LOW);
             else
                 lcd.setBacklight(HIGH);
             lcdOn = !lcdOn;
             lcdToggleTime = millis();// this is a global
         }
    }

body:
Besides the standard 'compute a target `millis()` and compare' standard, which can get clunky when you have to handle more than 1 repeating or delayed event, there are also more than one decent library that abstract the concept, but also add features.

One example is the [Ticker][1] library.

With these methods, you create a **callback** function and pass that function name into the object constructor, along with the timing parameters.

So you might:

    [various #include, #define, etc.]

    Ticker flashBacklight(toggleBacklight, 100); //call toggleBacklight() every 100ms

    // Create the callback function, which just toggles the backlight each call.
    void toggleBacklight() {
      lcd.setBacklight( !lcd.getBacklight() );
    }

    setup() {
      [...]
    }

    loop() {
      // Start or stop the ticker based on your own situation. Once started, it will call your callback function at the specified interval until stopped.

      if (warningSituation) {
        flashBacklight.start();
      } else {
        flashBacklight.stop();
      }

      flashBlacklight.update();
    }

Another related library is [SimpleTimer][2]

**EDIT**

Your code example, updated:

    #include <Ticker.h>
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

    void toggleBacklight();

    Ticker flashBacklight(toggleBacklight, 100); //when i use ticker here am getting not declared in scope

    const int buttonPin = 3;
    int buttonState = 0;
                          // pls declare   flashBacklight   , long flashBacklight = 100;   ??
                          //   pls declare toggleBacklight

    void toggleBacklight() {
     // lcd.setBacklight( !lcd.getBacklight() );  // !lcd.getbacklight() spelling mistake ? or it is setbacklight?
    }
    void setup() {
       lcd.begin(20, 4);
     lcd.setBacklight(HIGH);
     pinMode(buttonPin, INPUT);
     }
    void loop() {
          buttonState = digitalRead(buttonPin);
       if (buttonState == HIGH)          // if button goes high the back light must keep on flashing untill its released
       {
        flashBacklight.start();          //flash the lcd backlight
      } else {
        flashBacklight.stop();           // Stop flashing the backligh
     }
       flashBacklight.update();
      }

  [1]: https://github.com/sstaub/Ticker
  [2]: https://playground.arduino.cc/Code/SimpleTimer

body:
You will need to alter the pin / bit tied to the backlight led.

To do that you will need to be able to read the state of all the pins on the i2c expander.

That can be done by reading back the pin state from the i2c expander or to hold the pin state in a buffer.

Once you know the pin state, you can OR or NEG it to clear or set the pin.


body:
I am keeping a simple weather station to monitor humidity and temperature in my greenhouse. I have a ds18b20 and dht probes.  everything works great and I even used a little trick to hold my maximum and minimum values, but I would like them to reset every 24 hours. Is there anyway i can code the arduino to reset itself. i tried several examples of connecting digital pins to the reset pin and i couldn't get any of those to work.  i tried to reset the values of my max and min to 0 and 99 respectively after my millis() reached the equivalent of a day, but they just stuck at 0 and 999. I understand fully why it does this i just don't know how to fix it. all i want to do is reset my minimum and maximum temperatures after 24 hours.

    //       Green HAUS Version 1 by Kent Scipione 9/3/2017
    //       Monitors temperature and humidity
    long timenow;
    long day = 86400000; // 86400000 milliseconds in a day
    long hour = 3600000; // 3600000 milliseconds in an hour
    long minute = 60000; // 60000 milliseconds in a minute
    long second =  1000; // 1000 milliseconds in a second

    #include <OneWire.h>
    #include <DallasTemperature.h>
    #include <SPI.h>
    #include <Adafruit_SSD1306.h>
    #define OLED_RESET 4
    #define ONE_WIRE_BUS 10
    double temp;  // sensor is precise to .1 degree.
    //Double gives smoother serial graph, byte doesn't overflow oled screen
    Adafruit_SSD1306 display(OLED_RESET);
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);

    #include <Adafruit_Sensor.h>
    #include "DHT.h"
    #define DHTPIN 2
    #define DHTTYPE DHT22
    DHT dht(DHTPIN, DHTTYPE);

    int maxtemp=0;
    int mintemp=999;

    void setup() {

      Serial.begin(9600);
      Serial.println("green HAUS Version 1 by Kent Scipione 9/3/2017");
      display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
      display.display();
      display.setTextColor(WHITE);
      sensors.begin();
      dht.begin();

    }

    void loop() {
      timenow = millis();
      sensors.requestTemperatures();
      temp = sensors.getTempFByIndex(0);
      int humid = dht.readHumidity();
      float dtemp = dht.readTemperature(true);
      if (temp > maxtemp) {
        maxtemp=temp; }
      if (temp < mintemp) {
        mintemp=temp; }

      if (timenow >= day){
          digitalWrite(4, HIGH);
          pinMode(4, OUTPUT);       //*************************this is the part where I'm trying to reset the mintemp and maxtemp**********

        }

      Serial.print("Probe Temperature: ");
      Serial.println(temp); Serial.println("*F");
      display.setCursor(0,0);  //refreshes display
      display.clearDisplay();
      display.setTextSize(1); display.print("Probe "); display.println(temp);  //line 1 of text
      display.print("DHT  "); display.print(dtemp); display.print("  "); display.print(humid); display.println(" %");  //line 2 of text
      display.print("HIGH "); display.println(maxtemp);           //line 3 of text
      display.print("LOW  "); display.println(mintemp);   //line 4 of text
      display.display();

    }
Thank you so much for your help this is driving me mad haha

title: How to keep a 24 hour maximum and minimum temperature

Answers: 1

body:
You should also keep a timestamp of the last time you reset the min and max otherwise the arduino will keep thinking it's a new day:

    //add to globals
    unsigned long lastDay = 0;

and inside loop()

      if (timenow-lastday >= day){

          maxtemp=0;
          mintemp=999;
          lastDay = timenow;
      }


body:
I realized I don't fully understand how Arduino code handles variable lifetime. My tendency is to keep variables in the narrowest scope (which I realize isn't as important in Arduino code, but, habits...). But how inefficient is this?

Given these possible variations:

     const int c1 = 2, c2 = 7, c3 = 9;

     void functy();

     int foo[3] = {c1 | c2, c3, c2 | c3};

     static int foo[3] = {c1 | c2, c3, c2 | c3};

     const int foo[3] = {c1 | c2, c3, c2 | c3};

      ....

In case 1, foo is both allocated and initialized each call.

In case 2, foo is allocated only once, but is it initialized on each call?

In case 3 I assume that allocation and initialization are done only once? Is that true?

title: Allocation, initialization and scope

Answers: 1

body:
Here's a pretty definitive list for you:

    // Allocated once in the global area and assigned during
    // program startup
    int foo = 1;

    // May not even be allocated - the compiler will most likely
    // optimise it out.
    const int foo = 1;

    // Allocated once and assigned during program startup. Cannot be
    // accessed from outside the file.
    static int foo = 1;

    // The static here has no real effect.
    static const int foo = 1;

    void function() {
        // Allocated in the stack each call and initialised each call.
        // Only accessible from inside this function.
        int foo = 1;

        // Allocated in the global area and initialized on the first call
        // of the function. Only accessible from inside this function.
        static int foo = 1;

        // May not be allocated at all. Only accessible from inside
        // this function.
        const int foo = 1;
    }

Note that non-simple `const` values, things like arrays and strings, depending on the architecture (i.e., if it's a Harvard architecture or not) may be copied into a block of global RAM for simpler access. See [`PROGMEM` in the Arduino Reference Manual](https://www.arduino.cc/en/Reference/PROGMEM) for more information.


body:
I'm using a supplied library which uses a number of (non-sequential) outputs to latch a multiplexer. The code looks (in part) like this:

     digitalWrite(_S0, (chan & 1));
     digitalWrite(_S1, (chan & 3)>>1);
     digitalWrite(_S2, (chan & 7)>>2);
     digitalWrite(_S3, (chan & 15)>>3);

Those masks seem a little odd, but it would work. More natural to me would be:

     digitalWrite(_S0, (chan & 1));
     digitalWrite(_S1, (chan & 2)>>1);
     digitalWrite(_S2, (chan & 4)>>2);
     digitalWrite(_S3, (chan & 8)>>3);

But overall, would it be more efficient to do this?

     digitalWrite(_S0,       (chan & 1));
     digitalWrite(_S1, (bool)(chan & 2));
     digitalWrite(_S2, (bool)(chan & 4));
     digitalWrite(_S3, (bool)(chan & 8));

...or is shifting already pretty efficient?

I've actually re-written the code to build a mask and use PORTx to latch it all at once, so this is really an academic question, but I'm still curious.

title: Efficiency of a cast vs a shift

Answers: 2

body:
If you look at the assembly code the compiler produces, you can see it compiles to the exact same thing - when using a constant.:

    void setup() {
      ....
      digitalWrite(_S1, (chan & 2)>>1);
     282: 84 e0        ldi r24, 0x04 ; 4
     284: 0e 94 6b 00  call 0xd6 ; 0xd6 <digitalWrite.constprop.0>
     ....
      digitalWrite(_S1, (bool)(chan & 2));
     29a: 84 e0        ldi r24, 0x04 ; 4
     29c: 0e 94 6b 00  call 0xd6 ; 0xd6 <digitalWrite.constprop.0>

However, using a variable produces different results:

    void loop() {
      digitalWrite(_S0, (chan & 1));
     2a2: c0 91 00 01  lds r28, 0x0100 ; 0x800100 <__data_start>
     2a6: d0 91 01 01  lds r29, 0x0101 ; 0x800101 <__data_start+0x1>
     2aa: 6c 2f        mov r22, r28
     2ac: 61 70        andi r22, 0x01 ; 1
     2ae: 83 e0        ldi r24, 0x03 ; 3
     2b0: 0e 94 76 00  call 0xec ; 0xec <digitalWrite>
      digitalWrite(_S1, (chan & 2)>>1);
     2b4: 6c 2f        mov r22, r28
     2b6: 66 95        lsr r22
     2b8: 61 70        andi r22, 0x01 ; 1
     2ba: 84 e0        ldi r24, 0x04 ; 4
     2bc: 0e 94 76 00  call 0xec ; 0xec <digitalWrite>
      digitalWrite(_S2, (chan & 4)>>2);
     2c0: c2 fb        bst r28, 2
     2c2: 66 27        eor r22, r22
     2c4: 60 f9        bld r22, 0
     2c6: 85 e0        ldi r24, 0x05 ; 5
     2c8: 0e 94 76 00  call 0xec ; 0xec <digitalWrite>
      digitalWrite(_S3, (chan & 8)>>3);
     2cc: c3 fb        bst r28, 3
     2ce: 66 27        eor r22, r22
     2d0: 60 f9        bld r22, 0
     2d2: 86 e0        ldi r24, 0x06 ; 6
     2d4: 0e 94 76 00  call 0xec ; 0xec <digitalWrite>

     ....

      digitalWrite(_S0,       (chan & 1));
     2a2: c0 91 00 01  lds r28, 0x0100 ; 0x800100 <__data_start>
     2a6: d0 91 01 01  lds r29, 0x0101 ; 0x800101 <__data_start+0x1>
     2aa: 6c 2f        mov r22, r28
     2ac: 61 70        andi r22, 0x01 ; 1
     2ae: 83 e0        ldi r24, 0x03 ; 3
     2b0: 0e 94 76 00  call 0xec ; 0xec <digitalWrite>
      digitalWrite(_S1, (bool)(chan & 2));
     2b4: be 01        movw r22, r28
     2b6: 76 95        lsr r23
     2b8: 67 95        ror r22
     2ba: 61 70        andi r22, 0x01 ; 1
     2bc: 84 e0        ldi r24, 0x04 ; 4
     2be: 0e 94 76 00  call 0xec ; 0xec <digitalWrite>
      digitalWrite(_S2, (bool)(chan & 4));
     2c2: be 01        movw r22, r28
     2c4: 76 95        lsr r23
     2c6: 67 95        ror r22
     2c8: 76 95        lsr r23
     2ca: 67 95        ror r22
     2cc: 61 70        andi r22, 0x01 ; 1
     2ce: 85 e0        ldi r24, 0x05 ; 5
     2d0: 0e 94 76 00  call 0xec ; 0xec <digitalWrite>
      digitalWrite(_S3, (bool)(chan & 8));
     2d4: be 01        movw r22, r28
     2d6: 23 e0        ldi r18, 0x03 ; 3
     2d8: 76 95        lsr r23
     2da: 67 95        ror r22
     2dc: 2a 95        dec r18
     2de: e1 f7        brne .-8       ; 0x2d8 <main+0xc0>
     2e0: 61 70        andi r22, 0x01 ; 1
     2e2: 86 e0        ldi r24, 0x06 ; 6
     2e4: 0e 94 76 00  call 0xec ; 0xec <digitalWrite>

body:
I tried compiling your three snippets with avr-gcc 4.9.2 at the `-Os`
optimization level (standard with Arduino) but _without_ `-flto`. The
results were:

* The first snippet generated inefficient code: the ands and shifts were
  translated in assembly quite literally, the shifts were done on
  16 bits even though `chan` was declared `uint8_t`, and the last
  shift was even implemented as a loop roughly equivalent to
  `uint16_t tmp1 = chan & 15; uint8_t tmp2 = 3; while (--tmp2) tmp1 <<= 1;`

* The second and third snippets were translated identically and
  efficiently, using the `bst` (bit store) and `bld` (bit load)
  instructions to copy the relevant bit of `chan` into the second
  argument of the `digitalWrite()` call.

Personally I would just write

    digitalWrite(_S0, chan & 1);
    digitalWrite(_S1, chan & 2);
    digitalWrite(_S2, chan & 4);
    digitalWrite(_S3, chan & 8);

as `digitalWrite()` expects an integer as its second argument, and it
interprets it just like the `(bool)` cast does. If you want to be sure
to always call `digitalWrite()` with either 0 (`LOW`) or 1 (`HIGH`),
then use either your second of third form. The first form seems formally
equivalent to the second, but since it is _not_ an usual C idiom, the
compiler could not catch the optimization opportunity.


body:
I am attempting to build mocoLUFA under OS X el Capitan 10.11.6.

[Editor: [mocoLUFA (MIDI firmware for Arduino Uno)\]
][1]
[![enter image description here][2]][2]

I am using the specified LUFA version (LUFA101122) and I have tried building with both brew avr-gcc and also Crosspack-AVR.

The problem I am facing isn't with the build or the install. It's just that as soon as I install the hex file, I get no midi messages at all.

What does work - the OSX machine recognises the MIDI device and the MIDI device appears in DAW's, however MIDI Monitor registers no messages at all.

I have tried downloading [a custom-built mocoLUFA][3] and I am able to install this and it works fine. I see midi messages coming across from my sketch.

Crosspack-AVR installs avr-gcc 4.8.1.

My question is - what is the correct build environment in order to achieve a working mocoLUFA under OSX? I have tried both mocoLUFA and dualMoco and I get the same result with each.

My purpose for this is to modify mocoLUFA so that it can support sending MTC over USB. At present, it appears that mocoLUFA does not support System Common messages.

UPDATE: Built fresh Ubuntu VM. Installed avr-gcc, avr-libc, LUFA-100807 and mocoulfa. Same result. hex builds fine, no response from the atmega16u2. TX light flashing, sketch on the 2560 running, but no midi messages down the usb cable.

  [1]: https://github.com/kuwatay/mocolufa
  [2]: https://i.stack.imgur.com/eFF2f.jpg
  [3]: https://moco-lufa-web-client.herokuapp.com/

title: Building mocoLUFA under OSX & Linux

Answers: 2

body:
This is Franco, from Yaeltex, the guys who put up that site for custom MocoLUFA compiling.

Our site works on an Ubuntu server, and the build environment can be seen at the bottom of the site, which is as follows:

 1. Ubuntu Server Setup
 - avr-gcc: avr-gcc (GCC) 4.9.2
 - avrdude: Version 6.3, compiled on Mar 15 2016 at 21:26:45
 - LUFA: 100807
 - dualMocoLUFA: custom Yaeltex based on 2013/09/22

On the other hand, I use Windows 10 to build locally in my computer, and I have a similar setup with sligthly older versions of avr-gcc and avrdude:

 2. Windows 10 Server Setup
 - avr-gcc: avr-gcc (GCC) 4.3.3
 - avrdude: Version 5.10, compiled on Mar 15 2016 at 21:26:45
 - LUFA: 100807
 - dualMocoLUFA: custom Yaeltex based on 2013/09/22

Here is a link to the [fork we made to mocoLUFA][1], it has minor changes, that were very useful to us and our hardware.

Regarding your problem, I am really lost on the cause of it, but we can start with some questions to get closer to a solution.

 - What kind of MIDI messages are you trying to send/receive?
 - Can you share the code you are using?
 - Are you using Arduino MIDI Library (Last version is v4.3.1)?
 - If not, are you sure you are using 31.250 bps as baud rate?
 - Do you have something else connected to TX or RX lines in your circuit?

Let's start with these. Cheers!

  [1]: https://github.com/Yaeltex/mocolufa-ytx

body:
I see that you are reading the MIDI messages from your iPad. If so, it is to be noted that LUFA reports 500mA for power requirements. So you could try self powering your USB-HUB.

Source: http://morecatlab.akiba.coocan.jp/morecat_lab/MocoLUFA.html


body:
I've recently bought a NodeMCU board and flashed MicroPython in it. I've read about the `boot.py` and `main.py` scripts, but I can't understand how to access them...

I have succesfully connected to the Python REPL with the screen command and everything works fine. Is there a way to mount it as an external drive on Mac OS X? Because I haven't found a way till now.

Thanks in advance!

title: Cannot mount NodeMCU with MicroPython on Mac OS X

Answers: 2

body:
You have a NodeMCU; not a pyboard. I'm not sure that the USB Drive option is available in the NodeMCU.

I flashed microPython in a NodeMCU and Linux doesn't recognize it as a external drive or any other media type, but REPL thru serial monitor works fine.

body:
The typical NodeMCU board uses a fixed function CP-210x USB-Serial chip.  This cannot appear to a host operating system as any ordinary sort of storage device, so it is not "mountable" via conventional storage drivers.

Access would need to be through some client program - or else, at a bit of a stretch, some highly specialized driver that created something fitting the host operating system's idea of filesystem, but proxying the actions through operatings the CP-210x and software running in the ESP8266 can support.


body:
I'm currently learning I2C and having some issues displaying the correct temperature in the serial monitor.

I am using an Arduino Uno and an SI7021 temperature sensor from Sparkfun; here's [the datasheet][1] I'm looking at.

The datasheet says that its device address is `0x40` and the temperature register is `0xF3` (maybe I am looking at this wrong?). However when I print the result to the screen it reads -1 degrees F.

Here's my code:

    // SparkFun Si7021 Humidity and Temperature Sensor
    #include <SparkFun_Si7021_Breakout_Library.h>
    #include <Wire.h>

    //Weather sensor slave address
    int WeatherAddress = 0x40;

    #define Temperature_Register_DATA 0xF3

    //initialize humidity and temperature variables
    float humidity = 0;
    float tempf = 0;

    //create a sensor from the Weather library
    Weather temp_rh_sensor;

    void setup() {
      Serial.begin(9600);
      //create wire object
      Wire.begin();
      //begin weather sensor
      temp_rh_sensor.begin();
    }

    void loop() {
      //begin transmission to weather sensor
      Wire.beginTransmission(WeatherAddress);
      //ask particular register for data (temperature register)
      Wire.write(Temperature_Register_DATA);
      Wire.endTransmission();
      //request the transmitted single byte from the register
      Wire.requestFrom(Temperature_Register_DATA, 1);
      if(Wire.available() <= 1) {
        tempf = Wire.read();
      }
      Serial.print("Temp: ");
      Serial.print(tempf);
      Serial.println("F, ");
      delay(1000);
    }

  [1]: https://cdn.sparkfun.com/datasheets/Sensors/Weather/Si7021.pdf

title: I2C Temperature Sensor Communication Issue

Answers: 3

body:
    Wire.requestFrom(Temperature_Register_DATA, 1);

This should have the WeatherAddress as parameter instead of the register.

    Wire.requestFrom(WeatherAddress, 1);

body:
Reading this sensor is a little more involved. You don't just select a register and then read the value from it. Instead you send it a command to begin a read of a parameter (e.g., temperature) and then you need to wait for it to perform that command before you can read the result.

You need to use command 0xF3 for read with *no hold master mode* which will return NACK from a read request if the command isn't completed (which you are doing) - you then need to keep retrying the read until you don't get a NACK.

Also you need to read *two* bytes, not one:

    //begin transmission to weather sensor
    Wire.beginTransmission(WeatherAddress);

    //ask particular register for data (temperature register)
    Wire.write(Temperature_Register_DATA);

    Wire.endTransmission();

    // Keep retrying the read until it succeeds, or times out
    uint32_t start = millis();
    while (Wire.requestFrom(WeatherAddress, 2) < 2) {
        if (millis() - start > 2000) { // 2 second timeout
            break;
        }
    }

    if (Wire.available() < 2) { // It timed out
        Serial.println("Timeout");
    } else {
        // Read the two bytes
        uint8_t hi = Wire.read();
        uint8_t lo = Wire.read();

        // and combine them into a 16 bit value
        uint16_t temp = (hi << 8) | lo;

        // Now convert the returned value into a real temperature:
        tempf = ((175.25 * temp) / 65536.0) - 46.85
        Serial.print("Temperature: ");
        Serial.println(tempf);
    }

body:
> The datasheet says that its device address is: 0x40

there is no standard notation on how to code i2c addresses - it all depends on how the particular library is coded. In this case, try 0x80 and 0x40 and see which one works.


body:
I have seen another similar question and I followed the answer, but I cannot get my code to work for a single client properly.

In short, one NodeMCU provides AP and a WiFi server to multiple clients. The clients are supposed to stay connected. I am testing just a single client and it succeeds to connect and server reads just the first message, whereas all the subsequent messages are not received.

The server code:

    #include <ESP8266WiFi.h>

    #define MAX_CLIENTS 10

    IPAddress    apIP(42, 42, 42, 42);
    const char *ssid = "ESP8266";
    const char *password = "ESP8266Test";
    WiFiServer server(80);
    WiFiClient *clients[MAX_CLIENTS] = { NULL };

    void setup() {
      Serial.begin(115200);
      WiFi.mode(WIFI_AP_STA);
      WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
      WiFi.softAP(ssid, password);
      IPAddress myIP = WiFi.softAPIP();
      Serial.print("AP IP address: ");
      Serial.println(myIP);
      server.begin();
    }

    void loop () {
      WiFiClient newClient = server.available();
      if (newClient) {
        Serial.println("new client");
        // Find the first unused space
        for (int i=0 ; i<MAX_CLIENTS ; ++i) {
          if (NULL == clients[i]) {
            clients[i] = new WiFiClient(newClient);
            break;
          }
        }
      } else {
        // Check whether each client has some data
        for (int i=0 ; i<MAX_CLIENTS ; ++i) {
          if (NULL != clients[i]) //ako ima taj client {
            if (clients[i]->available()) {
              Serial.print("client "); Serial.print(i);
              Serial.println("data received");
              digitalWrite(ledPin, LOW);
              String request = clients[i]->readStringUntil('\r');
              Serial.println(request);
            }
          }
        }
      }
    }

As one can see, I'm checking incoming connections with `server.available()`, whereas I check if there is some data over the existing connection with `clients[i]->available`.

What happens is that I get only the first message from the client. The client code follows:

    #include <ESP8266WiFi.h>

    char ssid[] = "ESP8266";
    char pass[] = "ESP8266Test";
    WiFiClient client;

    void setup() {
      Serial.begin(115200);
      WiFi.begin(ssid, pass);
      while (WiFi.status() != WL_CONNECTED) {
        Serial.println("W");
        delay(500);
      }
      client.connect(WiFi.gatewayIP(), 80); // Connection to the server
    }

    void loop () {
      client.println("0.00"");
      Serial.println("0.00"");
      delay(3000);
    }

I suspect that I do not understand well the Server and Client classes from ESP8266WiFi Library, but it seems poorly documented.

Please advise.

title: Arduino & NodeMCU, one server and multiple clients

Answers: 1

body: I presume you are not flushing the first data that's why only the first time your communication is happening but not after the subsequent time


body:
I have a Django web application hosted on a Heroku server. Currently I am using the free package for hosting. I want to send data from an Arduino using a SIM900L GPRS module to the web application. I want to know if it is possible. I have searched for a solution but couldn't find a proper guide or example for it. My web application accepts get requests and updates values in the database when url is entered. However if the Arduino sends data using the same url I get the following error:

>
AT+CIPSTART="TipCP","https://<appname>.herokuapp.com",80
ERROR

Any tested example or suggestions about what I am doing wrong or what I should be doing instead?

         void gprs(float *value1, float *value2, float *value3, float *AFR, float *value5, float *value6)
    {

      String APN = "";
      String UNAME = "";
      String PWD = "";
      char fid[] = "";
      char nid[] = "";
      char s_ip[] = "https://<appname>.herokuapp.com";
      char apikey[] = "";

      wdt_reset();
      digitalWrite(A4, HIGH);
      Serial.println(F("GPRS-1 Function"));
      delay(5000);
      wdt_reset();
      delay(5000);
      wdt_reset();

      char buffer1[10];

      uint8_t GSMTries = 0;
      String res;

      //wdt_reset();
      // the below code establishes connection and if not successful
      // tries three times in total
      do {
        sendData(F("AT\r\n"), 1000, DEBUG);
        sendData(F("AT+CIPSHUT\r\n"), 2000, DEBUG);
        sendData(F("AT+CIPMUX=0\r\n"), 2000, DEBUG);

        sendData(F("AT+CSQ\r\n"), 2000, DEBUG);
        sendData("AT+CSTT= \"" + APN + "\", \"" + UNAME + "\", \"" + PWD + "\"\r\n", 2000, DEBUG);

        sendData(F("AT+CIICR\r\n"), 2000, DEBUG);
        sendData(F("AT+CIFSR\r\n"), 2000, DEBUG);

        sendData(F("AT+CSQ\r\n"), 2000, DEBUG);
        String scnt = "AT+CIPSTART=\"TipCP\",\"" ;
        scnt += s_ip ;
        scnt += "\",80\r\n" ;

        res = sendData(scnt, 10000, DEBUG);
        GSMTries++;

        wdt_reset();

      } while (((res.indexOf("ERROR") != -1) || (res.indexOf("CONNECT") == -1)) && (GSMTries < 3));
      /*
        if(res.indexOf("ERROR") != -1){
        delay(200);
        sendData(scnt, 10000, DEBUG);
        }
      */

      String api = "GET /value?apkey=" ;
      api += apikey;
      api += "&&fid=";
      api += fid;
      api += "&&nid=";
      api += nid;

      Serial.println(F("API......."));
      Serial.flush();
      Serial.println(F("here-1"));

      String Data1 = "";

      //wdt_reset();
      //Co ordinator data is compiled along with html commands
      //and sent through GPRS
      String sensor = dtostrf(*value1, 4, 2, buffer1);
      Data1.concat(api);
      Data1.concat(F("&field1="));
      Data1.concat(sensor);

      sensor = dtostrf(*value2, 4, 2, buffer1);
      Data1.concat(F("&field2="));
      Data1.concat(sensor);

      sensor = dtostrf(*value3, 4, 2, buffer1);
      Data1.concat(F("&field3="));
      Data1.concat(sensor);

      sensor = dtostrf(*AFR, 4, 2, buffer1);
      Data1.concat(F("&field4="));
      Data1.concat(sensor);

      sensor = dtostrf(*value4, 4, 2, buffer1);
      Data1.concat(F("&field5="));
      Data1.concat(sensor);

      sensor = dtostrf(*value6, 4, 2, buffer1);
      Data1.concat(F("&field6="));
      Data1.concat(sensor);

      Data1.concat(F("\r\n"));

      delay(1000);

      String cipSend = "AT+CIPSEND=";
      cipSend.concat(Data1.length());
      cipSend.concat("\r\n");
      sendData(cipSend, 8000, DEBUG);
      sendData(Data1, 8000, DEBUG);
      sendData(F("AT+CIPCLOSE\r\n"), 5000, DEBUG);
      digitalWrite(A4, LOW);

      wdt_reset();

    }
The above is a part of code used in arduino to upload data to website. This code was being used before to upload data to thingspeak through its IP address and worked fine.

title: How to send data from an Arduino GPRS module to a Django application hosted on Heroku?

Answers: 1

body:
There's a number of errors in your program regarding your understanding of basic networking:

Let's start with this bit:

    String scnt = "AT+CIPSTART=\"TipCP\",\"" ;
    scnt += s_ip ;
    scnt += "\",80\r\n" ;

That constructs a string:

    AT+CIPSTART="TipCP","https://<appname>.herokuapp.com",80

and sends it to the modem.  Now:

1. There is no such protocol as "TipCP" - I think you meant "TCP"
2. You need to provide an FQDN (Fully Qualified Domain Name), *not* a URL.  FQDNs don't start with "https://".  I think you meant to use "foobar.herokuapp.com" where "foobar" is the name of your application.

You then go on to form a GET request and send it.

Now: the URL you used instead of an FQDN starts with https:// - that tells me you want to be using SSL for your communications. I don't know if that is required for Heroku or not, but if it is then you cannot use `AT+CIPSTART` with it unless you feel like trying to implement the entirety of SSL in your program. Also you would be connecting to port 443 not port 80.

Assuming you don't need SSL fixing your protocol and FQDN may be enough. However using the `AT+HTTP...` commands instead of manual manipulation of a raw TCP socket may be an easier option.

If you *do* need SSL (and it is advisable that you do if you can) then you will have to use the SIM900's `AT+HTTPS...` command set (detailed [here](http://simcom.ee/documents/SIM900/SIM900_HTTPS AT Command Set_V1 00.pdf)).


body:
Are there any good circuit designs for Geiger-counter projects using an Arduino?

If so, what Geiger-Muller tubes should I choose to detect different types of radiation?

title: What good designs are available for Geiger counters using an Arduino?

Answers: 1

body:
There are a few good, open-source, designs for Geiger counters using cheap G-M tubes and Arduino boards out there. Which one is best for you depends on what you want to achieve, so let's start by taking a look at what you might want to detect.

What are these "types" of radiation?
------------------------------------

![Types of radiation][1]
(*source: Wikipedia*)

**Alpha radiation**: basically consists of helium-4 nuclei (i.e. two protons and two neutrons). These interact with matter strongly because they are relatively heavy and carry a positive charge. However, because of their mass they will normally only penetrate a few centimetres of air. Alpha particles can be stopped in their tracks by a single sheet of paper.

You may not realise it, but the sensor in most smoke detectors uses a very small amount (~0.2μg) of Americium -  241Am.

![ion chamber][2]

**Beta radiation**: consists of highly energetic electrons. Because these particles are relatively light, they can penetrate somewhat further than Alpha particles. Even so, beta radiation can be stopped by a thin sheet of aluminium.

The big risk to human health from alpha- and beta-emitters is when they are ingested or inhaled. In these cases, the particles are brought into close contact with sensitive live tissue where the ionising radiation has the potential to cause various types of cancers.

**Gamma radiation:** is electromagnetic radiation having a higher frequency and shorter wavelength than X-rays.

![e-m spectrum][3]

One way to think of gamma-radiation is like a kind of "super X-ray". Gamma rays can pass through virtually anything. To build an effective shield, you need to have either *very* thick walls or a shield made from something with a high atomic weight, such as lead.

Gamma rays are produced naturally by the sun and stars - this is the source of what we call "cosmic radiation".

So which tubes should you choose?
---------------------------------

Once you have decided what types of radiation you want your Geiger counter to detect the next step is choosing the tube. In general, they are all high-voltage tubes, typically operating at ~ 400V.

At the moment, the cheapest available tubes are probably the Russian [SI-3BG][4] Geiger Muller tubes, which can be picked up on eBay for about £5 GB. These are not very sensitive, but I've found they do work OK for beta and gamma radiation. However, it doesn't detect alpha radiation (which, as mentioned earlier, is what is emitted by the source in the sensor in many smoke detectors!)

One thing to watch out for is that these tubes are all different sizes, ranging from about 20mm long to more than 200mm. This matters. If you are going to design or buy a PCB for your project, just check that it has been designed to fit the sensor that you intend to use.

The following table lists the most popular G-M tubes, together with their main characteristics:

![G-M tubes][5]

Follow the links below for further data on each tube:

 - [SBM-20][6]
 - [SBM-21][7]
 - [SI-1G][8]
 - [SBT-9][9]
 - [SI-3BG][4]
 - [LND-712][10]
 - [LND-7124][11]
 - [LND-7224][12]
 - [J408γ][13]
 - [J305β][14]
 - [J306β][15]

Your choice of tube is going to be determined by your budget, the types of radiation you want to detect and the sensitivity you want to achieve with your G-M counter.

Circuit designs
---------------

OK, so now we understand the radiation types, and we've chosen our tube, what Geiger counter designs are out there that use the Arduino.

(***disclaimer***: I have no connection with any of the companies mentioned in this answer)

Well, it turns out there are a few good designs out there (Google is your friend here), but one that does stand out from the pack (IMHO) is the [Geiger Counter - Radiation Sensor Board for Arduino and Raspberry Pi][16] from Cooking Hacks.

This is an open hardware design, and the code can be downloaded on a GPL licence.

It's a relatively [simple design][17], and has a kit available pretty much off-the-shelf. Software can be downloaded for the Arduino and/or the Raspberry Pi. If you decide to buy the kit, they assure us that the shield/hat has been tested with the Arduino Uno and all models of the R-Pi.

Alternatively, you can just download the circuit diagram on the link above and design your own PCB (I don't think they offer the Gerber or Eagle files to download).

It is worth mentioning that the tutorial page also includes all the lovely useful background theory you'll need to understand how Geiger counters work, and how to get the most out of it.

**Final thoughts**. If you were thinking of building a Geiger counter without using an Arduino (Yes, yes, I know. But there may be some strange people out there who want to go this route!), there are still some nice designs out there you can play with.

The [Geiger counter][18] from MightyOhm is also open-source and uses the SBM-20 Geiger-Muller tube. Again, it is available as a kit, but if you prefer the DIY route, the [design files][19] are available to download.

Having looked at it, adapting this design to interface with an Arduino would probably also be relatively straightforward ...

If you are on a really tight budget there is a [$15 Geiger counter][20] on Hackaday. This uses the Russian SI-3BG G-M tube (discussed above) and a modified power-supply from a disposable camera.

I built one of these with a friend who was just starting out studying electronics and wanted to have a go at this project. I can confirm that it works, but that $15 price-tag is very optimistic.

(Having built this one, my friend decided that her next project would be to design a better one with greater sensitivity and which could detect alpha-, beta- and gamma-radiation and which incorporated an Arduino Uno. In hindsight, I should probably have mentioned the design from Cooking Hacks ..!).

  [1]: https://i.stack.imgur.com/SYZdn.png
  [2]: https://i.stack.imgur.com/RU0Bw.jpg
  [3]: https://i.stack.imgur.com/ujVHu.png
  [4]: https://www.pocketmagic.net/tube-si-3bg-cи-3бг-small-geiger-muller/
  [5]: https://i.stack.imgur.com/9mJuw.png
  [6]: http://www.gstube.com/data/2398/
  [7]: https://www.pocketmagic.net/tube-sbm-21-сбм-21-miniature-geiger-muller/
  [8]: http://gstube.com/data/2480
  [9]: https://www.pocketmagic.net/tube-sbt-9-end-window-geiger-tube/
  [10]: http://www.lndinc.com/products/711/
  [11]: http://www.lndinc.com/products/350/
  [12]: http://www.lndinc.com/products/368/
  [13]: http://sell.lulusoso.com/selling-leads/1738145/Geiger-Muller-counter-GM-counter-j408-GM-J408.html
  [14]: http://1169585.en.makepolo.com/products/Geiger-tube-J305-for-High-doses-p104457261.html
  [15]: http://en.ofweek.com/Product/Geiger-Muller-Counter-Tube-J306-High-Sensitivity-Beta-Gamma-Radiation-Detection-prod-92360-1087385.html
  [16]: https://www.cooking-hacks.com/documentation/tutorials/geiger-counter-radiation-sensor-board-arduino-raspberry-pi-tutorial/
  [17]: https://www.cooking-hacks.com/media/cooking/images/documentation/geiger_counter_arduino_radiation_sensor_board/radiation_board_v5.pdf
  [18]: http://mightyohm.com/blog/products/geiger-counter/
  [19]: http://mightyohm.com/blog/products/geiger-counter/design-files/
  [20]: https://hackaday.io/project/19479-15-geiger-muller-counter-for-betagammaxray


body:
I've got just a simple question. What happens when I overload Force Sensitive Resistor (FSR). [Example Here][1].

[![FSR][2]][2]

Let's say that it's got force sensitive range between 100g and 10 000g. What would happen if I'd create pressure about 100kg? I see that resistance is decreasing with bigger pressure. Will there be almost 0 ohm resistance? If so, can this FSR survive this overload? Has somebody test that?

Thank you for any answer.

  [1]: https://www.sparkfun.com/products/9375
  [2]: https://i.stack.imgur.com/lTdEg.jpg

title: Force Sensitive Resistor OverLoad

Answers: 1

body:
> I see that resistance is decreasing with bigger pressure. Will there be almost 0 ohm resistance?

The harder the force, the lower the resistance. Sparkfun has a datasheet attached that shows the following graph:
[![FSR Graph][1]][1]
Notice how both axis of the graph are logrithmic. This means that the resistance will never reach 0 ohms. However it will get close. At 10 Kg (22 lb) the resistance is about 250 ohms.

> What would happen if I'd create pressure about 100kg?

The datasheet has the following to say for weight above the 10 Kg mark:

> At the high force end of the dynamic range, the response deviates from the power-law behavior, and eventually saturates to a point where increases in force yield little or no decrease in resistance. Under these conditions of Figure 2 [ie. the graph above], this saturation force is beyond 10 kg. The saturation point is more a function of pressure than force. The saturation pressure of a typical FSR is on the order of 100 to 200 psi. For the data shown in Figures 2, 3 and 4, the actual measured pressure range is 0 to 175 psi (0 to 22 lbs applied over 0.125 in^2). Forces higher than the saturation force can be measured by spreading the force over a greater area; the overall pressure is then kept below the saturation point, and dynamic response is maintained. However, the converse of this effect is also true, smaller actuators will saturate FSRs earlier in the dynamic range, since the saturation point is reached at a lower force.

In summary, the weight applied can go over 10 Kg providing that weight is spread over the sensing area. The larger FSRs ([such as this one][2]) are better suited for this purpose as they have a larger area for which to spread the pressure.

Note: It is quite possible that with 100 Kg you could irreversibly damage the FSR, particularly if the weight isn't spread over the sensor area.

Measuring an analog voltage from the sensor is possible so that it can be fed into one of the analog pins of the Arduino. [This Adafruit page][3] has a nice table at the bottom showing the analog voltage that you get when you put the sensor in a [voltage divider network][4] (ie. in series) with a 10K ohm resistor.

  [1]: https://i.stack.imgur.com/dHfY5.png
  [2]: https://www.sparkfun.com/products/9376
  [3]: https://www.adafruit.com/product/166
  [4]: https://learn.sparkfun.com/tutorials/voltage-dividers


body: How does one control a digital pin directly avoiding the slow digitalWrite or digitalRead?

title: Arduino ESP8266 direct/fast control of the digital pins

Answers: 3

body:
In the spec sheet you will find the details for your device but most of the time it's pretty simple.

There will be global variables to control them, each will control various aspects of the pins.

For example you will have a register to control whether it's input or output, a register to control the output state, ... Again read the spec for your device to know what is what.

After the pin has been set up the instruction to set a pin high is:

    PORTA |= PINx_MASK;

where Pinx_MASK is a bit mask with a single bit set according to the pin it represents.

To set the pin low it's similar:

    PORTA &= ~PINx_MASK;

To set multiple pins on the port to different values you can do the following:

    PORTA = (PORTA & ~pinsMask) | pinValues;

where pinsMask is a bitmask where all the pins you want to change are set and pinValues is the bitmask of which pins should be set high.

It pays to know how to manipulate bits in bitmasks but that's out of scope for this answer.

The SDK will be doing direct port manipulation itself, if you follow the definitions you should be able to figure it out.

body:
After a weekend of searching and trying, here is what I was looking for:

It is slightly different than for the AVR chips. There is one register for setting the pins to HIGH and another one to set the pins to low.

Setting the pin HIGH:

    GPOS = (1 << PIN_OUT);

Setting the pin LOW:

    GPOC = (1 << PIN_OUT);

using this, I managed to speed up my code by a factor of three. It is not as dramatic as for the AVR chips, since the digitalWrite function is much more simple for the ESP8266.

**Edit Further experiments show it is 10x faster**: 910nsec for `digitalWrite` vs. 88nsec using `GPOC` or `GPOS`!

body:
Unfortunately, Ratchet Freak's answer is specific to AVR, and isn't how the ESP8266 works.

It looks like the ESP8266 does indeed have registers for doing exactly this, which would let you set all 16 GPIO pins (GPIO0 through GPIO15, 16 is a different thing entirely) with a single operation. There's also a SET register, which sets the pins corresponding to 1 bits, and ignores pins corresponding to 0 bits, and a CLEAR register, which is the other way around.

Something I found on a forum said a user went from ~800KHz to ~5.7MHz toggling pins using these direct registers, that sounds about right.

One version of this is found in `eagle_soc.h`. The relevant bits from the header to get you started:

    #define GPIO_REG_READ(reg)                         READ_PERI_REG(PERIPHS_GPIO_BASEADDR + reg)
    #define GPIO_REG_WRITE(reg, val)                 WRITE_PERI_REG(PERIPHS_GPIO_BASEADDR + reg, val)
    #define GPIO_OUT_ADDRESS                         0x00
    #define GPIO_OUT_W1TS_ADDRESS             0x04
    #define GPIO_OUT_W1TC_ADDRESS             0x08

So, if I've understood this correctly (and I haven't done any real testing, just going off the spec sheet and the header and posts elsewhere):

    GPIO_REG_WRITE(GPIO_OUT_ADDRESS, 0xF0F0);

would set GPIO 4-7 and 12-15 to high, and 0-3 and 8-11 to low. In one operation. But there's more! Look at those `W1TS` and `W1TC` names. Those are set and clear registers. Which means you *don't* have to mask things. Instead of grabbing the current value, masking a bit in or out, and then writing it back, you can use those:

    GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 0x1);

This will set GPIO0 high, and not affect any other bits.

This is also offered in a cleaner/simpler (??) form in `esp8266_peri.h`, which simplifies it to:

    GPOS = 0x1;

for setting a bit. This is what's actually called by the arduino library's digitalWrite (for pins other than GPIO16):

    extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) {
      pwm_stop_pin(pin);
      if(pin < 16){
        if(val) GPOS = (1 << pin);
        else GPOC = (1 << pin);
    [...]

But definitely be aware of this if you're doing anything fast, because writing multiple pins with a single operation is going to be *way* faster than multiple function calls. Without this, this chip can't even toggle bits as fast as a 16MHz Arduino.


body:
I'm currently developing a quad copter for my school project and I am coming to the part where I am collecting all the parts before I assemble everything.

I have recently encountered a roadblock. I am going to solder an Arduino nano onto a strip board, but the problem is I cannot seem to find cables/wires to connect the nano to the module.

Excuse my ignorance, but where can I find these cables for soldering and what are they called?

[![][1]][1]

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

title: What are these wires called?

Answers: 4

body:
If they are an intentional part of the design they are *jumper wires*. If they are to correct a mistake in the design they are *bodge wires*.

They aren't anything special, just wire. They look to be in the range of 24 to 30 AWG and PVC jacketed.

You can buy it in any electronic store.

You can also salvage it from things like old SCART cables and similar things.

body:
Read this [tutorial][1] about working with wires.

Sorry for the link-only answer, but I can't copy the article in full.

  [1]: https://learn.sparkfun.com/tutorials/working-with-wire

body:
>  but where can I find these cables for soldering and what are they called?

hook-up wires.

pretty much any hardware stores should have it.

body:
If you want to wire your board with stranded wire, you can ask for ***NYAF*** and solder the edges with the tip. Otherwise you can ask for ***hook-up wires***.

But if you are using breadboard, which i recommend you to use solid wire, you can ask it as ***wire wrap***.

You can find them at an electronic store.


body:
I'm trying to build this Midi2CV (control voltage for analog synths) using a Arduino Nano:

https://photos.app.goo.gl/3IhhFL3PrLELLODB3

I was hoping to use this Nokia screen too for settings and debugging purposes, but I just realized there's only one hardware serial port on 328p and software serial seemed to be doomed for MIDI:

https://arduino.stackexchange.com/questions/38567/softwareserial-too-slow-for-midi

So I have three peripherals:

* DAC (MCP4822)
* Nokia 5110 screen
* MIDI

I've gotten both the DAC and screen to work fine on normal pins so I'm thinking I'm good with just using the hardware serial for MIDI and the DAC and screen can use software. Or am I in for a world of pain without getting a more powerful chip with more hardware serial ports? And if so, what's the recommendation? (shoestring budget)

title: Atmega328p screen + midi, possible?

Answers: 1

body:
Of your three functions (DAC, screen and MIDI) only one (MIDI) actually uses UART.

The other two devices are SPI devices which, while it is a *serial* protocol isn't UART (serial is a *concept* not a protocol).

Connect the DAC and screen to the SPI port (you can share SCK, MOSI and MISO, but select different CS pins) and you have the UART pins (0/1) available for MIDI use - as long as you don't want to use the USB connection which is linked directly to those pins.


body:
I'm using LCD QC1602A with a 10k potentiometer and changing contrast. It works well but the problem is that no text is appearing.

I'm using the LCD hello world examples and a few other examples. I tried reconnecting wires at least 5 times but every time it's the same problem. I connected it [like this][1] but the screen is not displaying any text at any contrast.

  [1]: https://www.arduino.cc/en/uploads/Tutorial/LCD_Base_bb_Fritz.png

PS: It was showing white squares only in the top row, and now it's in both rows.

title: LCD is not showing any text

Answers: 2

body:
> It works well but the problem is that no text is appearing.

it works well and yet no text is appearing?

so there is or there isn't a problem?

> PS: It was showing white squares only in the top row, and now it's in both rows.

when correctly initialized, it should one row of blocks in the first row.

if it shows two rows of blocks, either it is not correctly initialized or the contrast is too much.

body:
Two rows of white squares means that the driver chip has been successfully initialised to run in a 2x16 mode (it defaults to 1x16 which was the 1 row of squares you had originally).

So that means that you are configuring the display at least partially correctly.

You should adjust the pot so that you can just about see the squares. The squares are the background and the text would appear over them. If they are too bright you won't see the text. So adjust the contrast until you can just see that there are squares there.

If the wiring is correct and the code is correct then you should be able to see the text.