message:
If I run a function in loop() or setup(), and the function doesn't work after some time, is there a way to escape the function and return to the code?

The hardware is an Arduino Uno, using the Arduino IDE.
As a simplest working example, say I have this code
(partially from Edgar Bonet's [answer][1]):

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

    // Simulate an initialization that can hang. Connect pin 8 to ground if
    // you want the function to ever return.
    void initialize()
    {
        pinMode(8, INPUT_PULLUP);
        while (digitalRead(8) == HIGH)
        ;  // wait
    }

    setup()
    {
        initialize();             //Function I want to run

        Serial.begin(9600);       //Baud rate
        Serial.println("TEST 1"); //Test message
    }

    loop()
    {
        Serial.println("TEST 2"); //Test message
        delay(1000);
    }

if the `initialize()` function does not complete after some time, such as 2 secs.,
is there a way to ignore that function and continue with the rest of the code?

  [1]: https://arduino.stackexchange.com/questions/51628/if-i-run-a-function-in-loop-or-setup-and-the-function-doesnt-work-after-so/51651#51651

body:
I'm not sure if you should want this in the first place. Initialization normally should contain the necessary parts to start with.

If there is a device/component you want to initialize that is not able to initialize (because it is not present, or broken), check first if there is an intiialization function with a timeout and when the timeout is reached, set a boolean to denote the device has not been initialized.

If there is not a timeout function, you could try to set up a timer interrupt and start it just before you initialize the device/component you want to initialize. When the timer interrupt triggers and the device is not initialized, behave the same like a timeout has occurred.


sender: user

sender: assistant

body:
In general, the _right thing_ to do in such a situation is to fix the
`initialize()` function so that it always returns. If there is a timeout
to be handled, it should be handled within that function. This is likely
to be the easiest and cleanest solution.

However, if for whatever reason that is not feasible (maybe it comes
from a library that is too opaque to edit), then the idea suggested by
Michel Keijzers is a viable alternative:

> [...] set up a timer interrupt and start it just before you initialize
> the device/component you want to initialize. When the timer interrupt
> triggers and the device is not initialized, behave the same like a
> timeout has occurred.

The issue with this is that you would want the ISR (interrupt service
routine) to return to the point where `initialize()` was called. This is
not trivial, but it can be done. Actually, and contrary to what my own
comment says, it can be handled without resorting to assembly hacks, by
using the [setjmp][] “non-local goto” feature of the avr-libc. Here is a
proof of concept:

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

    #include <setjmp.h>

    jmp_buf env;

    // Simulate an initialization that can hang. Connect pin 8 to ground if
    // you want the function to ever return.
    void initialize()
    {
        pinMode(8, INPUT_PULLUP);
        while (digitalRead(8) == HIGH)
            ;  // wait
    }

    // This fires when the initialization times out.
    ISR(TIMER1_OVF_vect)
    {
        TIMSK1 = 0;       // disable timer interrupt
        longjmp(env, 1);  // go to where setjmp() was called
    }

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

        // Configure Timer 1 to fire an interrupt in about 4 seconds.
        TCCR1A = 0;           // reset timer
        TCCR1B = 0;
        TCNT1  = 0;
        TIFR1  = _BV(TOV1);   // clear interrupt flag
        TIMSK1 = _BV(TOIE1);  // enable timer overflow interrupt
        TCCR1B = _BV(CS10)    // clock at F_CPU / 1024
               | _BV(CS12);   // ditto

        // Attempt initialization.
        if (setjmp(env) == 0) {

            // This is the normal program flow.
            Serial.println("Attempting initialization.");
            initialize();
            TIMSK1 = 0;  // disable timer interrupt
            Serial.println("Initialization succeeded.");
        } else {

            // We get here through longjmp() in case of timeout.
            Serial.println("Initialization aborted on timeout.");
        }

        Serial.println("Moving on to the rest of the program.");
    }

    void loop(){}

If pin 8 is grounded, the initialization succeeds and the program prints

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

    Attempting initialization.
    Initialization succeeded.
    Moving on to the rest of the program.

If pin 8 is left floating, the initialization hangs and the program
prints

    Attempting initialization.
    Initialization aborted on timeout.
    Moving on to the rest of the program.

with a 4 second pause between the first and second lines.

[setjmp]: https://www.nongnu.org/avr-libc/user-manual/group__setjmp.html


message:
How to add a pedestrian button code to a traffic light with ultrasonic sensor?

So I have a project to create a 2 set of traffic lights which would detect a car coming and stopping on the ultrasonic sensor and my code would allow the traffic lights to loop and let the car through. But now I also have to add a pedestrian code in for the pedestrians to press the button, the traffic lights to loop back to red and give 30 seconds of crossing time.

I did the ultrasonic sensor traffic lights code already and some of it seems confusing but somehow works quite well. I'm not familiar with the buttons and looping the traffic lights correctly back to red so I need help to add a pedestrian crossing code to this code:

    // Variables for Station 1 Traffic Light Components
    const int Red1LED = 9;
    const int Yellow1LED = 2;
    const int Green1LED = 3;
    const int GreenArrow = 4;
    #define trigPin 12
    #define echoPin 13
    // Setup Variables for Station 2 Traffic Light Components
    const int Red2LED = 5;
    const int Yellow2LED = 6;
    const int Green2LED = 7;
    const int GreenArrow2 = 8;

    void setup() {

      pinMode(Red1LED, OUTPUT);
      pinMode(Yellow1LED, OUTPUT);
      pinMode(Green1LED, OUTPUT);
      pinMode(GreenArrow, OUTPUT);
      pinMode(Red2LED, OUTPUT);
      pinMode(Yellow2LED, OUTPUT);
      pinMode(Green2LED, OUTPUT);
      pinMode(GreenArrow2, OUTPUT);
      pinMode(echoPin, INPUT);
      pinMode(trigPin, OUTPUT);
     Serial.begin(9600);
      // Set Initial state of all red LED to HIGH
      digitalWrite (Red1LED, HIGH);
      digitalWrite (Red2LED, HIGH);
    }

    void loop() {
      // put your main code here, to run repeatedly:
     long duration, distance;
      digitalWrite(trigPin, LOW);  // Added this line
      delayMicroseconds(2); // Added this line
      digitalWrite(trigPin, HIGH);
    //  delayMicroseconds(1000); - Removed this line
      //delayMicroseconds(10); // Added this line
      //digitalWrite(trigPin, LOW);
      duration = pulseIn(echoPin, HIGH);
      distance = (duration/2) / 29.1;
      Serial.println(distance);
      if (distance < 20) {  // This is where the LED On/Off happens
         delay(1000);  //  1 Seconds of Red
      digitalWrite(Green1LED, LOW);  //  Sets Red1 OFF Green ON
      digitalWrite(Yellow1LED, HIGH);
      delay(1000);  // 1 Seconds of Green
      digitalWrite(Yellow1LED, LOW);  //  Sets Green1 OFF Yellow ON
      digitalWrite(Red1LED, HIGH);
      delay(1000);  // 1 Seconds of Yellow
       // Station 2 Timing
      delay(1000);  //  1 Second of Red
      digitalWrite(Red2LED, LOW);
      digitalWrite(GreenArrow2, HIGH);  //  Sets Red2 OFF Green ON
      delay(1000);  // 1 Second of Green
      digitalWrite(GreenArrow2, LOW);
      digitalWrite(Green2LED, HIGH);  //  Sets Green ARROW OFF Yellow ON
      delay(1000);  // 1 Second of Yellow
      digitalWrite(Green2LED, LOW);
      digitalWrite(Yellow2LED, HIGH); // Sets Green 2 OFF YELLOW OFF
      delay(1000);
      digitalWrite(Yellow2LED, LOW);
      digitalWrite(Red2LED, HIGH);

       digitalWrite(Red1LED, LOW);
      digitalWrite(GreenArrow, HIGH);
      delay(1000);
      digitalWrite(GreenArrow, LOW);  //  Sets Yellow1 OFF Red ON
      digitalWrite( Green1LED, HIGH);
    }
      else {
       digitalWrite(Red1LED, LOW); // When the Red condition is met, the Green LED should turn off
      digitalWrite(Red2LED, HIGH);
      digitalWrite(GreenArrow, LOW);
      digitalWrite(Green1LED, HIGH);
      digitalWrite(Yellow1LED, LOW);
      digitalWrite(Yellow2LED, LOW);
      digitalWrite(Green2LED, LOW);
      digitalWrite(GreenArrow2, LOW);

      }
    }

I NEED HELP ASAP PLEASE. Due tomorrow by 12 am. It is extension so I am not that worried if I don't get help by the deadline but if I still do after the deadline I can still learn so don't hesitate to post.

body:
Thank you for making it clear that this is course work.
You are asking for help to do the extension, but by your own words you don't understand how the core code works.  I have to be honest I can't be bothered to read the code, it looks horrible.  If I was your teacher I would quit, because I have failed to teach you one of the most fundamental aspects of coding.  "You write it once but it gets read many times", it is ALWAYS worth spending a few minutes making the code look pretty!  (If you teacher can't be bothered to read it, you aren't going to get 100%!)

1. Comments - commenting out code is not the best use for // explaining __why__ you are doing what you are doing is.

2. Its good that you have defined variables to identify you pins, but you have two identical sets of variables, so you could have used an array, a structure or an array of structures.  (These might be more advanced than where you are at the moment, sorry if that's the case).

3. Breaking you code down into bite sized pieces make it more readable.  That start of your loop contains some code that could be in a function called `getDistance()`

4. Turning the lights on and off in the way you are doing it is open to errors.  You could turn the red light on and the green light on.  If you made a class to represent the lights then you could have a function that turned off all of the lights and only turned on the one you wanted.  You wouldn't need to store the state.

Example code (not tested or compiled)

    class Lights
    {
      public:
        enum eLight {Red, Amber, Green, GreenArrow, GreenPedestrian, RedPedestrian, eMaxLight};
        Lights(int[] pins)
        {
          for (int l = 0; l < eMaxLight; ++l)
            pinMode (pins[l], OUTPUT);
        }
        ~Lights()
        {}
        void setLight (eLight newLight)
        {
           for (int l = 0; l < eMaxLight; ++l)
             digitalWrite(m_Light[l], LOW);
           digitalWrite(m_Light[newLight], HIGH);
        }
    }

You probably want to look at a state machine.  List all the possible LEGAL combinations and then create a enum with each of those states in and then write a function that moves from a state to the next legal state, you will need conditionals for has the button been pressed.  This should give you a working system with a pedestrian button that hopefully you understand.


message:
Interrupt fires a random number of multiple times for one pulse

This is my first time posting on this forum. I have tried to format this question properly, but let me know if I need to correct anything. I searched to see if someone else had a similar problem, but let me know if someone has already answered this question.

**Overview:** I am sending pulses to my Arduino, but sometimes one single pulse is interpreted as anywhere from 2 to 30 pulses. But after looking at the pulse on an oscilloscope (see Fig. 1) I am not sure why. When I use a really long wire the ratio of false pulses to legit pulses is about 1 to 1. I shortened the length of the wire and improved the situation, so that only 1 in about every 2,000 pulses is registered as a false pulse.

For one test, I added a capacitor to the short wire situation, but that increased the rise time and made the problem worse. I am currently using `attachinterrupt` and have tested the situation with using both a rising and falling edge. Right now, I mainly want to understand how interrupts work on the Arduino in light of my current problem, although I welcome general advice.

1. When I set the interrupt to the falling edge, why does the Arduino still sometimes count 1 pulse as several? The falling edge in the photo, which is for the really long wire case, lasts about 40 microseconds and appears to have a clean break. The pulse remains low for about 80 milliseconds. Could the falling interrupt trigger during the rise time based off the oscillatory behavior shown in Fig. 1? I smoothed out the signal by adding in a 1 nF capacitor, but the Arduino still counted false pulses. So could the rise time period have anything to do with it? I also have a 10k Ohm pullup resistor connected to the Arduino's 5 V for the pulse path.

I have the relevant code attached below. I have much more code as well, but it deals with saving pulseCounts to the SD Card and uploading electricity consumption files through the cell network.

Cheers.

    //Global Variables
    unsigned long pulse_time = 0;
    unsigned long last_pulse_time = 0;
    byte code = 1; //code let's me see if a false pulse was reported for each
    //SD file

    void setup() {
      attachInterrupt(digitalPinToInterrupt(3), onPulse, RISING);
    }

    void onPulse() {
      pulse_time = millis();
      if ((pulse_time - last_pulse_time) > 50 ) {
        Serial.println("Good Pulse");
        pulseCount++;
        last_pulse_time = pulse_time;
      } else {
        Serial.println("Bad Pulse");
        pulseCount++;
        code = 2;
      }
    }

[![Fig. 1: Pulse With Really Long Wire (Counted as multiple pulses)][1]][1]

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

body:
Firstly, unless the processor pin is a Schmitt trigger, increasing capacitance will only make the problem worse by allowing any noise to be interpreted as multiple high-low transitions.  For a CMOS logic input the area around the transition point of 1/2 VDD typical is actually an area of linear operation, not digital.

A Schmitt trigger introduces hysteresis such that when the signal is interpreted as a high level, it must go low by more than the hysteresis to be interpreted as a low level again.  This is accomplished with a bit of positive feedback added to a buffer where the output transition from low to high then pulls the input that much higher or a transition from high to low pulls the input that much lower:

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

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

The red line represents the typical CMOS threshold and the green lines represent the thresholds defined by the hysteresis of the Schmitt trigger.  The hysteresis defines the noise immunity of the input.  Most processors have pins that are equipped with a Schmitt trigger or and external device like a 74HC14 can be used.

Another way to deal with this type of noise is to lock out any transitions within the expected pulse-to-pulse transitions:  Once triggered, no more transitions are allowed until the lock out time expires.


message:
Which container to use?

So for my project, I am measuring heartbeat of a person in a span of 10s. However, as the number of heartbeats may differ for each person, is it wise to use a vector?

body:
No, you don't want a vector, for a number of reasons:

1. There is no "vector" unless you add extra (unsupported) code.
2. Vectors use dynamic memory. Arduinos don't work well with dynamic memory.
3. It's pointless anyway.

Just allocate an array big enough to contain enough timestamps. In a 10 second period, if you get more than 100 beats, the person you are measuring the heart rate of is most likely in a noticeably "unfortunate" state. That's 600bpm. That's entering panicked mouse territory.

Even with that extreme number of beats an array of 100 32-bit values is only 400 bytes.


message:
how can I send a variable to println?

this is my method

    void mensaje_sms()
    {
      string numero = "777777";  // this is my variable
      SIM900.print("AT+CMGF=1\r");
      delay(100);
          SIM900.println("AT+CMGS=\"591"numero"\"");
    //IM900.println("AT+CMGS=\"59177777777\""); //only in this way does it work
          delay(100);
          SIM900.println("SEND NUMERO VARIABLE RODO");
          delay(100);
          SIM900.println((char)26);
          delay(100);
          SIM900.println();
          delay(5000);
          Serial.println("SMS sent successfully");
        }

***how can I send a variable to println?***

body:
Change:

    SIM900.println("AT+CMGS=\"591"numero"\"");

to

    SIM900.print("AT+CMGS=\"591");
    SIM900.print(numero);
    SIM900.println("\"");

Note that only the final call is to `println()` (which just prints a carriage-return character at the end.)


message:
Can a cheap RF module be used for two way communication

Can a cheap RF(transmitter and receiver) module be used for two way communication, not at the same time of course but for example arduino A sends string to be printed on lcd the arduino B receives it and prints it on lcd, then after some time arduino B sends a temperature data back to arduino A, then arduino prints the temperature data on the serial monitor. All of this while arduino A is connected to a transmitter and arduino B is connected a receiver.
[![these are the RF modules i'm using:][1]][1]

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

body: Sure it can.  A transmitter is only a transmitter *while it's actively transmitting*.  And you can have as many receivers as you like.


body:
Each device that will ever transmit anything will need a transmitter. Each device that will ever receive anything, needs a receiver. The devices you show in your question are separate receivers and transmitters, so on Arduino A **and** Arduino B, you will need both a receiver and a transmitter in order to have real, two-way communication between them.

Some RF devices are "Transceivers" which have both a receiver and a transmitter in the same module. Some of these can operate "full-duplex", meaning they can receive at the same time they are transmitting other data (Typically each direction is on a different frequency, but not necessarily.) Most cheap ones are half-duplex, meaning the module can only receive or transmit at any one time.

**ADDITIONAL INFORMATION ABOUT RADIOHEAD**

Your comment mentioned the RadioHead library. I was able to find the documentation on the library and see that it supports a wide range of radio chipsets and modules. The cheap ones you note are simple ones that use OOK (on-off-keying) or ASK (amplitude-shift-keying) and don't actually have a protocol. The receiver simply provide a `HIGH` or `LOW` output if it detects a signal on it's designated receive frequency. The transmitter simply oscillates at the transmit frequency when it's input pin sees a `HIGH` value, and stops when it sees a `LOW` value.

The RadioHead `RH_ASK` class deals with these simple transmitters. The documentation is at http://www.airspayce.com/mikem/arduino/RadioHead/classRH__ASK.html#details

This page notes the way to connect both a transmitter and receiver thus:

    Connecting to Arduino

    Most transmitters can be connected to Arduino like this:

    Arduino                         Transmitter
     GND------------------------------GND
     D12------------------------------Data
     5V-------------------------------VCC

    Most receivers can be connected to Arduino like this:

    Arduino                         Receiver
     GND------------------------------GND
     D11------------------------------Data
     5V-------------------------------VCC
                                      SHUT (not connected)
                                      WAKEB (not connected)
                                      GND |
                                      ANT |- connect to your antenna syetem


message:
How do I isolate numbers in text?

I need to separate numbers from the text where my string of numbers will always be of length 8:

    string text = "77953505HELLO THIS IS A MESSAGE"; //my string of numbers will always be of length 8

###My result

    string number = "77953505"; //my string of numbers will always be of length 8
    string message = "HELLO THIS IS A MESSAGE";

What operation should I use?

this is the job I'm doing

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

    void loop() {
      if (Serial.available() > 0) {

        String Texto = String(Serial.read());

        String number = Texto.substring(0, 7);
        String message = Texto.substring(8);

        Serial.write(number);
        Serial.write(message);
      }
    }

help me!

body:
Depends, and probably better to use C strings:

1. If you know the number is always the same amount of characters, use the C function `strncpy`.

2. You can also split on a delimiter (char), with `strtok`, but in your case this is not possible since you don't know the delimiter character.

3. If the number has a variable length, start copying character by character through the string, until you find a character that gives false for the `isdigit` condition and copy the remainder (with strncpy) to the other string.

**Update after the question's edit**

Since the number of text to be copied is know, strncpy can be used with the following prototype:

    char *strncpy(char *dest, const char *src, size_t n)

In your case put the text in a normal text string:

    char text[80]; /* Assuming max length of text */

Copy it where needed:

    strcpy(text, "77953505HELLO THIS IS A MESSAGE");

Note: it can be done in once like this:

    char text[] = "77953505HELLO THIS IS A MESSAGE";

Than you can copy the items by:

    char number[9]; // Add 1 for \0
    char message[81]; // Assuming max length of message;

    strncpy(number, text, 8);
    strncpy(message, &(text[8]), strlen(text) - 8);

(Note not checked with compiler).

Improvements: use instead of 8 a define e.g.

    #define NUMBER_LENGTH 8

    char number[NUMBER_LENGTH + 1];

    strncpy(number, text, NUMBER_LENGTH);
    strncpy(message, &(text[8]), strlen(text) - NUMBER_LENGTH);

You can do similar for MESSAGE LENGTH

    #define MESSAGE_LENGTH 80

Also, another improvement is not to copy the message, but just set the pointer to the correct place:

    char* message = &(text[8]);

message will point to "HELLO THIS IS A MESSAGE"

like below

    "77953505HELLO THIS IS A MESSAGE"
    |        |
    +-- text |
             +-- message

In an Arduino 80 bytes can be a lot of memory, using two buffers cost 160 bytes, and this way you save at least one buffer.


body:
For a fixed length substring the simple arduino-ish way would be to use [String.substring(left_pos, right_pos)][1]

    String number = text.substring(0, 7);
    String message = test.substring(8); // right_pos is optional

This is not necessarily the best option depending on how you intend to use the resulting substring.  Memory is allocated and the content is copied. Requiring at least double the memory (plus some overhead). If memory is tight you may not want to create a String but use char* instead.

  [1]: https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/substring/


message:
AnalogWrite not working in if statement

Arduino Uno with ATMega328P `Processor.analogWrite` is not working properly in if statement. It changes the brightness of the LED as if there wasn't any if statement at all.

There are 2 potentiometers to create an intervall in which to program increases of the LED brightness, starting at 40% of the maximum. When it's lower than the minimum value, the LED is turned off.

    int ledPin = 6;
    int sensorPot = 1; // it's a potentiometer for now
    int maxPot = 7; // potentiometer
    int minPot = 3; // potentiometer
    int fortypercent = 255*0.4;
    int brightness = 0;

    void setup() {
      pinMode(ledPin, OUTPUT);
      pinMode(sensorPot, INPUT);
      pinMode(maxPot, INPUT);
      pinMode(minPot, INPUT);
      Serial.begin(9600);
    }

    void loop() {
      int start = analogRead(minPot);
      int maxVal = analogRead(maxPot);
      int sensor = analogRead(sensorPot);
      Serial.println(sensor/4);
      Serial.println(start/4);
      Serial.println(maxVal);
      if(sensor/4 > start/4) {
        analogWrite(ledPin,sensor/4);
      } else if(sensor = baslangic) {
        analogWrite(ledPin,LOW);
      } else if ((start < sensor < maxVal)) {
        brightness = sensor/4 - fortypercent;
        analogWrite(ledPin,brightness);
      } else if (sensor = maxVal) {
        analogWrite(ledPin , 255);
      }
    }

body:
**ORIGINAL RESPONSE, BASED ON DIFFERENT CODE**

You are comparing `sensorValue` to see if it's ever less than `minValue`.

However, you have mapped `sensorValue` to range from `0` to `255`, and `minValue` is set at `0`. How can anything from 0-255 be less than zero?

**NEW RESPONSE, BASED ON UPDATED CODE**

One of your `if` statements: `else if(sensor = baslangic)` is not comparing, but assigning `baslangic` to `sensor`. To compare, use `==`.

Your other `if` statement: `else if ((start < sensor < maxval))` is wrong. C++ doesn't work this way. Maybe you want: `if ((start<sensor) && (sensor<maxval))`?

Instead, your statement evaluates like `if ( (start<sensor) < (maxval) )`, which means you are comparing the `TRUE` or `FALSE` of `(start<sensor)` to the `int` that is `maxval`.


message:
How to implement the Arduino Extended Database library in a custom class?

I am struggling to implement a custom class that uses the Arduino Extended Database Library (EDB.h). The purpose of my custom class is to manage my application's internal database.

While searching for a solution I found [this][1], which seems very relevant: the code and goal are the same as mine.

But my problem with that Q&A is that I am not able to implement the given solution as I don't fully understand the way it should be written.

For the sake of trying to give the best support for explanation, I upladed the code below. Feel free to explain me how to modify it.

Thank you.

EDIT: Following duplicate comments, I'll try to be more precise in my question.

  [1]: https://arduino.stackexchange.com/questions/14480/pass-a-member-function-pointer-to-a-method-of-a-foreign-class-edb-lib

body:
It is difficult to answer this question because I'm not sure what you have managed to achieve.  Sorry if some of it seems a bit basic.

Look at Majenko's answer to the question.  If you want to use this EDB class then you need to define two functions:

      void configWriter( unsigned long address, byte data );
      byte configReader( unsigned long address );

You need to be able to access the **single instance** of these functions from anywhere in the code, so the need to have global scope.  When they are global you can assign them to pointers by using the function name and no brackets/parenthesis.  i.e.

    aPtr = configWriter;

So the call to create the EDB instance would be:

     configDB = new EDB( configWriter, configReader );

Now you could create the EDB instance using a class member function.  To do this you have to make the function a `static` member, which means it has no access to the class's data. (in its simplest terms static means there is only one of the things it is referring to) i.e.

    class myEDB
    {
      public:
        static void configWriter( unsigned long address, byte data );
        static byte configReader( unsigned long address );
    ...
    };
    configDB = new EDB( myEDB::configWriter, myEDB::configReader );

Essentially its the same thing, but the code is compartmentalised better and you end up with neater code.

However, if you are only ever going to have one instance of the myEDB class then you can have a static member variable that hold the value of `this`.  You set this value in the class constructor.

    class myEDB
    {
      public:
        static void configWriter( unsigned long address, byte data );
        static byte configReader( unsigned long address );
        myEDB() {pInstance = this;}
      private:
        static myEDB* pInstance = nullptr;
    ...
    };
    configDB = new EDB( myEDB::configWriter, myEDB::configReader );

When configReader or configWriter is called it checks to see if the member `pInstance` has a non null value, if it doesn't then it creates a new instance.  The then use this `pInstance` to access the functions and variables for the instance of the class.  (This is the design pattern for a single instance class or singleton).

**SO** what should **YOU** do?

Start simply, define two global functions that do what you need as per the top of this answer.  If you get stuck, if you need more info feel free to ask or comment.


message:
Receive data from Arduino board to Android application

I'm trying to receive data and print it on a label of my application, but I can not get it. Actually, I have 0 experience with Arduino. It's the first time I see this. I read this [tutorial to receive data from an Arduino.][1] In my Arduino I have this code:

    #include <SoftwareSerial.h>
    const int RX_PIN = 2;
    const int TX_PIN = 3;
    SoftwareSerial blueTooth(RX_PIN, TX_PIN);
    char commandChar;

    void setup () {
      Serial.begin(57600);
      Serial.println("Let's start!");
      blueTooth.begin(9600);
      blueTooth.println("Hello, world?");
    }

    void loop () {
     if (blueTooth.available())
        Serial.write(blueTooth.read());
      if (blueTooth.available())
        blueTooth.write(Serial.read());
    }

My Android code is this:

    public class MainActivity extends AppCompatActivity {
    FrameLayout frame;
    GifImageView imagen;
    TextView mensaje,debug;
    Button boton;
    private TextToSpeech talk;
    public static StringBuilder sb;
    private static final String TAG = "conexionBluetooth";
    ConnectedThread mConnectedThread;
    BluetoothAdapter blueAdapter;
    BluetoothDevice mDevice;
    BluetoothSocket mSocket;
    Handler handler;

    final int MENSAJE_RECIBIDO = 1;
    final UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private static String MAC = "00:21:13:02:EA:07";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        setContentView(R.layout.activity_main);
        talk = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int i) {
                if(i == TextToSpeech.SUCCESS){
                    talk.setLanguage(Locale.US);
                    mensajeInicio();
                }
            }
        });
        debug = (TextView) findViewById(R.id.debug);
        mensaje = (TextView) findViewById(R.id.mensajeApp);
        frame = (FrameLayout) findViewById(R.id.androidIc);
        imagen = (GifImageView) findViewById(R.id.imageBluethoot);
        imagen.setVisibility(View.INVISIBLE);
        frame.setVisibility(View.VISIBLE);
        boton = (Button) findViewById(R.id.botonInicio);
        Animation flotarArriba = new TranslateAnimation(
                TranslateAnimation.ABSOLUTE, 0f,
                TranslateAnimation.ABSOLUTE, 0f,
                TranslateAnimation.RELATIVE_TO_PARENT, 0f,
                TranslateAnimation.RELATIVE_TO_PARENT, 0.05f
        );
        flotarArriba.setDuration(1000);
        flotarArriba.setRepeatCount(-1);
        flotarArriba.setRepeatMode(Animation.REVERSE);
        flotarArriba.setInterpolator(new LinearInterpolator());
        mensaje.setAnimation(flotarArriba);
        boton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                boton.setEnabled(false);
                mConnectedThread.write("0");
                Toast.makeText(getApplicationContext(),"Data send to arduino",Toast.LENGTH_LONG).show();
            }
        });
        handler = new Handler(){
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case MENSAJE_RECIBIDO:
                        byte[] readBuf = (byte[]) msg.obj;
                        String strIncom = new String(readBuf, 0, msg.arg1);
                        sb.append(strIncom);
                        int endOfLineIndex = sb.indexOf("\r\n");
                        if (endOfLineIndex > 0) {
                            String sbprint = sb.substring(0, endOfLineIndex);
                            sb.delete(0, sb.length());
                            debug.setText(sbprint);
                            boton.setEnabled(true);
                        }
                        //Log.d(TAG, "...String:"+ sb.toString() +  "Byte:" + msg.arg1 + "...");
                        break;
                }
        }};
        configBluetooth();
        comprobarEstadoBluetooth();
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "...onResume - try connect...");

        BluetoothDevice device = blueAdapter.getRemoteDevice(MAC);

        try{
            mSocket = crearSocket(device);
        } catch (IOException e) {
            Toast.makeText(getApplicationContext(),"ERROR!! No se ha logrado crear el enchufe! " + e.getMessage(),Toast.LENGTH_LONG).show();
            finish();
        }

        blueAdapter.cancelDiscovery();

        Log.d(TAG, "...Connecting...");
        try{
            mSocket.connect();
            Log.d(TAG,"Connection OK!!");
        } catch (IOException e) {
            try{
                mSocket.close();
            } catch (IOException e1) {
                Toast.makeText(getApplicationContext(),"Error fatal en el metodo onResume. Incapaz de cerrar conexion: " + e1.getMessage(),Toast.LENGTH_LONG).show();
                finish();
            }
        }
        mConnectedThread = new ConnectedThread(mSocket);
        mConnectedThread.start();
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.d(TAG, "...In onPause()...");
        try {
            mSocket.close();
        } catch (IOException e) {
            Toast.makeText(getApplicationContext(),"Error fatal en el metodo onPause. Incapaz de cerrar conexion: " + e.getMessage(),Toast.LENGTH_LONG).show();
        }
    }

    private void enable() throws IOException {
            boton.setText(getString(R.string.finalizar));
            mensaje.setText(getString(R.string.mensajeActivo));
            frame.setVisibility(View.INVISIBLE);
            imagen.setVisibility(View.VISIBLE);
            mensaje2();
            boton.setText(getString(R.string.iniciar));
            mensaje.setText(getString(R.string.pontelos));
            frame.setVisibility(View.VISIBLE);
            imagen.setVisibility(View.INVISIBLE);
            mensaje1();

    }

    private void mensajeInicio(){talk.speak(getString(R.string.app_name) + getString(R.string.textApp) + getString(R.string.pontelos),TextToSpeech.QUEUE_FLUSH,null);}
    private void mensaje1(){talk.speak(getString(R.string.pontelos),TextToSpeech.QUEUE_FLUSH,null);}
    private void mensaje2(){talk.speak(getString(R.string.mensajeActivo),TextToSpeech.QUEUE_FLUSH,null);}

    private void configBluetooth(){
        Toast.makeText(getApplicationContext(),"Metodo llamado",Toast.LENGTH_LONG).show();
        blueAdapter = BluetoothAdapter.getDefaultAdapter();
        if(blueAdapter != null){
            Set<BluetoothDevice> pairedDevices = blueAdapter.getBondedDevices();
            if(pairedDevices.size() > 0){
                for(BluetoothDevice device: pairedDevices){
                    if(device.getName().equals("HC-06")) {
                        mDevice = device;
                        Toast.makeText(getApplicationContext(), "Nombre del dispositivo: " + mDevice.getName() +
                                "\nDireccion MAC: " + mDevice.getAddress() + ".", Toast.LENGTH_LONG).show();
                    }
                }
            }
        }
    }

    private void comprobarEstadoBluetooth(){
        if(blueAdapter == null){
            Toast.makeText(getApplicationContext(),"ERROR!!! No hay soporte Bluetooth!",Toast.LENGTH_LONG).show();
            finish();
        }else{
            if(blueAdapter.isEnabled()){
                Toast.makeText(getApplicationContext(),"Bluetooth encendido. . .",Toast.LENGTH_LONG).show();
            }else{
                Intent activarBTH = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(activarBTH, 1);
            }
        }
    }

    private BluetoothSocket crearSocket(BluetoothDevice device) throws IOException {
        if(Build.VERSION.SDK_INT >= 15){
            try{
                final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class });
                return (BluetoothSocket) m.invoke(device, uuid);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return device.createRfcommSocketToServiceRecord(uuid);
    }

    private class ConnectedThread extends Thread {
        private final InputStream mInStream;
        private final OutputStream mOutStream;

        public ConnectedThread(BluetoothSocket socket) {
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the input and output streams, using temp objects because
            // member streams are final
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) { }

            mInStream = tmpIn;
            mOutStream = tmpOut;
        }

        public void run() {
            byte[] buffer = new byte[256];  // buffer store for the stream
            int bytes; // bytes returned from read()

            // Keep listening to the InputStream until an exception occurs
            while (true) {
                try {
                    // Read from the InputStream
                    bytes = mInStream.read(buffer);        // Get number of bytes and message in "buffer"
                    handler.obtainMessage(MENSAJE_RECIBIDO, bytes, -1, buffer).sendToTarget();     // Send to message queue Handler
                    handler.handleMessage(new Message());
                } catch (IOException e) {
                    break;
                }
            }
        }

        /* Call this from the main activity to send data to the remote device */
        public void write(String message) {
            Log.d(TAG, "...Data to send: " + message + "...");
            byte[] msgBuffer = message.getBytes();
            try {
                mOutStream.write(msgBuffer);
            } catch (IOException e) {
                Log.d(TAG, "...Error data send: " + e.getMessage() + "...");
            }
        }
    }
    }

I notice the following behaviors:

 - The application does not crash when it is executed.
 - When I start the application, the bluetooth module of the Arduino flashes differently. (I guess it's because my app connectswith the board).
 - Inside the Log Cat, it can be seen that the connection has been made correctly. . .

[![enter image description here][2]][2]

What could be missing here to print the data received from the Arduino? I do not know if it's me, or the handler method never runs. (public void handleMessage (Message msg))

Also note that in the serial monitor of the Arduino, the value that I command when pressing the button of the application is never printed...

**UPDATE**

Investigating on the internet about the module of my Bluetooth (HC-06) I found that;

 - If the light of the module is constantly flashing, it is not paired
   with the phone.
 - If the module light stays on, then it is already connected.

My concern is that when I open my application, to blink constantly, it blinks much slower. . . Could it be that I've never been able to connect?

  [1]: http://solderer.tv/data-transfer-between-android-and-arduino-via-bluetooth/
  [2]: https://i.stack.imgur.com/Ypnrx.png

body:
I don't think your code is correct:

    void loop () {
     if (blueTooth.available())
        Serial.write(blueTooth.read());
      if (blueTooth.available())         <----
        blueTooth.write(Serial.read());
    }

Shouldn't you be monitoring Serial.available on this line?


body:
I could solve it already !!!! It turns out that the bluetooth module was badly connected to the arduino !!!! I can already receive data! thank you very much for your comments, especially chrisl, for your suggestion to use the bluetooth serial monitor app! :)

I had connected the VCC to 5V ... that was what was bothering me, I read on the web that if you have it in 5V, as a self defense, the RX pin is completely blocked. The VCC must be connected to 3.3V.

**EDIT:** I forgot something very important! had to change the baud of bluetooth to 9600 like Serial! this part was very important too.


message:
Add a watermark to text message in an Arduino

I'm trying to add a watermark to the text in the Arduino and there are several levels of watermarks (fragile, semi-fragile, robust). What is the difference between these levels in terms of algorithms used?

body:
"Robustness", in the context of digital watermarking, specifies the ability to detect the watermark after some signal processing modification (for images, this might be translation, rotation, scaling, compression, etc.) Some digital watermarking techniques are robust against some operations but not against others. The classifications are:

 - **Robust**: The watermark should be able to survive against any and all
   modification. This is often used in copyright protection, for
   example.
 - **Fragile**: This kind of watermark is designed to be destroyed by any
   modification to the original. This allows any manipulation, even
   slight changes, to be detected. Fragile watermarks are generally used
   to enable authentication and integrity verification.
 - **Semi-fragile**: The watermark should be "robust" against certain,
   defined, modifications, but "fragile" against others. In other words,
   the watermark should survive intact under the operations you want to
   allow, but be destroyed by anything else. Again, these are used to
   enable authentication.

<hr>

For more information, you might find the 2005 paper [A Review Study on Digital Watermarking][1] by L. Jian and H. Xiangjian (in the journal *Information and Communication Technologies*) useful.

  [1]: https://ieeexplore.ieee.org/document/1598615/


body:
Watermarking is used to detect changes against the original source. In images this is done by changing some pixels, almost invisible to see, but enough to check the source or see if changes have been made.

For text this is not possible normally, since changing the text will visible change the output (when you print it).

Instead a so called CRC (cyclic Redundancy Code) is used and stored separately. E.g. a certain text has a specific CRC code. When the code is changed, the CRC code should be changed too. But if someone only changes the text, you can check the text against the (unchanged/encrypted) CRC code to see it has been mangled with.


message:
Ultrasonic Sensor receiving Side

I'm doing my project regarding 40khz ultrasonic sensor which will be used to get accurate distance measurements. I have a separate transmitter and receiver. I want to get the time between the moment my transmitter transmitted the waves and the time my receiver received it. However, I couldn't actually make it work. Does any of you give me a code that would help me transmit and receive the 40khz waves and get the time in between so I could use it to compute for the distance?Thank you in advance. I would greatly appreciate it!

body:
I don't have 'a code', but what you can do is using a timer set to 40 kHz and send the pulses you need. .

If nothing else needs to be done (nor in the future) you can use a delay function.

Also check the pulseIn function from Arduino, you can use this convenience function for the checking the result.


body:
This is the most basic ultrasound pulse and receive code. I wrote it to work with the `HC-SR04` modules; so hopefully it will work fro you too as those also sound at `40khz`.

The main functionality comes from the [`pulseIn()`](https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/) funciton.

    #define TRIGPIN 9
    #define ECHOPIN 10

    void setup() {
      Serial.begin(9600);
      pinMode(TRIGPIN, OUTPUT);
      pinMode(ECHOPIN, INPUT);
    }

    void loop() {
      digitalWrite(TRIGPIN, HIGH);
      delayMicroseconds(10);
      digitalWrite(TRIGPIN, LOW);

      uint16_t duration = pulseIn(ECHOPIN, HIGH, 4000);
      int distance = (duration*.0343)/2;
      Serial.println(distance);
    }

---

Note that you will need to adjust the `4000` (`μs`) to whatever timeout in you want (or emit entirely if you don't want it).


message:
ToF VL53L1X sensor integrate with arduino

I have this latest version VL53L1X time of flight laser distance sensor: http://www.st.com/en/imaging-and-photonics-solutions/vl53l1x.html

I study about this sensor, It says that sensor only Access with API(Application program Interface) how do I Integrate that API code in arduino or
how do I use Wire library to Integrate this sensor.

body:
<s>There's actually a library created by Pololu that is quite straightforward to use so you don't need to worry about any of that. I think it covers all available functionality.
https://github.com/pololu/vl53l0x-arduino

I was also a bit confused by the API comment and the datasheet.</s>

I misread the device name so the above is not relevant.

In theory I think to use the API you can just #include the C code they provide into your sketch like a normal library. You can download the API code from the manufacturer ST here.
You'll need to give your name and email but it's free.
It's in C but you can probably understand it if you're familiar with Arduino/C++.

Before compiling you would also need to implement some I2C functions for which they provide prototypes (in the vl53l1_platform.c file). However, I think there are some additional steps when using C files that you will need to take to get this to compile, unfortunately I am not familiar with this so can't help - if anyone does then they can probably write a more complete answer.

The alternative is to write your own functions that replicate the functionality that is described in the API.
I would do this by looking at the basic process flow in the API User Manual, taking each function and working through the API files to see what it does.
The main thing you're looking for is the registers that you need to write (via I2C) in order to trigger a range measurement starting, and then the registers that you need to read to find out the result.
I would note that there are multiple levels of #defines for some of the register values and there is a lot of code that deals with managing the status of the device, so this might take a while.


message:
Camera on mkr1000 or nodemcu 0.9

My question is: it is possible to connect camera on an Arduino/Genuino [mkr1000][1] or to a [NodeMCU][2] 0.9?

If yes which one?

As far as I now [ArduCam][3] OV2640 has ported a library for ESP8266 (that is the chip inside the nodemcu)? Where can I find it and how does I plug the camera to the board?

Reading the camera user guide I've found that:

> The ArduCAM mini can be used in any platforms like Arduino, [...] as long as they have SPI and I2C interface

Does one of these 2 board have both [SPI][4] and [I2C][5] interfaces

EDIT: Here I list my personal search with possible interesting results:

 - Here is a [guide of arducam on ESP8266 module ESP-12E][6] (My nodemcu is ESP-12)
 - Here [another guide for ESP8266-12E][7]

I hope that can be useful the wiring scheme to ESP8266-12E

         ArduCAM mini   ->    ESP8266-12E
             CS         ->        D0
            MOSI        ->        D7
            MISC        ->        D6
             SCK        ->        D5
             GND        ->       GND
             VCC        ->       3V3
             SDA        ->        D2
             SCL        ->        D1

  [1]: https://store.arduino.cc/arduino-mkr1000
  [2]: https://en.wikipedia.org/wiki/NodeMCU
  [3]: http://www.arducam.com/arducam-supports-esp8266-arduino-board-wifi-websocket-camera-demo/#more-1093
  [4]: https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
  [5]: https://en.wikipedia.org/wiki/I²C
  [6]: https://cdn.instructables.com/ORIG/F9W/40DH/ILJSHKZK/F9W40DHILJSHKZK.pdf
  [7]: http://www.instructables.com/id/ArduCAM-Mini-ESP8266-Web-Camera/

body:
There are a couple of levels of names in your question, so here are how they fit together:

**ESP8266** - This is the bare chip found in the wide range of "esp8266"-based boards/modules/etc. The chip itself has no flash storage, no clock/oscillator, and no voltage regulation.

The I/O pins on the ESP8266 bare chip have labels like `GPIO0`, `GPIO1`, etc.

[![Chip outlined in Red is the ESP8266][1]][1]

Chip outlined in Red is the ESP8266 alone.

So, to be of much use, the chips are often found on other modules along with flash memory, an oscillator, perhaps voltage regulation, a PCB antenna for the wifi portion, etc.

A popular "brand" of such module is the **[AI-Thinker][2]** modules, with names like

 1. ESP-01
 2. ESP-07
 3. ESP-12
 4. ESP-12E
 5. ESP-12F

The different modules have different PCB sizes, but most notably, different numbers of pins from the actual ESP8266 chip brought out to the module's pins.

These often also call the I/O pins names like `GPIO0`, `GPIO1`, etc.

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

These ESP-xx modules, in turn, are often incorporated into larger modules that then add a USB-serial chip, LEDs, etc. One popular line are the [NodeMCU][4] series.

These modules provide different names for the I/O pins. **NodeMCU** in particular uses `D0`, `D1`, etc. and these don't correspond to the same numeric suffix as the bare chip. [This chart][5] gives the mappings for NodeMCU modules.

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

**ANSWER**

Thus, in the [web page you linked about the ArduCAM and ESP8266][7], you can see a chart on the Hardware Connection of the the ArduCAM pins, and equivalent pins for both the NodeMCU-style pin names, and also the AI-Thinker and bare chip pin names.

The ESP-12 and ESP-12E both have the exact same ESP8266 chip inside, and the same amount of flash memory. There is no difference between them as far as connecting to the ArduCAM is concerned. The ESP-12E has a few more pins brought out to the headers than the ESP-12.

So, as long as you have D0, D1, D2, D5, D6, and D7 on a NodeMCU, **OR** GPIO4, GPIO5, GPIO12, GPIO13, GPIO14, and GPIO16 on the AI-Thinker module, then you can hook up the ArduCAM, as these are all the pins described in the hookup table.

  [1]: https://i.stack.imgur.com/fYMHF.jpg
  [2]: https://www.esp8266.com/wiki/doku.php?id=esp8266-module-family
  [3]: https://i.stack.imgur.com/AVwG2.jpg
  [4]: https://en.wikipedia.org/wiki/NodeMCU
  [5]: https://nodemcu.readthedocs.io/en/latest/en/modules/gpio/
  [6]: https://i.stack.imgur.com/0UbS1.jpg
  [7]: http://www.arducam.com/arducam-supports-esp8266-arduino-board-wifi-websocket-camera-demo/#more-1093


message:
Connecting CAT5 robustly between portable Arduino and more portable sensors

Newbie wiring question. I’m building a lightwand of some sort, involving an RGB LED and a few pushbuttons that I want to wave around (the “remote”), while staying connected over ~0.5 - 3m to an Uno (the “head”).

In a portable incarnation, the remote might be on your finger and the battery-operated head in your backpack. I’m hoping to use stranded CAT5 for the connection between them (“the bridge”) — it’s the right number of conductors, good flexibility, I have lots of it.

My question is: how should I best mate the CAT5 to both ends — pins on the Arduino at the head, and pins or bare wire off my LED and switches at the remote?

At the head, I like the idea of an RJ45 jack (“NOT ETHERNET”), both for modularity and as I’m a bit worried about strain on the cable pulling wires out of Arduino pins. (The jack basically gives me a good interface at the enclosure level.) I could get an RJ45-to-wiring-terminal-block, and then run solid jumpers from the block to the pins, but they’re expensive. I could try a keystone jack and just try using solid jumpers rather than more CAT5 going between the jack’s wire-breakout and the Arduino board — but I worry the jumpers won’t be the right “size” for the jack, and I’m worried about flimsiness. (If the entire head enclosure is in your backpack, it’s going to get jostled. I want something durable.)

I see some examples of an RJ45 jack soldered directly to a board. What sort of RJ45 is that, and could I do that and solder straight to the board pins on a cheap shield, with relatively novice soldering skills? Or is this at risk when people yank the cable inadvertently?

As I said: I’m a newbie, don’t know what’s reasonable, and keep coming up with overcomplicated architectures where the CAT5e connects to a jack to a block to jumpers to pins,  etc. etc.

At the remote, I think I’m better off. Things need to be as small/portable as possible, so I think I bring the bare stranded wire out of the CAT5e onto a tiny bit of board, and just solder the strands directly to the leads coming off my buttons and LED, and wrap some tape around it, then attach the whole thing to a glove or a bracelet to keep it relatively immobile at the end of the cable. Ok or terrible?

Thanks for suggestions, directions, and other help. I’ve looked around and don’t see questions at this level of ignorance. One of the answers to [this](https://arduino.stackexchange.com/questions/18701/connect-ethernet-cable-wires-directly-to-pins) mentions that “people wire a RJ45 sock directly to an Arduino” (my head problem) but doesn't say exactly how.  https://arduino.stackexchange.com/questions/18813/how-can-i-attach-sensors-without-a-shield-for-a-wearable-project/18894#18894 is doing what I want, but also underspecified...

body:
Certainly go for RJ45 sockets.  Not only does it help protect the wire, but it gives you a really easy way of swapping the wire for different lengths should you want to.

You can't solder an RJ45 socket directly to a normal prototyping board. The pins aren't in the right pattern.  So, you could go for something like [this](https://www.amazon.co.uk/Connector-Breakout-Ethernet-DMX-512-Unassambled/dp/B0120Q1WSU)

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

That can then either be soldered to wires or, since the pins are now in a normal 0.1" pitch, solder the whole module to a prototype board or shield.

Be sure you get a vanilla RJ45 socket, not a "MagJack", which contains extra Ethernet-specific electronics inside it.

If you do want to solder the wires directly to a PCB simply drill a couple of holes just in from one edge of the PCB, run the cable between them, and strap a cable tie around it.  Here's an example:

[![enter image description here][2]][2]

That PCB has specially shaped slots designed into it for the cable tie.

Also, for soldering, you want a good quality cable. A cheap one from eBay will most likely be made of aluminium with a thin plating (if you're lucky) of copper. A better quality one will be made entirely of copper. Aluminium cables don't solder well. Fine for crimping to an RJ45 plug, but rubbish for soldering.

  [1]: https://i.stack.imgur.com/KGSO3.jpg
  [2]: https://i.stack.imgur.com/5PGP7.png


message:
I need help with code for two 74HC595

I created and learned this code myself from many examples. I tried to add another chip to it, but I have no idea. Do I need to rewrite all of it? Just some simple code is needed.

    int latchPin = 2;
    int dataPin = 3;
    int clockPin = 4;
    const int analogPin = A0;
    const int ledPin = 13;
    const int EmptyEn = 0;
    const int GreenOne = 100;
    const int GreenTwo = 200;
    const int GreenThree = 300;
    const int GreenFour = 400;
    const int YellowOne = 500;
    const int YellowTwo = 600;
    const int RedOne = 750;
    const int RedTwo = 900;
    const int MaxHold = 1000;

    void setup() {
      pinMode(ledPin, OUTPUT);
      Serial.begin(9600);
      pinMode(latchPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
    }

    void loop() {
      int analogValue = analogRead(analogPin);
      if (analogValue > GreenOne) {
        digitalWrite(latchPin, LOW);
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
        digitalWrite(latchPin, HIGH);
        delay(1);
      }
      if (analogValue > GreenOne) {
        digitalWrite(latchPin, LOW);
        shiftOut(dataPin, clockPin, MSBFIRST, B10000000);
        digitalWrite(latchPin, HIGH);
        delay(1);
      }
      if (analogValue > GreenTwo) {
        digitalWrite(latchPin, LOW);
        shiftOut(dataPin, clockPin, MSBFIRST, B11000000);
        digitalWrite(latchPin, HIGH);
        delay(1);
      }
      if (analogValue > GreenThree) {
        digitalWrite(latchPin, LOW);
        shiftOut(dataPin, clockPin, MSBFIRST, B11100000);
        digitalWrite(latchPin, LOW);
        delay(1);
      }
      if (analogValue > GreenFour) {
        digitalWrite(latchPin, HIGH);
        shiftOut(dataPin, clockPin, MSBFIRST, B11110000);
        digitalWrite(latchPin, LOW);
        delay(1);
      }
      if (analogValue > YellowOne) {
        digitalWrite(latchPin, LOW);
        shiftOut(dataPin, clockPin, MSBFIRST, B11111000);
        digitalWrite(latchPin, HIGH);
        delay(1);
      }
      if (analogValue > YellowTwo) {
        digitalWrite(latchPin, LOW);
        shiftOut(dataPin, clockPin, MSBFIRST, B11111100);
        digitalWrite(latchPin, HIGH);
        delay(1);
      }
      if (analogValue > RedOne) {
        digitalWrite(latchPin, LOW);
        shiftOut(dataPin, clockPin, MSBFIRST, B11111110);
        digitalWrite(latchPin, HIGH);
        delay(1);
      }
      if (analogValue > RedTwo) {
        digitalWrite(latchPin, LOW);
        shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
        digitalWrite(latchPin, HIGH);
        delay(1);
      }
      if (analogValue > MaxHold) {
        digitalWrite(latchPin, LOW);
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
        digitalWrite(latchPin, HIGH);
        delay(100);
      }
      Serial.println(analogValue);
      delay(1);
    }

body:
Look for a repetition in your code.

      //Repeating code..
      if (analogValue > GreenOne) {
        digitalWrite(latchPin, LOW);
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000 );
        digitalWrite(latchPin, HIGH);
        delay(1);
      }

      if (analogValue > GreenTwo) {
        digitalWrite(latchPin, LOW);
        shiftOut(dataPin, clockPin, MSBFIRST, B10000000 );
        digitalWrite(latchPin, HIGH);
        delay(1);
      }

You will notice that you have a lot of repetition of the general structure of a if-comparison (always with a different value) and then a `shiftOut` with a different value to be shifted out.

      //General code structure
      //Only things to change is someComparisonValue and someDataValue
      //the rest is the same.
      if (analogValue > someComparisonValue) {
        digitalWrite(latchPin, LOW);
        shiftOut(dataPin, clockPin, MSBFIRST, someDataValue);
        digitalWrite(latchPin, HIGH);
        delay(1);
      }

You can generalize and simplify the code by storing those different comparison values and data values in a look-up table (LUT). Now you could use two arrays to hold these values but you could also further condense it in a C `struct`, a "data structure".

 Let's define a data structure which holds a threshold value and then the data to be shifted out as  `struct`.

    /* Defines a LUT entry */
    struct LutEntry {
     int treshhold; /* threshhold value */
     byte data;  /* data to be shifted out */
    };

We can then pack the actual data into a single variable. Because this is constant data, it will take up flash memory instead of RAM.

    static const LutEntry lutTable[] = {
     { GreenOne, B00000000},
     { GreenOne, B10000000},
     { GreenTwo, B11000000},
     { GreenThree, B11100000},
     { GreenFour, B11110000},
     { YellowOne, B11111000},
     { YellowTwo, B11111100},
     { RedOne, B11111110},
     { RedTwo, B11111111},
     { MaxHold, B00000000}
    };

From there we can also see that there is a computable relationship between the index of the treshhold value and the data to be shifted out - an entry at index `i` will be associated with the `data` bitstring in which all bits from the MSB up to `i` inclusive are `1`, the rest being `0`. Except for `MaxHold` as special value. We could exploit this property to get rid of that `data` member entirely, but that is an exercise left to you.

Now we can re-write the `loop` code by simply taking a `analogRead` sample and then iterating through the entires of the LUT to shift out the corresponding data.

    void loop() {
     int analogValue = analogRead(analogPin);
     int numLutEntries = (int)(sizeof(lutTable) / sizeof(lutTable[0]));

     for(int i=0; i < numLutEntries; i++) {
      if (analogValue > lutTable[i].treshhold) {
       digitalWrite(latchPin, LOW);
       shiftOut(dataPin, clockPin, MSBFIRST, lutTable[i].data);
       digitalWrite(latchPin, HIGH);
       delay(1);
      }
     }
        Serial.println(analogValue);
        delay(1);
    }

Which transforms 69 lines of repeating code into 12 lines of non-repeating code.

After this general code cleanup it becomes easier to add another shift register: You can define a new look up table, or modify the structure of the old one, to hold the information you need (treshholds, data to be shifted out, the clock, data and latch pin for the register, ...). What logic needs to be there is something only you know, because the description "add another chip [to this code]" is quite broad.

In short:

* **DRY**: Don't repeat yourself. If you use a piece of code over and over again with only slight variances in used values, make it a function
* recognize the differences of the used data values in used code pieces and try to group them neatly together. Use the language feature of `structs` or `class` to express the meaning of this data
* exploit certain properties / relationships of your data to save even more memory / computing time.


message:
PROGMEM Corrupted Array

I am trying to store a large number of values into a couple of arrays using PROGMEM, but I am finding that a few of the values are read back corrupted. I am storing just 1s and 0s, but when I read these values back, I will sometimes get values greater than 1. I am using a MEGA 2560 to do this.

    // Each array contains 32000 values
    const byte VALUES_1[] PROGMEM = { 1, 0, 1, .... 0 };
    const byte VALUES_2[] PROGMEM = { 1, 1, 0, .... 0 };
    const byte VALUES_3[] PROGMEM = { 1, 0, 1, .... 1 };
    const byte VALUES_4[] PROGMEM = { 1, 0, 1, .... 1 };
    const byte VALUES_5[] PROGMEM = { 1, 0, 1, .... 1 };

    const long ARR_LEN = 32000;
    long index = 0;

    void setup() {
      Serial.begin(57600);
      while (!Serial) {}
    }

    byte readNextValue() {
      if (index >= 160000L) {
        return -1;
      }

      Serial.print(index);
      Serial.print(" ");

      long arr = index / ARR_LEN;
      long i = index % ARR_LEN;
      index++;

      byte j = -1;
      switch(arr) {
        case 0:
          j = pgm_read_byte_far(VALUES_1 + i);
          Serial.println(j);
          return j;
        case 1:
          j = pgm_read_byte_far(VALUES_2 + i);
          Serial.println(j);
          return j;
        case 2:
          j = pgm_read_byte_far(VALUES_3 + i);
          Serial.println(j);
          return j;
        case 3:
          j = pgm_read_byte_far(VALUES_4 + i);
          Serial.println(j);
          return j;
        case 4:
          j = pgm_read_byte_far(VALUES_5 + i);
          Serial.println(j);
          return j;
      }

      Serial.println("Unable to return next value");
      return -1;
    }

    void loop() {
      // put your main code here, to run repeatedly:
      readNextValue();
    }

What I have noticed is that when I use `pgm_read_byte_far` for `case 0` I will get garbage values for right away, but using `pgm_read_byte_near` will cause these garbage values to occur sometime later. Any insight to this problem is appreciated.

body:
Just a follow up in case someone else has the same problem. One solution is Nick's answer in his comment, which grabs the far addresses first in the setup, storing them in an array, and using them. I

    // Each array contains 32000 values
    const byte VALUES_1[] PROGMEM = { 1, 0, 1, .... 0 };
    const byte VALUES_2[] PROGMEM = { 1, 1, 0, .... 0 };
    const byte VALUES_3[] PROGMEM = { 1, 0, 1, .... 1 };
    const byte VALUES_4[] PROGMEM = { 1, 0, 1, .... 1 };
    const byte VALUES_5[] PROGMEM = { 1, 0, 1, .... 1 };

    long VALUES[] = { 0, 0, 0, 0, 0 };

    const long ARR_LEN = 32000;
    long index = 0;

    void setup() {
      Serial.begin(57600);
      while (!Serial) {}

      VALUES[0] = (long) pgm_get_far_address(VALUES_1);
      VALUES[1] = (long) pgm_get_far_address(VALUES_2);
      VALUES[2] = (long) pgm_get_far_address(VALUES_3);
      VALUES[3] = (long) pgm_get_far_address(VALUES_4);
      VALUES[4] = (long) pgm_get_far_address(VALUES_5);
    }

    byte readNextValue() {
      if (index >= 160000L) {
        return -1;
      }

      Serial.print(index);
      Serial.print(" ");

      long arr = index / ARR_LEN;
      long i = index % ARR_LEN;
      index++;

      byte j = pgm_read_byte_far(VALUES[arr] + i);
      Serial.println(j);

      return j;
    }

    void loop() {
      // put your main code here, to run repeatedly:
      readNextValue();
    }

This runs perfectly with all bytes correct. The better answer would be to convert the bytes into bits like everyone else was saying in order to save memory space.


message:
Arduino + nRF24L01 + ESP8266 mod

I was wondering if it is possible to connecting two Arduino boards with each other (Uno + Nano) using an ESP8266 mod on one of them and an nRF24L01 on the other board?

I have seen lots of details of connecting two nRF but couldn't find any about ESP talking to nRF.

body:
No. That would be like trying to connect your TV to your microwave. Both RF devices, but both work different ways and do different things.

Just because they are both rectangular boxes with a window in the front doesn't mean they are the same.


body:
No, that is not possible: the ESP8266 is a WiFi SoC, and the nRF24L01 uses a proprietary protocol.
The fact that they both operate in the same frequency range doesn't matter if the protocols are different.


message:
Bluetooth module HC-05 not finding mobile phones, only PC

I put the HC-05 in the AT mode with arduino and the comands:

    AT+CMODE=1
    AT+ROLE=1
    AT+INQM=0,10,48
    AT+CLASS=0
    AT+INIT
    AT+INC

It responds "OK" after all till AT+INC, and after this, shows only my notebook's adress, but it has many other mobile phones near with bluetooth on (I can find with my cell phone) and they are not found. Why? Someone help me please

body:
Bluetooth maybe on, but some phones are "invisible" until you put them in "other Bluetooth devices can find me" -mode.

Current iPhones are visible when Bluetooth is on but, Androids for example, (at least 7.0 upwards) are visible only when you have the Bluetooth settings screen open.


message:
What are these components in Arduino Mega Schematic?

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

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

I was looking at Arduino Mega's reference schematic [here](https://www.arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf?) and trying to understand how the circuit functions. However, I am unable to understand what these schematic symbols (marked in black rectangles) represent or what their function is. Can anyone please explain it to me?

body:
The symbol indicates a pair of solder pads that can be bridged by the user using a blob of solder.

Here's something similar.

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

*Figure 1. Source: [CyberGibbons](https://cybergibbons.com/arduino/converting-a-usb-bub-ii-to-use-a-3-3v-regulator/).*

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


body:
@Transistor accurately answered what they are. I'll approach their specific function.

The Arduino Mega [documentation](https://store.arduino.cc/usa/arduino-mega-2560-rev3) gives some information on "RESET-EN" and "UBOOT."

 1. **"RESET-EN"** allows you to enable/disable the auto-reset feature. By default there is a trace between the pads. That's why it look like there is a short in parallel below it. Cut the trace to disable auto-reset. Solder bridge back together to re-enable.

 With auto-reset enabled, the board will automatically reset every time the serial communication is initially established. This causes problems if you are using a non-usb power supply and want to plug in for some debugging or have a design that opens and closes serial comm.

 2. **"UBOOT"** is related to the DFU (Device Firmware Update) bootloader. This may be on the back of the board and will be different between revs.

>The ATmega16U2/8U2 is loaded with a DFU bootloader, which can be activated by:
>
 - On Rev1 boards: connecting the **solder jumper** on the back of the board (near the map of Italy) and then resetting the 8U2.
 - On Rev2 or later boards: there is a resistor that pulling the 8U2/16U2 HWB line to ground, making it easier to put into DFU mode.

You can use this to update the USB firmware and even change the device name when you plug it in. More info [here](https://www.arduino.cc/en/Hacking/DFUProgramming8U2).

 3. **"GROUND"** can optionally link USB ground (UGND) to the main circuit ground. I don't know enough about USB comm circuit design to understand what the advantages or disadvantages are here. Perhaps someone else can clarify this idea. [ATMEGA8U2-MU datasheet](https://www.mouser.com/datasheet/2/268/doc7799-1315152.pdf) for reference.


message:
Arduino Mega not recognized by device manager

My lab partner and I are working on a project for school and we are using an Arduino Mega 2560 for prototyping. The board was working just fine until, out of nowhere, the board was not being recognized at all. I tried reinstalling the IDE but still it does not work. I checked to see if the Arduino driver was installed, but the board does not show up in the device manager. Also, the L LED on the board does not light up at all. Attached are photos to help understand the problem.

[![grayed out port in the tools drop-down][1]][1]

[![arduino mega driver does not show up in device manager][2]][2]

  [1]: https://i.stack.imgur.com/SxnhV.png
  [2]: https://i.stack.imgur.com/7sTc7.png

If someone could help, it would be much appreciated. Thanks.

body:
hey i had the same problem, i am thinking because i installed atmel studio and then this started happening,
I then downloaded arduino from the microsoft store,(no change)
then i restarted the pc, now its compiling and uploaded normally but still does not show the name of the board that is connected just shows lets say just  COM22 with out saying what board


message:
DS2436 Arduino UNO programming

I am struggling with programming my DS2436 chip using an Arduino UNO. To be honest, I am trying to modify DS18B20 code (the one that is anywhere on the internet) to work with DS2436. It's just harder for me to understand how whole memory and adressing thing work, since DS2436 has those pages of memory blocks, unlike DS18B20, which has only 1. Also the language factor is stopping me, I am not a native speaker.

I keep getting wrong data/temperature/CRC. Can someone assist me, please? I need this thing to show me voltage/temperature and cycles.

    #include <OneWire.h>
    OneWire  ds(10);

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

    void loop(void) {
      byte i;
      byte addr[8];
      byte data[32];
      byte type_s;
      byte present = 0;
      float celsius, fahrenheit;

      if (!ds.search(addr)) {
        ds.reset_search();
        delay(1000);
        return;
      }

      Serial.print("ROM =");
      for( i = 0; i < 8; i++) {
        Serial.write(' ');
        Serial.print(addr[i], HEX);
      }
      Serial.print("\n");
      if (OneWire::crc8(addr, 7) != addr[7]) {
        Serial.println("CRC is not valid!");
        return;
        Serial.print("\n");
      }
      if (addr[0] != 0x1B) {
        Serial.print("Device is not a DS2436 family device!");
        Serial.print("\n");
      }
      {
        Serial.print("CRC= ");
        Serial.print(OneWire::crc8(data, 8), HEX);
      }
      Serial.print("\n");
      ds.reset();
      ds.select(addr);
      ds.write(0xD2, 1);
      delay(1000);
      present = ds.reset();
      ds.select(addr);
      ds.write(0xB2);
      Serial.print("  Data = ");
      for (int i = 0; i < 13; i++) {
        data[i] = ds.read();
        Serial.print(data[i], HEX);
        Serial.print(" ");
      }
      Serial.print(" CRC=");
      Serial.print(OneWire::crc8(data, 8), HEX);
      Serial.println();
      unsigned int raw = (data[1] << 8) | data[0];
      int sig = raw & 0x8000;
      if (sig) {
        raw = (raw ^ 0xffff) + 1;
      }
      celsius = (float)raw * 0.03125;
      Serial.print("Temperature = ");
      Serial.print(celsius);
      Serial.print(" Celsius ");
      Serial.print("\n");
      Serial.print("_______________________________________________");
      Serial.print("\n");
    }

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

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

body:
Yes necro, but having my own example of a DS2436 to try this out on, and having to write code for it with little else to go on, seems like the IC doesn't really know what to send you when reading the bus after sending the read register command.

As per the datasheet, 0xFF is data the IC sends when the bus master reaches the end of a page or an address that's reserved. Adding in `ds.write(0x60);` before performing the read cycles fixes most of this.

Haven't gotten into much past that, but it seems like there's also something not quite right going on with your arithmetic to turn your binary into temperature. Even with my fix getting something serviceable as output, I get 1024.00 Celsius.


message:
Digital input signal to be converted to analog signal

Hello and a very good day.
I am currently doing my final year project which involving Arduino KY-031 Knock Sensor as my input signal and it is apparently a digital type of sensor. So, my question is can the digital signal be converted to analog signal ?

The reason I need it to be analog signal because I wanted it to be classified into 3 type of stages (low,medium,high).
p/s: I am using Arduino Uno as my controller.

body:
You can create an analogue representation of any signal - but you can't add in information which wasn't previously there.  The [KY-031][1] doesn't give you any more information than "knock" or "no knock", so there's no way to get further detail out of it.

  [1]: http://henrysbench.capnfatz.com/henrys-bench/arduino-sensors-and-input/keyes-ky-031-arduino-knock-impact-sensor-manual-and-tutorial/


message:
Having an issue running an Arduino sketch

I just got my USB host shield attached to my Arduino Uno, opened the program sketch for `USBDESC.ino` and I'm getting an error. It says "usbhub.h not found". It won't compile. How did I go wrong?

I am using the Mac version of the Arduino IDE and downloaded the USB host shield Master v 2.0 file directly into /Arduino/java/examples. This was how I have added every previous library download. Please help. Thanks.

body:
I don't know how you came up with that location as the right place to put libraries. It is wrong. Oh so very wrong.

Libraries go in `~/Documents/Arduino/libraries` as stated in [the first hit for "arduino macos libraries" on Google](https://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use/installing-a-library-on-mac-osx).


message:
GPS showing incorrect speed

I am using Arduino ATmega 2560.
When i am using "AT+CGNSINF" command to get GPS value, sometimes it showing incorrect speed.
The correct speed should be (50-60)km/h but sometimes it showing (200-300)km/h.
How can I fix the problem or avoid/ignore the unexpected speed.
here is my code

    void get_GPS()
    {
        sendATCommand("AT+CGNSINF","OK", 1000);

        // condition for valid response
        while (strstr(AT_Buffer, "+CGNSINF: 1,1") != NULL)
        {
            delay(3000);
            strtok(AT_Buffer, ",");
            strtok(NULL, ",");
            strtok(NULL, ",");
            strtok(NULL, ",");
            strtok(NULL, ",");
            strtok(NULL, ",");
            Serial.println("\n");
            Serial.println(strtok(NULL, ","));

            //sendATCommand("AT+CGNSINF", "OK", 1000);
        }
    }
    uint8_t sendATCommand(char* ATcommand, const char *expectedResponse, unsigned long timeout)
    {
        uint8_t x = 0, answer = 0;

        memset(AT_Buffer, '\0', AT_BufferLength);    // Initialice the string
        delay(100);
        while (Serial1.available() > 0) Serial1.read();    // Clean the input buffer
        if (ATcommand[0] != '\0')
        {
            Serial1.println(ATcommand);    // Send the AT command
        }

        unsigned long previous = millis();

        // this loop waits for the answer
        do {

            if (Serial1.available() != 0) {    // if there are data in the UART input buffer, reads it and checks for the asnwer
                AT_Buffer[x] = Serial1.read();
                //Serial.print(AT_Buffer[x]);
                x++;
                if (strstr(AT_Buffer, expectedResponse) != NULL)    // check if the desired answer (OK) is in the response of the module
                {
                    answer = 1;
                    break;
                }

            }
        } while ((millis() - previous < timeout));    // Waits for the asnwer with time out

        return answer;
    }

body:
Speed calculation in most GPS systems is very crude. It consists of simply "Where was I then? Where am I now?". Many will also add "How long has passed between then and now?", but many also don't - they assume a fixed time between points (1 second, for example). It doesn't know it's supposed to move, all it knows is the coordinates it has at the moment.

With the latter, if you don't get a reading for a couple of seconds (buildings in the way, for example) the position can suddenly jump a long way.  You can see the effect in your phone's GPS in built-up areas - your position may jump long distances and then pause for a bit.

To visualise it in 1-dimension, you can think of a simple number sequence 0-9 and the difference between each value:

    Value:        0 1 2 3 4 5 6 7 8 9
    Difference:     1 1 1 1 1 1 1 1 1

The difference equates to the "speed" of the sequence.

Now if the numbers don't get updated smoothly, but all at once at the end, you get something like:

    Value:        0 1 2 2 2 2 2 7 8 9
    Difference:     1 1 0 0 0 0 5 1 1

The end results is the same, but you get a "dead" period with no "movement" and then a big jump with an unusually high speed.

It's up to you to filter out such anomalies. It's simple enough to say "5 is too much - ignore it". You could also average the past 10 seconds worth of data (for example) and use that as your average speed over that time period, which would smooth out such peaks and troughs.


message:
A4988 and capacitors

I’m working at a project which involves 3 stepper motors that are driven by A4988 drivers. I have read that I have to connect an 100uf capacitor in parallel with the motor power supply that goes to the driver, but do I have to use a capacitor for every driver, or only 1 capacitor because the drivers are connected in parallel to the same 12v power supply.

body:
There are two purposes of such capacitor:

 - first it supply power for short peaks in demand, so effectively enabling the 12V power source supply much more current for short time, than it can support over long time and so the driver have more stable power and works generally better. Also it protects the driver from noise of other parts.
 - the other is protect all other parts from voltage drops and noise caused by the driver. It is recomended to have capacitors as near as possible to any IC/driven circuit for this reason.

So basically - if you have good power source, you can often get away even without such capacitors. But if you power also logic from the same source, it is already better to have some capacitors on power lines where posssible. Escpecially if you expect some noise around (like having motors near or lines to motors in paralel with other lines ...). Depends how much you care and how critical you see the project. Hobby project just for fun can go even without capacitors and be all good. Good industry projects have capacitors always everywhere.

I had project, where it worked even without capacitors (laser printer), but now I would place some there in any case near each driver, just to be sure. 100uF is really good capacity, enables for lot power. But if you use any other value (which you have more ready), it should not hurt too. It is not about if it would work or not, it is more about if it ensures, that it would work flawlessly even in bad conditions even under unexpected conditions and would not have "sometimes strange problems, which disapear spontaneously during debugging".

Also note, that for improving power are good high capacity electrolytes. For preventing noise are much better ceramic (which are fast, even if they have a lot smaler capacity) and so many people put both there (like 100uF electrolyte and 100nF ceramic in paralel).

**Short answer:** Do as you want, it would probably work anyway. I personally would place big+small capacitors near each driver.


message:
Printing transmission data from nRF24L01+

I have a beginner's problem. I have 2 nRF24L01+ devices. They are communicating with each other great, and I can talk with the nRF via SPI.

The problem is I want to display, on the serial monitor, the number of retransmitted packets (ARC_CNT) and the number of lost packets (PLOS_CNT), which are both in the "observe_tx" register on the nRF.

I am using the "Getting Started" example from RF24 1.3.1, with Arduino 1.84, with a few more bits added, and it all works great apart from getting it to show PLOS_CNT & ARC_CNT! I have tried:

    printf_P(PSTR("OBSERVE_TX=x: PLOS_CNT=%x ARC_CNT=%x\r\n"));

But this does not give the correct result.

As you have probably guessed, I know nothing about C or C++. There must be a simple way of showing the 2 numbers?

The code I am using is:

    #include <SPI.h>
    #include "RF24.h"
    #include <printf.h> // Required for "radio.printDetails();"

    /****************** User Config ***************************/
    /***      Set this radio as radio number 0 or 1         ***/
    bool radioNumber = 0;

    /* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */
    RF24 radio(7, 8);
    /**********************************************************/

    byte addresses[][6] = {"1Node", "2Node"};

    // Used to control whether this node is sending or receiving
    bool role = 0;

    void setup() {
      //pinMode(53,OUTPUT); //may not be required after all
      Serial.begin(115200);
      printf_begin(); //required for "radio.printDetails();" to work
      Serial.println(F("RF24/examples/GettingStarted"));
      Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
      radio.begin();
      // Set the PA Level low to prevent power supply related issues since this is a
      // getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.
      radio.setPALevel(RF24_PA_LOW); // _MIN, _LOW, _HIGH, _MAX
      radio.setDataRate(RF24_250KBPS); //250KBPS, _1MBPS, _2MBPS  Lowest rate gives longest range.
      radio.setChannel(108); // 0 - 124 (2.4GHz - 2.524GHz) Usually above 100 best. USA 70 - 80 best.
      radio.setRetries(15, 15); // set retry delay and no of retries. delay between retries, 0=250uS, 15 = 4000uS
      radio.setCRCLength(RF24_CRC_16);  // 8 or 16 bit crc
      radio.printDetails();
      Serial.print(radio.getChannel());
      radio.setAutoAck(1);
      // Open a writing and reading pipe on each radio, with opposite addresses
      if (radioNumber) {
        radio.openWritingPipe(addresses[1]);
        radio.openReadingPipe(1, addresses[0]);
      } else {
        radio.openWritingPipe(addresses[0]);
        radio.openReadingPipe(1, addresses[1]);
      }
      // Start the radio listening for data
      radio.startListening();
    }

    void loop() {
      /****************** Ping Out Role ***************************/
      if (role == 1)  {
        radio.stopListening(); // First, stop listening so we can talk.
        Serial.println(F("Now sending"));
        unsigned long start_time = micros();
        // Take the time, and send it.  This will block until complete
        if (!radio.write( &start_time, sizeof(unsigned long) )) {
          Serial.println(F("failed"));
        }
        radio.startListening(); // Now, continue listening
        unsigned long started_waiting_at = micros(); // Set up a timeout period, get the current microseconds
        boolean timeout = false; // Set up a variable to indicate if a response was received or not
        while (!radio.available()) {
          // While nothing is received
          if (micros() - started_waiting_at > 200000 ) {
            // If waited longer than 200ms, indicate timeout and exit while loop
            timeout = true;
            break;
          }
        }

        if (timeout) {
          // Describe the results
          Serial.println(F("Failed, response timed out."));
          printf_P(PSTR("OBSERVE_TX=x: PLOS_CNT=%x ARC_CNT=%x\r\n"));
        } else {
          unsigned long got_time;
          // Grab the response, compare, and send to debugging spew
          radio.read( &got_time, sizeof(unsigned long) );
          unsigned long end_time = micros();
          // Spew it
          Serial.print(F("Sent "));
          Serial.print(start_time);
          Serial.print(F(", Got response "));
          Serial.print(got_time);
          Serial.print(F(", Round-trip delay "));
          Serial.print(end_time - start_time);
          Serial.println(F(" microseconds"));
        }
        // Try again 1s later
        delay(1000);
      }

      /****************** Pong Back Role ***************************/
      if (role == 0) {
        unsigned long got_time;
        if (radio.available()) {
          // Variable for the received timestamp
          while (radio.available()) {
            // While there is data ready
            radio.read(&got_time, sizeof(unsigned long));
            // Get the payload
          }
          radio.stopListening();
          // First, stop listening so we can talk
          radio.write(&got_time, sizeof(unsigned long));
          // Send the final one back.
          radio.startListening();
          // Now, resume listening so we catch the next packets.
          Serial.print(F("Sent response "));
          Serial.println(got_time);
        }
      }

      /****************** Change Roles via Serial Commands ***************************/

      if (Serial.available()) {
        char c = toupper(Serial.read());
        if (c == 'T' && role == 0) {
          Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
          role = 1; // Become the primary transmitter (ping out)
        } else if (c == 'R' && role == 1) {
          Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
          role = 0; // Become the primary receiver (pong back)
          radio.startListening();
        }
      }
    } // Loop

body:
    printf_P(PSTR("OBSERVE_TX=x: PLOS_CNT=%x ARC_CNT=%x\r\n"));

This should be

    printf_P(PSTR("OBSERVE_TX=x: PLOS_CNT=%x ARC_CNT=%x\r\n"),
     OBSERVE_TX, PLOS_CNT, ARC_CNT);

Where the two variables contain the values.

- first OBSERVE_TX= means the text that is literally printed
- X is the format of the variable which is printed
- OBSERVE_TX is the variable name

The variable names should be in the same order as the formatting (%'s).

However, in your case the above will not result in the values you want. The items above (OBSERVE_PLOS_CNT and ARC_CNT) are offsets from an addres. What you want is to print the content of that address. Since I don't have an Arduino IDE nearby, you should find yourself the address, and use *(address + OBSERVE_PLOS_CNT). This will use the address, adds OBSERVE_PLOS_CNT, and * means it will show the content of that new address.

Btw, I'm not sure about the exact use of printf_P and PSTR.


message:
Looking for Power Bank with "Always-On-Feature"

I want to build a mobile weather station with an Arduino and some sensors. I want to use a power bank as power source. The Powerbank should support "Always-On", because weather data should not be measured continuously. This means that almost no current flows between the time intervals. Common power banks switch off automatically when the current flow is low.

I don't want to connect an additional device or electronic component to increase the power consumption. So I need a power bank that doesn't switch off even when the current flow is low.

During my search I found the Powerbank "V44 USB Battery Pack" from Voltaic. Unfortunately I cannot buy them in Germany.
https://www.voltaicsystems.com/v44

Can anyone recommend an alternative?

body:
Lithium cell based powerbanks use a boost converter to boost the voltage from the Cell to the 5V for the USB. They turn off because keeping the voltage boosted when not used wastes quite a bit of power.

If all your devices can run straight on 3.3V you can use a Lithium cell directly with a voltage regulator (and with the normal protection circuitry).

Otherwise you can simulate a button press on the on button with a gpio pin to activate the boost circuitry when you are ready to take your measurements; let he voltage stabilize; use transistors to connect the components to power; take your measurements; disconnect the components and then let the timeout expire after which the voltage will drop again.


message:
Single & multi sensor code

I have been having problems trying to run multi sensor code for my project, this requires four KY-024 Linear magnetic Hall sensors as position sensors that trigger NC independent relays to make a circuit.
I can get the code to run on one independent circuit, one hall switch one relay with no problems.
But when I try the code for 4 hall sensors + relays I get no response from the circuit at this point I am at a loss where to go from here the code compiled with no problems.

    int hallswitch = 1;
    int val = 0;
    int RELAY1 = 6;

    void setup() {
      pinMode(hallswitch, INPUT);
      pinMode(RELAY1, OUTPUT);
    }

    void loop() {
      val = digitalRead(hallswitch);

      if (val == HIGH) {
        digitalWrite(RELAY1, HIGH);
      }
      else {
        digitalWrite(RELAY1, LOW);
      }
    }

and

    int hallswitch1 = 1;  //Pin for Hall switch
    int hallswitch2 = 2;  //Pin for Hall switch
    int hallswitch3 = 4;  //Pin for Hall switch
    int hallswitch4 = 5;  //Pin for Hall switch

    int val = 0;       //Integer for reading Hall statu

    int RELAY1 = 6;    // The socket number on the Arduino that the relay1 will go to.
    int RELAY2 = 7;    // The socket number on the Arduino that the relay1 will go to.
    int RELAY3 = 8;    // The socket number on the Arduino that the relay1 will go to.
    int RELAY4 = 9;    // The socket number on the Arduino that the relay1 will go to.

    void setup()
    {
      pinMode(hallswitch1, INPUT);
      pinMode (RELAY1, OUTPUT);

      pinMode(hallswitch2, INPUT);
      pinMode (RELAY2, OUTPUT);

      pinMode(hallswitch3, INPUT);
      pinMode (RELAY3, OUTPUT);

      pinMode(hallswitch4, INPUT);
      pinMode (RELAY4, OUTPUT);
    }

    void loop() {
      val = digitalRead(hallswitch1);               //Read Hall pin status
      val = digitalRead(hallswitch2);               //Read Hall pin status
      val = digitalRead(hallswitch3);               //Read Hall pin status
      val = digitalRead(hallswitch4);               //Read Hall pin status

      if (val == HIGH) {                        //If there is a magnet infront of Hall switch...
        digitalWrite(RELAY1, HIGH);             // Turn RELAY1 on:
        digitalWrite(RELAY2, HIGH);
        digitalWrite(RELAY3, HIGH);
        digitalWrite(RELAY4, HIGH);
      }
      else {
        digitalWrite(RELAY1, LOW);               // Turn RELAY1 off:
        digitalWrite(RELAY2, LOW);
        digitalWrite(RELAY3, LOW);
        digitalWrite(RELAY4, LOW);
      }
    }

body:
This is the quick and dirty way, I would suggest re writing it to use arrays rather then having to declare all these variables and copy paste pinMode, read,writes if statments a bunch of times.

     int hallswitch1 = 1;  //Pin for Hall switch
     int hallswitch2 = 2;  //Pin for Hall switch
     int hallswitch3 = 4;  //Pin for Hall switch
     int hallswitch4 = 5;  //Pin for Hall switch

     int val1 = 0;       //Integer for reading Hall statu
     int val2 = 0;
     int val3 = 0;
     int val4 = 0;

     int RELAY1 = 6;    // The socket number on the Arduino that the relay1 will go to.
     int RELAY2 = 7;    // The socket number on the Arduino that the relay1 will go to.
     int RELAY3 = 8;    // The socket number on the Arduino that the relay1 will go to.
     int RELAY4 = 9;    // The socket number on the Arduino that the relay1 will go to.

    void setup()
    {

      pinMode(hallswitch1, INPUT);
      pinMode (RELAY1, OUTPUT);

      pinMode(hallswitch2, INPUT);
      pinMode (RELAY2, OUTPUT);

      pinMode(hallswitch3, INPUT);
      pinMode (RELAY3, OUTPUT);

      pinMode(hallswitch4, INPUT);
      pinMode (RELAY4, OUTPUT);

    }

    void loop() {

      val1 = digitalRead(hallswitch1);               //Read Hall pin status
      val2 = digitalRead(hallswitch2);               //Read Hall pin status
      val3 = digitalRead(hallswitch3);               //Read Hall pin status
      val4 = digitalRead(hallswitch4);               //Read Hall pin status

      if (val1 == HIGH) {digitalWrite(RELAY1, HIGH);}
      else {digitalWrite(RELAY1, LOW);}

      if (val2 == HIGH) {digitalWrite(RELAY2, HIGH);}
      else {digitalWrite(RELAY2, LOW);}

      if (val3 == HIGH) {digitalWrite(RELAY3, HIGH);}
      else {digitalWrite(RELAY3, LOW);}

      if (val4 == HIGH) {digitalWrite(RELAY4, HIGH);}
      else {digitalWrite(RELAY4, LOW);}

    }


message:
Distance from Arduino UNO to LCD: How far?

How far from the UNO can I place an LCD (the typical 16x2)? Assuming that everything that is plugged into the LCD comes directly from the Arduino (power and data).

I'd like to mount the LCD on the wall at eye level, my "box" will be on the floor, close to a power source.

body:
The actual distance depends highly on several other factors:

 - Wire thickness / current carrying capacity / resistance
 - RFI (Radio Frequency Interference) environment
 - Data rate that you write to the LCD (Maybe you are using an I2C or SPI backpack)

In general, even 5 meters is **probably** going to work if you use sufficient wiring, but try it and see.

You may also need to add shielding to mitigate RFI.


message:
CH340 Nano avrdude: stk500_getsync() not in sync resp=0xa4

I'm trying to upload some code to an non-arduino nano with the CH340G chip, and the avrdude refuses to let me upload. The error I'm getting is:

    Using Port                    : COM4
    Using Programmer              : arduino
    Overriding Baud Rate          : 115200

    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0xf6
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0xf6
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0xf6
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0xf6
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0xf6
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0xf6
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xf6
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xf6
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0xf6
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xf6

    avrdude done.  Thank you.

I've tried installing the drivers for the CH340 chip following [this guide][1] but have had no luck. I've also tried uploading to my arduino uno and my arduino micro (both are arduino brand) with no problems. I'm running Windows 10, Arduino IDE 1.8.5

Any ideas?

  [1]: http://woodsgood.ca/projects/2014/11/18/driver-for-arduino-nano-with-ch340g-usb-chip/

body: Arduino has recently changed to using a different bootloader on their official Nano boards that communicates at 115200 baud rather than the previous 57600 baud. Support for these new boards was [added](https://github.com/arduino/ArduinoCore-avr/commit/1b14cc07331268e95eddcce2cc67e29ed667e62f) in Arduino AVR Boards 1.6.21. The new Nano board definition is not compatible with old Nanos and likely most 3rd party Nanos so backwards compatibility is provided via the **Tools > Processor > ATmega328P (Old Bootloader)** menu selection.