message:
Want criticism on my code

The code is controlling 3 blinds. There are 2 buttons for each blind for going each way and 2 buttons controlling all of them at the same time. The motorSerial is a way to control all of the blinds through the serial monitor where sending 1 goes one way and 2 the other way.

What I'm most concerned about is when pressing a button, it turns on the motor, waits for 0.2 seconds and turns the off. But if I'm holding the button down it will continuously keep turning it on and off. Does anyone have a better way of doing this?

    const int PWMA = 13;
    const int AI2_left = 12;
    const int AI1_left = 11;
    const int PWMB = 18;
    const int BI1_middle = 10;
    const int BI2_middle = 9;

    const int PWMA2 = 8;
    const int AI2_right = 7;
    const int AI1_right = 6;

    const int greenLeft1 = 5;
    const int greenLeft2 = 4;
    const int redMiddle1 = 3;
    const int redMiddle2 = 2;
    const int yellowRight1 = 14;
    const int yellowRight2 = 15;
    const int blueAll1 = 16;
    const int blueAll2 = 17;

    int motorSpeed_left = 0;
    int motorSpeed_middle = 0;
    int motorSpeed_right = 0;
    int motorSpeed_all = 0;
    int motorSerial = 0;

    void setup() {
      pinMode(PWMA, OUTPUT);
      pinMode(AI2_left, OUTPUT);
      pinMode(AI1_left, OUTPUT);
      pinMode(BI1_middle, OUTPUT);
      pinMode(BI2_middle, OUTPUT);
      pinMode(PWMA2, OUTPUT);
      pinMode(AI2_right, OUTPUT);
      pinMode(AI1_right, OUTPUT);

      pinMode(greenLeft1, INPUT_PULLUP);
      pinMode(greenLeft2, INPUT_PULLUP);
      pinMode(redMiddle1, INPUT_PULLUP);
      pinMode(redMiddle2, INPUT_PULLUP);
      pinMode(yellowRight1, INPUT_PULLUP);
      pinMode(yellowRight2, INPUT_PULLUP);
      pinMode(blueAll1, INPUT_PULLUP);
      pinMode(blueAll2, INPUT_PULLUP);

      Serial.begin(9600);
    }

    void loop() {

      if(Serial.available() > 0) {
        motorSerial = Serial.parseInt();
      }

      if(digitalRead(greenLeft1) == LOW) {
        motorSpeed_left = 200;
        spinMotor_left(motorSpeed_left);
        delay(200);
        motorSpeed_left = 0;
        spinMotor_left(motorSpeed_left);
      }
      else if(digitalRead(greenLeft2) == LOW) {
        motorSpeed_left = -200;
        spinMotor_left(motorSpeed_left);
        delay(200);
        motorSpeed_left = 0;
        spinMotor_left(motorSpeed_left);
      }
      else if(digitalRead(redMiddle1) == LOW) {
        motorSpeed_middle = 200;
        spinMotor_middle(motorSpeed_middle);
        delay(200);
        motorSpeed_middle = 0;
        spinMotor_middle(motorSpeed_middle);
      }
      else if(digitalRead(redMiddle2) == LOW) {
        motorSpeed_middle = -200;
        spinMotor_middle(motorSpeed_middle);
        delay(200);
        motorSpeed_middle = 0;
        spinMotor_middle(motorSpeed_middle);
      }
      else if(digitalRead(yellowRight1) == LOW) {
        motorSpeed_right = 200;
        spinMotor_right(motorSpeed_right);
        delay(200);
        motorSpeed_right = 0;
        spinMotor_right(motorSpeed_right);
      }
      else if(digitalRead(yellowRight2) == LOW) {
        motorSpeed_right = -200;
        spinMotor_right(motorSpeed_right);
        delay(200);
        motorSpeed_right = 0;
        spinMotor_right(motorSpeed_right);
      }
      else if(digitalRead(blueAll1) == LOW) {
        motorSpeed_left = 200;
        motorSpeed_middle = 200;
        motorSpeed_right = 200;
        spinMotor_left(motorSpeed_left);
        spinMotor_middle(motorSpeed_middle);
        spinMotor_right(motorSpeed_right);
        delay(200);
        motorSpeed_left = 0;
        motorSpeed_middle = 0;
        motorSpeed_right = 0;
        spinMotor_left(motorSpeed_left);
        spinMotor_middle(motorSpeed_middle);
        spinMotor_right(motorSpeed_right);
      }
      else if(digitalRead(blueAll2) == LOW) {
        motorSpeed_left = -200;
        motorSpeed_middle = -200;
        motorSpeed_right = -200;
        spinMotor_left(motorSpeed_left);
        spinMotor_middle(motorSpeed_middle);
        spinMotor_right(motorSpeed_right);
        delay(200);
        motorSpeed_left = 0;
        motorSpeed_middle = 0;
        motorSpeed_right = 0;
        spinMotor_left(motorSpeed_left);
        spinMotor_middle(motorSpeed_middle);
        spinMotor_right(motorSpeed_right);
      }
      else if(motorSerial == 1) {
        motorSpeed_left = 200;
        motorSpeed_middle = 200;
        motorSpeed_right = 200;
        spinMotor_left(motorSpeed_left);
        spinMotor_middle(motorSpeed_middle);
        spinMotor_right(motorSpeed_right);
        delay(2500);
        motorSpeed_left = 0;
        motorSpeed_middle = 0;
        motorSpeed_right = 0;
        spinMotor_left(motorSpeed_left);
        spinMotor_middle(motorSpeed_middle);
        spinMotor_right(motorSpeed_right);
        motorSerial = 0;
      }
      else if(motorSerial == 2) {
        motorSpeed_left = -200;
        motorSpeed_middle = -200;
        motorSpeed_right = -200;
        spinMotor_left(motorSpeed_left);
        spinMotor_middle(motorSpeed_middle);
        spinMotor_right(motorSpeed_right);
        delay(2500);
        motorSpeed_left = 0;
        motorSpeed_middle = 0;
        motorSpeed_right = 0;
        spinMotor_left(motorSpeed_left);
        spinMotor_middle(motorSpeed_middle);
        spinMotor_right(motorSpeed_right);
        motorSerial = 0;
      }

    }

    /*****************************************************/
    void spinMotor_left(int motorSpeed_left)
    {
      if (motorSpeed_left > 0)
      {
        digitalWrite(AI1_left, HIGH);
        digitalWrite(AI2_left, LOW);
      }
      else if (motorSpeed_left < 0)
      {
        digitalWrite(AI1_left, LOW);
        digitalWrite(AI2_left, HIGH);
      }
      else
      {
        digitalWrite(AI1_left, LOW);
        digitalWrite(AI2_left, LOW);
      }
      analogWrite(PWMA, abs(motorSpeed_left));
    }

    void spinMotor_middle(int motorSpeed_middle)
    {
      if (motorSpeed_middle > 0)
      {
        digitalWrite(BI1_middle, HIGH);
        digitalWrite(BI2_middle, LOW);
      }
      else if (motorSpeed_middle < 0)
      {
        digitalWrite(BI1_middle, LOW);
        digitalWrite(BI2_middle, HIGH);
      }
      else
      {
        digitalWrite(BI1_middle, LOW);
        digitalWrite(BI2_middle, LOW);
      }
      analogWrite(PWMB, abs(motorSpeed_middle));
    }

    void spinMotor_right(int motorSpeed_right)
    {
      if (motorSpeed_right > 0)
      {
        digitalWrite(AI1_right, HIGH);
        digitalWrite(AI2_right, LOW);
      }
      else if (motorSpeed_right < 0)
      {
        digitalWrite(AI1_right, LOW);
        digitalWrite(AI2_right, HIGH);
      }
      else
      {
        digitalWrite(AI1_right, LOW);
        digitalWrite(AI2_right, LOW);
      }
      analogWrite(PWMA2, abs(motorSpeed_right));
    }

body:
    if(digitalRead(greenLeft1) == LOW) {
        motorSpeed_left = 200;
        spinMotor_left(motorSpeed_left);
        delay(200);
        motorSpeed_left = 0;
        spinMotor_left(motorSpeed_left);
    }
    else if(digitalRead(greenLeft2) == LOW) {
        motorSpeed_left = -200;
        spinMotor_left(motorSpeed_left);
        delay(200);
        motorSpeed_left = 0;
        spinMotor_left(motorSpeed_left);
    }

Doesn't quite do what you want it to do.

Instead you want something like:

    if(digitalRead(greenLeft1) == LOW) {
        motorSpeed_left = 200;
        spinMotor_left(motorSpeed_left);

    } else if(digitalRead(greenLeft2) == LOW) {
        motorSpeed_left = -200;
        spinMotor_left(motorSpeed_left);
    } else {
        motorSpeed_left = 0;
        spinMotor_left(motorSpeed_left);
    }

However because you also want a master switch and control through serial. You can pull out the tests on each button to a variable and then make the master switch override those:

    int motor_left = 0;
    if(digitalRead(greenLeft1) == LOW) {
        motor_left = 1;
    } else if(digitalRead(greenLeft2) == LOW) {
        motor_left = -1;
    } else {
        motor_left = 0;
    }

    //...

    if(digitalRead(blueAll1) == LOW){
        motor_left   = 1;
        motor_center = 1;
        motor_right  = 1;
    } else if(digitalRead(greenLeft2) == LOW) {
        motor_left   = -1;
        motor_center = -1;
        motor_right  = -1;
    }

    if(motor_left > 0) {
        motorSpeed_left = 200;
        spinMotor_left(motorSpeed_left);

    } else if(motor_left < 0) {
        motorSpeed_left = -200;
        spinMotor_left(motorSpeed_left);
    } else {
        motorSpeed_left = 0;
        spinMotor_left(motorSpeed_left);
    }

Also the pin number is just and `int` so you can pull those out as a parameter as well and have only one copy of the `spinMotor` function.

    void spinMotor(int motor_pin1, int motor_pin2, int motorSpeed)
    {
      if (motorSpeed > 0)
      {
        digitalWrite(motor_pin1, HIGH);
        digitalWrite(motor_pin2, LOW);
      }
      else if (motorSpeed < 0)
      {
        digitalWrite(motor_pin1, LOW);
        digitalWrite(motor_pin2, HIGH);
      }
      else
      {
        digitalWrite(motor_pin1, LOW);
        digitalWrite(motor_pin2, LOW);
      }
      analogWrite(PWMA, abs(motorSpeed));
    }

To reduce the number of globals you can group the state for each motor into a struct and initialize them in `init()`:

    struct motorState {
       int motor_pin1, motor_pin2;
       int pwm_pin;
       int button1, button2;
       int direction;
       int speed;
    }

    motorState motor_left;
    motorState motor_center;
    motorState motor_right;

then pass the globals by pointer or ref to the functions doing the input and output.

    void readMotorButton(motorState *motor){
        if(digitalRead(motor->button1) == LOW) {
            motor->direction = 1;
            motor->speed = 200;
        } else if(digitalRead(motor->button2) == LOW) {
            motor->direction = -1;
            motor->speed = 200;
        } else {
            motor->direction = 0;
            motor->speed = 0;
        }
    }

    void spinMotor(motorState *motor)
    {
      if (motor->direction > 0)
      {
        digitalWrite(motor->motor_pin1, HIGH);
        digitalWrite(motor->motor_pin2, LOW);
      }
      else if (motor->direction < 0)
      {
        digitalWrite(motor->motor_pin1, LOW);
        digitalWrite(motor->motor_pin2, HIGH);
      }
      else
      {
        digitalWrite(motor->motor_pin1, LOW);
        digitalWrite(motor->motor_pin2, LOW);
      }
      analogWrite(motor->pwm_pin, abs(motor->speed));
    }


sender: user

sender: assistant

body:
There is a code review group on here where you will get a more generic code review if you want.

First thing I noticed is there are no comments.  You have written a paragraph explaining what the code does, but that should be in the code where you will be able to read it when you find the code 12 months down the line.

Rachet Freak has covered loads of good points, but one point I would disagree with is passing globals to functions using pointers.  I would use references instead, the only reason for this is IF you mess up references can't be NULL, so you don't need to check within the function to see if they are NULL.  Of course it will never happen, you never pass a NULL pointer to one of these functions, but as you code grows in size the chances of you doing that will increase and should you ever write a library, the chances of someone else passing a NULL pointer to your library is very high, and then you have got "a problem in your library".

Moving on from that if the parameter's value will not be modified during the life of a function pass it in as a `const` reference.  The main reason for this is it explains to the reader that the value won't change in the function, its a simple way of documenting your intention without having to write a comment.  So

    void spinMotor(int motor_pin1, int motor_pin2, int motorSpeed){...}

would become

    void spinMotor(const int& motor_pin1, const int& motor_pin2, const int& motorSpeed) {...}

Personally I would always add a constructor to structures.  This way you know that every field has the correct value to start with.  (I believe the Arduino compiler will initialise everything, but not all compilers are so kind.)  Also it allows you to write neater code, i.e.

    struct motorState {
       int motor_pin1;
       int motor_pin2;
       int button1;
       int button2;
       int direction;

      // Parameterised constructor can be called either:
      //    motorState mState;
      //    motorState mState2 = motorState (2, 3, 4, 5, -1);
      motorState (const int& pin1 = 5, const int& pin2 = 6, const int& b1 = 7, const int& b2 = 8, const int& dir = 1)
      : motor_pin1(pin1)
      , motor_pin2(pin2)
      , button1(b1)
      , button2(b2)
      , direction(dir)
    {}
}

Finally, I have always been told to never put two declarations on the same line.

    int motor_pin1, motor_pin2;

There is no difference between the above and this as far as the compiler is concerned.

    int motor_pin1;
    int motor_pin2;

It is purely for readability you don't realise you are doing it, taking longer to read the first case than the second because your brain is more attuned to seeing a type, variable name and optional value.

    int
    motor_pin1,
    motor_pin2;

The above is legal, but what type in `motor_pin2`?  It is just a convention that is widely used and makes code easier to read, even though it is harder to write, in the same way that code has to be indented by 4 spaces on here.  If it isn't indented it has the same text, but is virtually unreadable.

Finally, if you find yourself copy and pasting lines, it should probably be a function or an array or both.


body:
ratchet freak's long answer has many good points. I would also agree
with Code Gorilla's suggestion to add a constructor to the `struct`.
However, once you have a constructor, it pretty much looks like a
regular C++ class¹, so it would make sense to add the motor-related
functions as members of the class. Thus I would start by building a
class that abstracts out the details of driving the motors:

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

    class Motor {
    public:
        Motor(uint8_t pin_1, uint8_t pin_2, uint8_t pin_pwm)
        : pin_1(pin_1), pin_2(pin_2), pin_pwm(pin_pwm) {}

        void begin() {
            pinMode(pin_1, OUTPUT);
            pinMode(pin_2, OUTPUT);
            pinMode(pin_pwm, OUTPUT);
        }

        void spin(int speed) {
            digitalWrite(pin_1, speed > 0 ? HIGH : LOW);
            digitalWrite(pin_2, speed < 0 ? HIGH : LOW);
            analogWrite(pin_pwm, abs(speed));
        }

    private:
        const uint8_t pin_1, pin_2, pin_pwm;
    };

I have left the buttons out of the class, because you have those blue
“all motors” buttons that do not fit well with the notion that each
button “belongs” to a particular motor.

Then, I would use some other abstraction for representing the buttons.
Maybe from a debouncing library. If button bounces are not problematic
in this application, then the “abstraction” would simply be:

    // Is that button pressed?
    static inline bool pressed(uint8_t pin) {
        return digitalRead(pin) == LOW;
    }

Of course, as an abstraction, this does not provide a lot of value. It
can be seen as a small bit of “syntactic sugar” that makes writing (and
reading) the rest of the code easier.

With those in place, the program would look like:

    // Pinout.
    const uint8_t left_1   = 5;
    const uint8_t left_2   = 4;
    const uint8_t middle_1 = 3;
    const uint8_t middle_2 = 2;
    const uint8_t right_1  = 14;
    const uint8_t right_2  = 15;
    const uint8_t all_1    = 16;
    const uint8_t all_2    = 17;
    const int button_count = 8;
    const uint8_t buttons[button_count] = {
        left_1, left_2, middle_1, middle_2, right_1, right_2, all_1, all_2
    };

    // Motors.
    const int SPEED = 200;
    Motor motor_left(11, 12, 13);
    Motor motor_middle(10, 9, 18);
    Motor motor_right(6, 7, 8);

    void setup() {
        motor_left.begin();
        motor_middle.begin();
        motor_right.begin();
        for (int i = 0; i < button_count; i++)
            pinMode(buttons[i], INPUT_PULLUP);
        Serial.begin(9600);
    }

    void loop() {
        // Read the serial command, if any.
        int serial_command = Serial.read();  // is -1 if there is no input
        bool serial_1 = serial_command == '1',  // serial request for '1'
             serial_2 = serial_command == '2';  // serial request for '2'

        // Operate the motors.
        if      (pressed(left_1))   motor_left.spin(SPEED);
        else if (pressed(left_2))   motor_left.spin(-SPEED);
        else if (pressed(middle_1)) motor_middle.spin(SPEED);
        else if (pressed(middle_2)) motor_middle.spin(-SPEED);
        else if (pressed(right_1))  motor_right.spin(SPEED);
        else if (pressed(right_2))  motor_right.spin(-SPEED);
        else if (pressed(all_1) || serial_1) {
            motor_left.spin(SPEED);
            motor_middle.spin(SPEED);
            motor_right.spin(SPEED);
            if (serial_1) delay(2500);
        } else if (pressed(all_2) || serial_2) {
            motor_left.spin(-SPEED);
            motor_middle.spin(-SPEED);
            motor_right.spin(-SPEED);
            if (serial_2) delay(2500);
        } else {
            motor_left.spin(0);
            motor_middle.spin(0);
            motor_right.spin(0);
        }
    }

¹ The `struct` keyword in C++ actually declares a class.


message:
Set variable value with serial?

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

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

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

    void setup() {

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

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

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

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

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

      }
    }

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

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

Try swapping those two lines.


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

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

But this will work only for single digit numbers, for more robust solution please refer to [readString function](https://www.arduino.cc/en/Serial/ReadString) to see how you can read strings from UART and to function [atoi](http://www.cplusplus.com/reference/cstdlib/atoi/) which converts string to number.


body:
Try changing these lines

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

to these lines

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

<br>
As shown in the [Arduino documentation](https://www.arduino.cc/en/Serial/ParseInt), Serial.parseInt() will read a number from Serial. If a non-number character is entered it will return 0.


message:
how to set the pin 13 only HIGH for 1 minute if sensor at pin 8 give HIGH?

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

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

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

      delay(0);
    }

body:
Just add delay after you turn on pin 13. So it would be:

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

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

    void loop() {

      val = digitalRead(8);

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


body:
I want to add to the answer of Ian:

- If you later want to do something within that minute, you should not use `delay`. Instead use millis, see [Blink without delay][1] and use the same principle. It is considered bad practice to use delays, since it prevents from doing anything else in the mean time. For your small example it is not a problem though.

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

  [1]: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay


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

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


message:
Timer0 overflow interrupt not working

<br>
I try to use the Timer0 of an Arduino Leonardo (ATmega32u) to trigger an interrupt at regular intervals, using plain avr-gcc (not the arduino library). I try to blink the built-in LED as test, but it does not light up.

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

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

Here is my code:

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

    ISR(TIMER0_OVF_vect)
    {
        PINC = 0x80;
    }

    int main()
    {
        DDRC = 0b10000000;

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

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

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

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

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

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

Thanks to those who helped me !


message:
How to indicate an End of a stream on USB

I am making a Lora-USB passthrough device using arduino and somehow I want to indicate that a stream over some data has ended.

So far I have done:

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

      byte[packetSize] buffer=[];

      while (LoRa.available()) {
        site_t recievedData=LoRa.readBytes(buffer,packetSize);
        Serial.write(buffer,recievedData);
      }
    }
So what I want to know is how the software reading from the serial interface will know that a packet has ended; One way I thought is by sending an `EOF` byte but I am afraid of "rogue" `EOF` values in packet data.

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

body:
What you need is some form of *protocol*. Some system that both ends of the communication channel agree on.

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

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

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

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

Problem solved.

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

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

So as an example, sending the following data stream:

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

would be done as:

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

(Added 0x10s highlighted with brackets).

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


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

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

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


message:
Dim a led using a NPN transistor

I know there are a lot of questions about this topic, but I've tried everything and any possible guide online without success.

I want dim (increase and decrease the brightness) some leds (3.5 Watt each). To do that I'm using an Arduino Nano, a 10k potentiometer and an NPN transistor ([TIP41][1]).

I was able to drive the potentiometer as a switch: on/off. Now I want to control its brightness using the potentiometer. I don't get what I'm expecting because the led is always on except when the potentiometer is turned all the way on the right (where is connected Vcc).

This is the schematic:

[![dim led using transistor npn][2]][2]

This is my Arduino code:

    int pinPotentiometer = 0;
    int pinTransistor = 3;

    void setup() {
      Serial.begin(9600);
      pinMode(pinTransistor, OUTPUT);
      pinMode(pinPotentiometer, INPUT);
    }

    void loop() {
      int potValue = analogRead(pinPotentiometer);
      int outValue = map(potValue, 0, 1023, 0 ,255);
      Serial.println(outValue);
      digitalWrite(pinTransistor, outValue);
      delay(100);
    }

The potentiometer is working fine because I read from the serial values between 0 and 255.

Am I using the wrong transistor? Or maybe I'm using it in the wrong way?

**NOTE**: to test my circuit I'm using a small 5mm led and not the 3.5 Watt one so I don't have any external power source.

Many thanks!

  [1]: http://html.alldatasheet.com/html-pdf/2785/MOSPEC/TIP41C/443/3/TIP41C.html
  [2]: https://i.stack.imgur.com/QMaga.png

body:
Try using analogWrite().

Writes an analog value (PWM wave) to a pin. Can be used to light a LED at varying brightnesses or drive a motor at various speeds. After a call to analogWrite(), the pin will generate a steady square wave of the specified duty cycle until the next call to analogWrite() (or a call to digitalRead() or digitalWrite()) on the same pin. The frequency of the PWM signal on most pins is approximately 490 Hz. On the Uno and similar boards, pins 5 and 6 have a frequency of approximately 980 Hz.

Source: https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/


body: your transistor base should be connected to the PWM side of the Arduino and not the collector. put a 1kOhm resistor between that base and arduino too. collector to load, load to positive of battery or power source. emitter to ground.


message:
How to protect link/url form ESP-12E for controlling LED

I am using ESP8266 ESP-12E NodeMCU for controlling LEDs and Relay.

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

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

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

192.168.0.104/status1=0 (for turn off LED)

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

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

Here is my code, this code works very well:

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

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

    ESP8266WebServer server(80);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      server.on("/", handleRoot);

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

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

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

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

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

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

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

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

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

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

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

Thank you.

Dear Garben,

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

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

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

    const char* pwd = "dada123456";

    ESP8266WebServer server(80);

    const int output4 = D4;

    boolean device4 = false;

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

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

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

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

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

    void setup(void){

      pinMode(output4, OUTPUT);

      digitalWrite(output4, LOW);

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

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

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

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

      server.on("/", handleRoot);

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

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

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

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

body:
You need to take a look at the [HttpBasicAuth](https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WebServer/examples/HttpBasicAuth/HttpBasicAuth.ino) example that comes with the ESP8266's ESP8266WebServer library that you are using. It is simple enough.

Here it is pasted in for reference:

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

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

    ESP8266WebServer server(80);

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

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

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

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

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

The key part is this bit:

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

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

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


message:
How to decrease adc accuracy?

I read in this [atmega328p datasheet][1] the following on page 308:

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

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

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

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

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

  [1]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf

body:
From: http://forum.arduino.cc/index.php?topic=6549.0

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

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

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


message:
3rd Libraries: fatal error: Something.h: File does not exist

> I created this question because I find many questions with similar problems,
> so I wanted to provide a reference/ more generic question for these type of problems.

For my projects I have installed 3rd party libraries by cloning from the library's git repository into the folder that `preferences.txt`'s `sketchbook.path` value exists into a folder named `libraries`. In other words if the `sketchbook.path` has the value `/home/myuser/sketchbook` I clone the repositories into the folder `/home/myuser/sketchbook/libraries`.

Then on the folder `/home/myuser/sketchbook/myexample` I store my code `myexample.ino` that needs a library with header files `Something.h`.

While I click on Arduino IDE the verify button I get the error:

    /usr/share/arduino/hardware/tools/avr/bin/avr-g++ -c -g -Os -Wall -fno-exceptions
        -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD
        -DUSB_VID=null -DUSB_PID=null -DARDUINO=105 -D__PROG_TYPES_COMPAT__
        -I/usr/share/arduino/hardware/arduino/cores/arduino
        -I/usr/share/arduino/hardware/arduino/variants/standard
        -I/usr/share/arduino/libraries/SPI
        /tmp/build6596169359663087897.tmp/LoRaSerialGateway.cpp -o
        /tmp/build6596169359663087897.tmp/LoRaSerialGateway.cpp.o
    LoRaSerialGateway.ino:15:18: fatal error: Something.h:
    compilation terminated.

So my guess is that I cannot make avr-gcc to compile using the 3rd party library. Do you know how to pass into avr-gcc the correct paths for the appropriate libraries?

body:
Sometimes you should modify a bit the library's file stricture in case of [this](https://github.com/sandeepmistry/arduino-LoRa) library in order to make it avaialble I moved the code in folder `./src` **outside** to the **project's** root folder.

Also an another problem is that you may use older version of the ide. Especially this can happen in GNU/Linux if you install the arduino ide from the distribution's repositories.


body:
Assuming you have a working library system already, i.e., there are some libraries in `.../libraries` now and they compile properly or at least the compiler are successfully finds them; and you want to add another library, say "CrashAndBurn.h" and "CrashAndBurn.cpp", you need to put those two files into a folder named `.../libraries/CrashAndBurn/`. Then in your sketch, you add an include directive `#include <CrashAndBurn.h>`.

An alternative is to put the .h and .cpp files somewhere else, such as a folder under your project folder, and modify the include directive to point to them, as `#include "libs/CrashAndBurn.h"`, where the libs folder is within the sketch folder. Or you could put them in any folder, anywhere, and write an absolute path to them: `/home/some/place/else/CrashAndBurn.h`


message:
Arduino IDE Display Code Line Numbers

In the Arduino IDE: How can I get the line numbers shown in a sidebar of the editor?

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

I am using Arduino IDE on a form of Windows.

body:
Go to **File > Preferences.** Under the **Settings** tab, click the checkbox for **Display line numbers**.

[![Options in arduino ide to show the lines on the code][1]][1]

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

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

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


message:
Arduino Uno programed from a Nvidia Jetson tx2

I'm trying to program my Arduino Uno with a Jetson tx2 and get the error

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

    avrdude: Send: 0 [30]   [20]
    avrdude: ser_recv(): programmer is not responding
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00

The serial port is set to /dev/ttyS0

dmesg when the Arduino is plugged in returns

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

    [78222.855639] usb 1-1: USB disconnect, device number 60
    [78224.468387] usb 1-1: new full-speed USB device number 61 using xhci-tegra
    [78224.605794] usb 1-1: feature bit otg_vbus_off set
    [78224.610575] usb 1-1: New USB device found, idVendor=2341, idProduct=0043
    [78224.617365] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=220
    [78224.624750] usb 1-1: Manufacturer: Arduino (www.arduino.cc)
    [78224.630502] usb 1-1: SerialNumber: 55739323237351306122
    [78224.636529] usb 1-1: ep 0x82 - rounding interval to 1024 microframes, ep desc says 2040 microframes
    [78224.646057] xhci-tegra 3530000.xhci: tegra_xhci_mbox_work mailbox command 6

lsusb returns

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

    Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 001 Device 054: ID 413c:2107 Dell Computer Corp.
    Bus 001 Device 065: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

body:
The device *should* be `/dev/ttyACM0`, *not* `/dev/ttyS0`.

Since it doesn't provide you with that device it rather looks like it doesn't have the CDC/ACM device drivers installed or loaded.

Depending on what distribution of Linux you're running on there you may need to install additional packages (you certainly do for OpenWRT, but I have no clue what that device is you're using or what it's running).


body:
When you built your Jenson kernel, did you enable the CDC/ACM driver using menuconfig?

From [Arduino Playground][1]:

> If you configured your own kernel, the driver is either under "Device
> Drivers => USB Support => USB Serial Converter Support => USB FTDI
> Single Port Serial Driver" or "Device Drivers => USB Support => USB
> Modem (CDC ACM) support". Select [Y], to have it "built in" to the
> kernel or [M] to have it built as a module.

I'm not familiar with Arduino and whether it would show up as `/dev/ttyUSB0` or `/dev/ttyACM0` per @Majenko.

  [1]: https://playground.arduino.cc/Learning/Linux "here"


body:
The version of the Arduino IDE contained in the Jetson repositories is buggy on the Jetson TX2 with Jetpack 3.2+ and the Arduino IDE in the repository is rather old.  Instead, try the beta related to [Github Issue #7302](https://github.com/arduino/Arduino/issues/7302).  This beta should work with the Jetson and other aarch64 platforms.  Many thanks to the wonderful people working to support this platform.

## Steps
After downloading and unpackaging the build, perform the following steps:

    #Install the OpenJDK Dependencies
    sudo apt-get install openjdk-8-jre openjdk-8-jdk

    #Remove the Packaged Java Folder
    cd ${PATH}/arduino-PR-beta1.9-BUILD-69
    sudo rm -r java

    #Add armhf Architecture to Package Manager
    sudo dpkg --add-architecture armhf
    sudo apt-get update
    sudo apt-get install libc6:armhf libstdc++6:armhf

    #Install the Arduino IDE
    sudo ./install.sh
    sudo ./arduino-linux-setup.sh

    #Reboot

## Notes
- The script `arduino-linux-setup.sh` handles the permissions for the IDE to talk to ttyACM0, updates the udev rules, and removes the pesky Modem Manger.
- The armhf packages are necessay to prevent ctags from crashing.
- If you are still having issues with CDC/ACM, install the module using the scripts from [JetsonHacks](https://www.jetsonhacks.com/2017/11/19/install-ttyacm-module-nvidia-jetson-tx-development-kits/)


message:
Reading bitswise for 'FALSE'

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

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

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

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

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

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

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

body:
The simplest thing is just to mask an individual bit, not do any shifting:

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

Or, to invert it:

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

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

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

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


body:
There is an alternative to doing bit shifts, and that is to use the `bit` macro which is defined in Arduino.h (and thus is automatically available).

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

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

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

This is easier to read than:

    if (options & (1 << 2))

or:

    if (options & 0x04)

---

And to invert it:

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

Or:

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

---

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

[![WDTCSR register][1]][1]

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

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

That is easier to read than:

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

And much easier than turning them into hex numbers:

    WDTCSR |= 0x10 | 0x08;

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

    WDTCSR &= ~bit (WDCE);

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


message:
Small Baseball Scoreboard using 2 to 3 breadboards

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

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

body:
Actually, you can very easily verify this yourself:

1. Per item (1602LCD, 7 segment LCD and LEDs check how many pins you need and what type, like e.g. I2C or SPI for the 1602 LCD). The 7 segment displays can have many or less pins, depending on the 'controller', See the reaction of CrossRoads below.

2. Count them together. If it fits on the Arduino you want to use OK. The Uno is cheapest, so if it fits on it, you use that, otherwise you can go to the Mega.

3. As alternative, and you need 'generic pins, called GPIOs' (not SPI/I2C) for some, you can use multiplexers like 74HC595 to reduce the number of GPIOs needed, at the cost of some speed (not critical for your project), and some more programming work.

4. In some cases you can use a MAX7219 driver IC, see (again) the remark of Crossroads below.


message:
USB reset fails on arduino due because of 5v on digital pins

I have the signal channels of four [5v magnetic encoders](http://www.portescap.com/products/motor-accessories/encoders/mr2-magneto-resistive-encoder) connected directly to the digital pins of the arduino due. I am aware that this is not allowed according to the specification which says that digital pins should only sink 3.3v but I have not encountered many problems with this setup until now and the encoders only sink 20mA.

This is the setup of one of the encoders, I only encounter the following problem only if I connect more than 2 encoders in this formation

[![circuit][1]][1]

The Due resets fine when I press the reset button, but when I reconnect USB, the Due crashes and is not able to run any code (tested a blink sketch).

I cannot change any of the circuitry because it is already in multiple PCBs. Does anybody have an idea why the 5v on the 3.3v tolerant pins is causing the reset over usb to fail and how I could fix this in software? It must be fixable in software as the arduino IDE manages to upload sketches while the encoders are connected. I tried to reset over USB by connecting with 1200 baud and setting DTR but that didnt work.

Thanks so much in advance, I hope my question was clear.

edit: I am aware I am doing things wrong here and that that is whats causing the issue. The problem is we soldered 20+ of those PCBs and I cannot simply make modifications, even simple ones. I am looking for ideas on how to hotfix something in software that I messed up in hardware.

edit edit: Honestly kinda disappointed with the hostility on here, am I being downvoted simply because I made mistake with the specification and am trying to find a workaround? I dont see how that makes it a bad question.

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

body:
You're over-stressing the MCU and causing all sorts of horrible things to happen with the power rails. Of course nasty things are going to happen.

The only way to fix it is to change the circuitry.  Something as simple as adding a 1kΩ resistor in series with each of the input connections could be enough to sort it out.


message:
How long does it take for a servo to change rotation?

I have an Arduino Uno and a [Micro Servo 9g A0090](https://www.sparkfun.com/products/9065) servo.

Given that [Servo.read()](https://www.arduino.cc/en/Reference/ServoRead) simply returns the _last_ value written to the servo I guess there is no way to query a servo's actual position.

If I can't query the servo, how do I know that the servo rotated to the position of my last [write()](https://www.arduino.cc/en/Reference/ServoWrite) call?

Rotating from 0 to 180 will take longer than rotating from 0 to 10. How do people normally handle this scenario? Perhaps I just time how long it takes to go from 0 to 180 and then always call [delay()](https://www.arduino.cc/reference/en/language/functions/time/delay/) afterward to give the servo time to complete its rotation?

body:
I can imagine several ways how to do it:

- You can wait some specific time. How long it takes to rotate from 0 to 180. But it'll wait for much longer for small angles than it's necessary.
- Better aproach would be to compute delay based on angle (maybe even on servo power supply voltage)
- Another way would be measuring servo's power supply current.
- You can use some rotary encoder. But some extra gears might be needed to be able to detect position fine enough.
- You can "hack" into the servo's electronic and get the position - it's usually voltage divider (potentiometer). But it might introduce some extra interferences and servo might be fuzzy or unstable...


body:
Normal servos don't provide any feedback. Their speed depends on the servo's specs and the load.

You could measure the time it takes to rotate a certain angle and use that to calculate the time, then add some safety margin. But if the load isn't constant, the times will be off.
You could change the position slowly, but that still doesn't guarantee that the servo will do what you told it to.

If you want to know servos's position, you need a servo that outputs it. There are servos that expose the signal from their internal potentiometer.

[![analog feedback servo][1]][1]

[Adafruit sells them][2] and has [a useful guide][3] about them.

[You can also modify a normal servo yourself, by attaching a feedback wire to the potentiometer's wiper pin.][4]

  [1]: https://i.stack.imgur.com/aqvrH.jpg
  [2]: https://www.adafruit.com/?q=Analog Feedback servo
  [3]: https://learn.adafruit.com/analog-feedback-servos/about-servos-and-feedback
  [4]: http://www.instructables.com/id/Servo-Feedback-Hack-free/


body:
For 9g servo .10 sec for 60 degree rotation.
For mg995 .18 to .19 sec for 60 degree rotation.
For servo 3003 0.19 to 0.20 or 60 degree rotation.

You can check specification for other servos. I gave for common servos above.

Hope this help.


message:
Need lot GPIO pins on arduino mega - what are restrictions?

I would like to use as much as possible GPIO pins on Arduino Mega especially with (mis)using `pinMode(x,INPUT);` and `pinMode(x,INPUT_PULLUP);` to achieve two things at the same time - drive something else by the pin weakly down or up and measure the logical level there with `digitalRead(x)` to detemine, if that "something else" is input, or outputting some logical level.

Also I need I2C, Serial over USB and nothing else.

On Arduino UNO/nano/micro/pro it works just fine for Digital pins (except D0/D1 (RX/TX), D13 (LED as strong pull-down), A4/A5 (I2C) and A6/A7 which are not digital IO). The problem is limited number of pins, so I bought **ArduinoMega**.

**The question is** - which pins can be used that way there?
So far I am aware of D0/D1 (RX/TX), D20/D21 (I2C) and D13 (LED).
The rest (D2-D12, D14-D19, D22-D52 and A0-A15) seem aviable and usable.
Or I am missing something else?

Are there some libraries/objects I should disable to not interfere with my script?

Thank you.

body: All those pins should be available. But if you want to use Pin change interrupts, you have to check which pins are usable.


message:
Looking for a sensor that measures heart/pulse rate

I am looking for a sensor which is able to measure heart/pulse rate. Apart from the common pulse sensor [from here][1], are there any others?

I have seen people recommending [this][2] as well, and it seems more accurate. Should I get the piezo vibration sensor or are there better sensors? Hoping for something that is easy to use (Like the pulse sensor where you can just place your finger onto the sensor)

Cross-post from: https://www.reddit.com/r/arduino/comments/8f051k/looking_for_a_sensor_which_measures_heartpulse/ and https://forum.arduino.cc/index.php?topic=543857.0

  [1]: https://pulsesensor.com/
  [2]: https://www.dfrobot.com/product-399.html

body:
The commonly used approach is to use an infrared source and sensor pressed against the skin.  Usually the finger tip is all that is needed. In addition to pulse, many have also incorporated an Oxygen measurement feature.

The 1st sensor you linked to appears to use this approach.  But instead of buying a ready made sensor, many have made a project of building their own...

This project has been done and published many times on the Internet.  There are well documented projects such as [this one from Rutgeurs][1].  As well as [this complex one from a journal called EDN][2].  And [this one][3] and [this one][4] from various independent hackers.

  [1]: https://pdfs.semanticscholar.org/9a69/e809de07ca61e1aed19dc5c5c52d8ed93cdd.pdf
  [2]: https://www.edn.com/design/medical/4434616/Simple-pulse-oximetry-for-wearable-monitor
  [3]: https://hackaday.com/2010/05/02/diy-pulse-oximeter/
  [4]: http://www.makery.info/en/2014/11/11/bricole-it-yourself-capter-son-pouls-du-bout-du-doigt/


message:
How do I merge two programs in Arduino?

So I have an esp8266 nodemcu which I flashed a program called Deauther 2.0. I spent the past two hours trying to merge another Sketch. Which I failed miserably.

What I am trying to achieve:

When I first power up my nodemcu it should load the Deauther program. But when I press the built in flash button it should load the second sketch.

What I have tried to fix the problem:

1. Add my own clock.cpp to the Deauther sketch and edited the top part of the sketch:

        const int button = 0;

        int temp = 0;

         void setup() {

         pinMode(button, INPUT)

         }

         void loop() {

         temp = digitalRead(button)

         if (temp == HIGH ) {

         // run the code below

        }

2. Some other stuff which I don't want to mention.

Any ideas on how to fix this?

Thanks!

body:
To be able to merge the sketches you must ensure that both will not try to access the same pins/resource in ways that are incompatible. For example if both need to input from serial you will need to adjust things so the input you send it will reach the correct code.

Once you have made sure of that it is often simplest to first refactor both sketches to avoid any type of delay-like code or anything that halts execution while waiting for something to happen and instead go with state-machine based that just loops constantly and uses timestamps to manage when to actually do stuff.

For example the second sketch has the format:

    void loop(){
        //do stuff

        delay(1000);
    }

You should refactor that to

    unsigned long last_run = 0;

    void loop(){
        unsigned long current_millis = millis();
        if(current_millis - last_run > 1000){
            last_run = current_millis;
            //do stuff that never blocks

        }
    }

Once that is complete and you made sure there is no name conflict between the sketches for the functions/globals you can simply append the `loop()` and `setup()` functions into a new `loop()` and `setup()`


message:
Sending data to Arduino Via Nodejs: Arduino does not echo back the data

I have the following sketch that runs in a arduino UNO:

    /*
     * Copyright 2018 Dimitrios Desyllas
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction,
     * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
     * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     */

    String inputString = "";         // a String to hold incoming data
    bool seralReadEnded=false;

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

    void loop() {
      if(seralReadEnded){
        sendDataOverSerial((byte [])inputString.c_str(),inputString.length());
        inputString="";
        seralReadEnded=false;
        delay(5000);
      }
    }

    String concatHex(byte value,String string){
      string+="\\x";
      if(value<16){
       string+="0";
      }
      string+=String(value,HEX);
      return string;
    }

    void sendDataOverSerial(byte byteArray[],size_t arrayLength){
      String returnVal="BEGIN:";
      for(int i=0;i<arrayLength;i++){
        returnVal=concatHex(byteArray[i],returnVal);
      }
      returnVal+="\n";
      Serial.println(returnVal);
    }

    void serialEvent() {
      while (Serial.available()) {
        // get the new byte:
        char inChar = (char)Serial.read();
        if(inChar == 0x11){
           char inChar = (char)Serial.read();
        } else if (inChar == 0x03) {
          seralReadEnded = true;
        } else {
         inputString+=inChar;
        }
      }
     }
And I made the following Node.js software in order to read and send data over the USB to arduino:

    const SerialPort = require('serialport');
    const Readline = require('parser-readline');
    const Ready = require('parser-ready');
    const Regex = require('parser-regex');
    const crypto = require('crypto')

    const valueIntoHex=function(value){
      switch(value){
        case 0x11:
          return "0x11";
        case 0x03:
          return "0x03";
        case 0x02:
          return "0x02";
        default:
          return value;
      }
    }

    /**
    * Escaping NonPrintable Ascii Characters (bytes) of a buffer data
    * @param <Buffer> data The data to read
    */
    const formatDataForSerialSend=function(data){
      //I allocate double the length because I assume worst case scenario that all bytes to be the ones I need to escape
      const returnBuffer =  Buffer.alloc(2*data.length);
      indexToWrite=0;
      //I use indexToWrite index because during escapes the posision that I write the byte is different from the ne I read.
      for(let i=0;i<data.length;i++){
        const byte=data.readUInt8(i);

        if(byte == 0x11 || byte == 0x03 || byte == 0x02){
          console.log("Escaped Ascii: "+valueIntoHex(byte));
          indexToWrite=returnBuffer.writeUInt8(0x11,indexToWrite);
        }
        indexToWrite=returnBuffer.writeUInt8(byte,indexToWrite);
      }
      returnBuffer.writeUInt8(0x03,indexToWrite);
      //Because I do not want uneeded size of data in my buffer
      const lastIndex=returnBuffer.lastIndexOf(0x03);
      return returnBuffer.slice(0,lastIndex+1);//I want size and not the last index. (Size=lastIndex+1)
    }

    /**
    * Application Specific send logic
    * @param <Buffer> data Data te send
    */
    const sendData=function(data){
      console.log("Escaping dirty Ascii");
      data=formatDataForSerialSend(data);
      console.log("SEND DATA: "+data.toString('hex'));
      port.write(data,'binary',(err)=>{
        if(err){
          console.err("Could not send data",err);
        }
      });
    }

    const portName = '/dev/ttyACM0';

    const port = new SerialPort(portName, {baudRate: 19200});

    //Look over: https://regex101.com/r/QcBTTj/1
    const hexRegex=/((\\|0)(x|X)[0-9A-Fa-f]{2})+/g;
    const parser = port.pipe(new Ready({ delimiter: 'BEGIN:' })).pipe(new Readline({ delimiter: '\r\n' }));

    console.log("################# SEND ####################");
    sendData(Buffer.from('hello','ascii'));
    console.log("############# END OF SEND #################");

    parser.on('data', function(input) {
        console.log("################# RECIEVE ##################");
        console.log("Message: "+input);

        const input2=input.replace(/^BEGIN:|(\r|\n|(\\|0)(x|X))/g,"");
        console.log("Sanitized Input: ",input2);

        try{
            const data=Buffer.from(input2,'hex')
            console.log("REPRINT HEX FOR VERIFICATION: "+data.toString('hex'));
            console.log("############ END RECIEVE ##############");
        } catch(e) {
            console.error(e);
        }
    });

But for some reason I managed to make it send data but the arduino does not send them back. So I want to debug it, but I do not know how I can do that I mean over arduino code how I will launch a debugger in order to do that?

How I can at the same time look and analyze the USB traffic between an application and Arduino in order to determine the logic bug?

Also I could not distinguish why arduino does not echo back some data, if I use this code for this sketch, the node.js application reads the data fine:

    /*
     * Copyright 2018 Dimitrios Desyllas
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction,
     * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
     * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     */

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

    void loop() {
      byte byteArray[]={1,10,255,3,4,2,1,55};
      for(int i=0;i<sizeof(byteArray);i++){
        Serial.print("\\x");
        if(byteArray[i]<16){Serial.print(0);}
        Serial.print(byteArray[i],HEX);
      }
      Serial.println("\n");
      delay(3000);
    }

# Edit1
So far I modified the sketch into this:

    String inputString = "";         // a String to hold incoming data
    bool seralReadEnded=false;

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

    void loop() {
      if(seralReadEnded){
        sendDataOverSerial((byte [])inputString.c_str(),inputString.length());
        inputString="";
        seralReadEnded=false;
      }
    }

    String concatHex(byte value,String string){
      string+="\\x";
      if(value<16){
       string+="0";
      }
      string+=String(value,HEX);
      return string;
    }

    void sendDataOverSerial(byte byteArray[],size_t arrayLength){
      String returnVal="BEGIN:";
      for(int i=0;i<arrayLength;i++){
        returnVal=concatHex(byteArray[i],returnVal);
      }
      returnVal+="\n";
      Serial.println(returnVal);
    }

    void serialEvent() {
      while (Serial.available()) {
        // get the new byte:
        char inChar = (char)Serial.read();
        if(inChar == 0x11){
           char inChar = (char)Serial.read();
        } else if (inChar == 0x03) {
          seralReadEnded = true;
        } else {
         inputString+=inChar;
        }
      }
     }

And I tested it by running over my GNU/Linux terminal like that:

    screen /dev/ttyACM0 19200

I typed some stuff and by pressing `CTRL+C` keyboard combination I managed to get them back (Somehow gives a character `0x03` that is the `ETX` ascii character that in my case indicated the data stream).

But How I get some random binary escape them with `0x11` charactes and send into arduino via bash, as fas ad I know is that on GNU/Linux systems I can use the `/dev/random` for generating data?

body:
There are too many `String` copies in your code. This is asking for
trouble, as it can lead to memory fragmentation and, ultimately, to
memory exhaustion. That's why I recommended in a comment to buffer the
data in plain byte arrays.

However, it appears your Node.js script is going to do the buffering
anyway (that's what the `Readline` parser does). Thus there is no point
in buffering also on the Arduino, which has one million (or more) times
less memory than the computer running the Node.js code. If the Arduino
just outputs the bytes as it gets them, the program becomes very simple:

    void setup()
    {
        Serial.begin(19200);
        Serial.print("BEGIN:");
    }

    // Send a byte over the serial port, formatted in hex.
    static void send_hex(uint8_t value)
    {
        Serial.print("\\x");
        if (value < 16)
            Serial.print('0');
        Serial.print(value, HEX);
    }

    void loop()
    {
        static bool escaped;  // is the next character escaped?
        if (Serial.available()) {
            char c = Serial.read();
            if (c == '\x10' && !escaped) {  // DLE (data link escape)
                escaped = true;
            } else if (c == '\x03' && !escaped) {  // ETX (end of text)
                Serial.print("\r\nBEGIN:");
            } else {
                send_hex(c);
                escaped = false;
            }
        }
    }

Note that, upon receiving an “end of text”, the program terminates the
current line (by sending "\r\n") and immediately sends the preamble for
the next one ("BEGIN:"). On the receiving side, the readline parser will
take care of delivering only complete lines.

If, for whatever reason, you do need to buffer inside the Arduino, then
remove the `Serial.print("BEGIN:");` line from `setup()` and change the
loop as follows:

    void loop()
    {
        static char buffer[1024];
        static size_t pos;    // current position in buffer
        static bool escaped;  // is the next character escaped?
        if (Serial.available()) {
            char c = Serial.read();
            if (c == '\x10' && !escaped) {  // DLE (data link escape)
                escaped = true;
            } else if (c == '\x03' && !escaped) {  // ETX (end of text)
                Serial.print("BEGIN:");
                for (size_t i = 0; i < pos; i++)
                    send_hex(buffer[i]);
                Serial.println();
                pos = 0;
            } else {
                if (pos < sizeof buffer)
                    buffer[pos++] = c;
                escaped = false;
            }
        }
    }

Note that the buffer is sized at half the RAM of your Uno. This is safe,
as it is a very simple program that uses very little dynamic memory
(stack only, no heap) and has no risk of fragmentation. Note also that
your original program stores _both_ the raw data and the formatted hex
(which is 4 times larger) in memory at the same time, which means your
buffering would be limited to 1/5 of the available RAM.


message:
"function" was not declared in this scope (called in setup)

I have this bit of code I'm trying to execute only once. but I seem to get this error every time I try to compile: "calcOppervlakte' was not declared in this scope" when it's being called in the setup.

I've looked at code examples where calling functions like this works, and I cannot wrap my head around this problem.

google isn't really helpful either since the search for something-something not declared in this scope gets me thousands of results.

    double pi = 3.14159265359;

    void setup() {
      Serial.begin(9600);
      for(int r = 1; r <11; r++){
        Serial.print(calcOppervlakte(r)); <----
      }
    }

    void loop() {

    }

    double calcOpppervlakte(float radius){
      double result = pi * pow(radius, 2);
      return result;
    }

body: The function name you're calling is **`calcOppervlakte`** but the function name in the definition is **`calcOpppervlakte`**. If you look closely you'll see there is an extra `p` in the function definition. If you change the names to match the error will be resolved.


message:
How to connect/call to the PSTN network using Arduino?

For a few months I made an alarm for my house, it is very simple: it is based on magnetic sensors DC-1561 (for windows and exterior doors), a few PIR sensors for rooms, buttons, LEDs and (of course) an ArduinoNano v3. Something simple!

The question is that lately I do not spend much time in my house and I would like it when I'm away from home the alarm calls me (when is activated) to my cell phone using the public switched telephone network (PSTN) because I live in Cuba and it's the easiest way and cheaper (the GSM modems/modules are very expensive for me). I do not want to leave any message or sound record, just call me and receive the call on my cell phone, using the RJ-11 connector (in my country only 2 pins are used) to connect it with the Arduino/some_IC.

[I have been investigating][1] since yesterday and have found quite a bit of information. The most recommended/successful that I found (remember that I want to continue using the system that I already have, I just want to add to the Arduino the ability to use the mark through the PSTN) is to use an IC ([HT9200B][2]) that is a generator of DTMF codes (as see in the figure) with serial AND parallel connection, aparently, compatible with the electronic logic of the Arduino (5V).

[![HT9200B connection][3]][3]

But of all the information that I found is to connect to this IC (HT9200B) a speaker and reproduce the DTMF codes. This is **not** what I want, what I want is to **connect directly to the phone line and be able to "call" from it**.

Anyone have any ideas, links, projects in progress, or anything that can help me?

  [1]: http://forum.arduino.cc/index.php?topic=14687.0
  [2]: http://www.futurlec.com/Others/HT9200B.shtml
  [3]: https://i.stack.imgur.com/uYroK.png

body:
As already written in the comments, you may use any RS232 modem you can find. They use the so-called AT commands, which is a very common way to exchange commands with this kind of peripheral. You can check on [wikipedia][1] or on google to get more information on it.

The main problem is that this kind of modems are a bit hard to find (or at least, they are a bit harder to find and a bit too expensive for my liking). That's why, for a project of mine, I wanted to switch to a cheaper alternative. Looking on the internet, a lot of people stated that it was much better to have an already approved instrument rather than designing your own. For this reason, I bought a mini-phone like this one:

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

You just have to open it, wire the keys (or rather, the rows and columns of the keypad) to the arduino and let it do the magic.

This solution is cheaper (I spent 4€ for this, but if you have an old phone it becomes free) than getting a RS232 modem, but needs more work on your side.

  [1]: https://en.wikipedia.org/wiki/Hayes_command_set
  [2]: https://i.stack.imgur.com/kINdX.jpg


message:
Arduino AES128 - CMAC

I'm looking for ***AES128*** library with ***CMAC*** for Arduino. Help me to find one

body:
I happen to know some libraries which use this. AES128-CMAC is for example used in the LoRaWAN MAC / driver implementation (LoRa is a low-power-wide-range radio technology). For example, the library Arduino-LMIC (**L**oRa **M**AC **i**n **C**) uses this AES-CMAC implementation (has actually 2 built-in, Ideetron is the other one):

* https://github.com/matthijskooijman/arduino-lmic/tree/master/src/aes

Other stacks use the mbedtls library with only the AES and CMAC layer activated. The library, written by ARM, is entirely in C and thus easily configrable (`config.h`) and compilable for the Arduino platform:

 * https://github.com/ARMmbed/mbedtls
 * https://github.com/ARMmbed/mbedtls/blob/development/library/cmac.c

Semetech's LoRa stack even has AES and CMAC abstracted in 4 four files:

* https://github.com/arduino-org/arduino-library-lora-node-shield/tree/master/src/system/crypto

Another good point would be to search PlatformIO's library index for "AES CMAC". Then this library comes up:

 * https://platformio.org/lib/search?query=AES CMAC
 * https://github.com/DavyLandman/AESLib

This also offers a CMAC implementation specifically designed for the Atmel AVR MCUs (Arduino Uno and likes) and partially written in Assembler. This should be best suited for you.

* https://github.com/DavyLandman/AESLib/blob/master/bcal-cmac.c


message:
Arduino MKR Zero problem with new UART comunication

I'm currently using an *Arduino MKR Zero* board and I need to add a new communication because the *Serial1* on pins 13 and 14 is already used by another device.

I've followed [this][1] tutorial from *Arduino* official website to create a new serial communication, but using the given code **I have no communication on pins 0 and 1**.

The code compiles, but it doesn't work when uploaded to the *MKR Zero* board.
I've noted that *IrqHandler()* is not highlighted in my *Arduino IDE* (it remains black).

So, should I install some library?

Thank you.

  [1]: https://www.arduino.cc/en/Tutorial/SamdSercom

body:
When a library does not highlight, it might be that the library is not coded to be highlighted (see [here][1]).

If you installed the library yourself, you may have put it in the wrong path.

  [1]: http://forum.arduino.cc/index.php?topic=202136.0


message:
Can I use an IR distance sensor in rain?

I am planning on using 'SHARP IR Distance Sensor - GP2Y0A710K0F' in an outdoor environment. Assuming the casing I design for the sensor is waterproof, can I use this IR sensor without any trouble? If the water is interfering, what can I do to reduce that noise?

The sensor is fixed above the ground and aimed towards the ground like this.

[![SHARP sensor is aimed towards the ground][1]][1]

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

body:
the ir-sensor senses a difference in infrared. the rain will only interfere if its way warmer then the base outside temperature. this is how humans and other mammals trigger infrared sensors on outdoor garden lamps. we emit infrared because our body temp being higher than the temperature of our surroundings.

just a nice quote from this site: https://www.techwalla.com/articles/how-do-ir-sensors-work

> All objects emit light according to their temperature--this is called "black body radiation." The hotter the object, the shorter wavelength of light it emits. The Earth emits infrared light at a peak of about nine to 10 micrometers--and so do warm-blooded animals like humans. This light can be used to detect motion or warmth.


body:
According to the [data sheet for this device][1], located at Adafruit's web site, the frequency used is 870nm. If you required specific attenuation figures, that might be useful information.

Another web site suggests that thermal IR camera imaging systems (which use a different frequency IR) are attenuated by rain. Some of the IR energy is lost by absorption and some by reflection. I was hesitant to suggest that as the answer due to the different frequencies involved.

[Digikey has a document][2] covering wide use of IR sensing. Listed in the document:

The disadvantages of IR technology are:

 1. Line of sight: transmitters and receivers must be almost directly
    aligned
 2. Blocked by common materials: people, walls, plants, and other objects can block transmission
 3. Short range: performance drops off with longer distances
 4. Light and weather sensitive: direct sunlight, rain, fog, dust, and pollution can affect transmission
 5. Speed: data rate transmission is lower than typical wired and RF transmission

Even though data transmission is not your objective, the considerations apply. A wet surface over which your sensor passes will have the signal attenuated and may also be slightly diffracted.

I found no direct reference to the magnitude of the attenuation. If your sensor is protected from water intrusion and the surface is only slightly wet, you may have minimal problems reading the distance. If the rainfall is at the level of a [frog-strangler][3], there could be sufficient water to eliminate useful readings.

Another search resulted in a similar question on the physics stack exhange, which led to [a more comprehensive answer][4]:

[![IR absorption graph][5]][5]

There is another image on the same page, but both show that at the 870nm frequency, there is lower attenuation than much of the IR spectrum, particularly above 3000nm. The above linked document suggests that the affect of rain (water) is low at near-infrared (970-1940nm) but that's still higher than the device's 870nm figure.

For your objective, shielding the surface from rain (umbrella) or clearing the surface of standing water seems to be the best options. If those are impractical, one would have to experiment to determine how much water flow can be tolerated before the signal is lost or attenuated beyond reception limits.

  [1]: https://cdn-shop.adafruit.com/datasheets/gp2y0a710k.pdf
  [2]: https://www.digikey.com/en/articles/techzone/2012/feb/using-infrared-technology-for-sensing
  [3]: https://www.urbandictionary.com/define.php?term=frog strangler
  [4]: http://www1.lsbu.ac.uk/water/water_vibrational_spectrum.html
  [5]: https://i.stack.imgur.com/jzaa5.gif


message:
Controlling voltage and current from chip?

I'm well aware that this question perfectly showcases my spectacular ignorance, but oh well. It's a simple enough question, so here we go.

I have a 595 chip (SN74HC595) wired up to an Arduino, fed by the 5V output. After switching all the outputs on, I measured an output pin at 5.04V and 74mA.

I want to use the chip's outputs to switch transistors (P2N2222A) which will have 60 mA through them (switching common cathode RGB LEDs), so I believe I need to drop it down to around .6 to 1.2V at .6mA, right (I'm not at all sure I'm reading the datasheet right)?

So how exactly do I do that? It seems like I need to put a resistor in between the pin and the base, but don't I need to know the TOTAL resistance of the circuit? Or can I just calculate from the pin itself (I believe that would need 7K)?

Thanks in advance for your help, and please feel free to OVER-explain if you're so inclined.

**EDIT:**

**EDIT 2: Resistor values are listed wrong. R1=200, R2 & R3 = 100.**

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

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

body:
You're misunderstanding what you need to drive a transistor.

A transistor will allow *up to* a specific amount of current through the collector depending on the current that flows through the base. If less is needed by the load then less will flow.

Think of it like a tap. If there's not much water pressure it doesn't matter how far you turn on the tap, after a certain point the flow of water won't increase any more.

To allow 60mA through the collector you need to provide *at least* 0.6mA (assuming a *hFE* of 100) through the base. That 0.6mA will set the *upper limit* of the current to 60mA. If you provide *more* than 0.6mA then you will allow a higher *upper limit*.

The 0.6V on the base is the voltage (difference between base and emitter when wired as "common emitter") at which current will start flowing through the base. It's the same concept as the forward voltage of an LED. For switching the voltage you put on the base must be *more than* 0.6V to allow current to start flowing. Since 5V is more than 0.6V you don't need to worry about it.  If you want precision in your calculations you will want to take that 0.6V into account, though.

So if you want *at least* 0.6mA from 5V with a 0.6V drop on the BE junction, you need:

    R=V/I = (5 - 0.6) / 0.0006 = 7.3kΩ.

That's the *maximum* resistance you want. Anything more than that and the current through the base will limit the current through the collector to *below* the 60mA you want.  So you must select some resistance that is lower than that.

What value? Well, it really doesn't matter that much. The lower the value the higher the current, but at these levels the current levels you're dealing with will be minuscule anyway.

It's common to use a 1kΩ resistor in the base for a transistor when using it as a simple switch like you are.  That would give you, for each transistor:

    I=V/R = (5 - 0.6) / 1000 = 4.4mA

For all 8 outputs that's a paltry 35.2mA. Far below the total the chip can provide of 70mA.

If you care about current consumption (you're running from batteries, for instance) you may want to increase to 4.7kΩ resistors to reduce the total drive current down to 7.5mA.


body:
You are making the design more complicated than it needs to be.
Use a WS2803 chip, it has 18 outputs, 0-255 PWM level programmable for each output.  Got more LEDs? Use more chips.
http://da-share.com/files/datasheets/WS2803.pdf

Or use WS2812B RGB LEDs, easy to wire up in a daisychain. SMD typically, and Sparkfun carries 2 thru hole variants also.


message:
Pro Micro recognised as Micro (win10, IDE 1.8.1)

I just got this [pro-micro clone 5V][1] and it's my first pro micro ever. After reading lots of discussions about how easy it is to brick and how it's just a smaller Leonardo, I've also found tutorials where they guide you to install custom things (sprkfun) to recognise the board, and others where it shows up as a Leonardo board.

However in my case I just plugged it in my Win10 laptop, the drivers got installed and it is automatically recognised as an Arduino Micro.
Since I haven't found people having this, and since I'd like not to brick it immediately I was wondering what's the procedure between:

 1. follow sparkfun's guide for pro micro and install their custom
    drivers
 2. treat it as a Leonardo (in the IDE)
 3. treat it as a standard Micro (in the IDE) since it's recognised as such

Thanks!

edit: solution: it's a **Leonardo**.

  [1]: https://www.ebay.co.uk/itm/Arduino-Pro-Micro-Leonardo-compatible-5V-16MHz-ATmega32U4-headers-UK-TESTED/251960157859?ssPageName=STRK:MEBIDX:IT&_trksid=p2057872.m2749.l2649

body:
Treat it as what it is.

What windows sees it as is just what USB reports it as. It's just a name. It has no bearing on what it is or how you program it. Select the actual board that you have in the IDE, not what Windows says it thinks it is.

As a general rule: Ignore everything Windows ever says, it's full of sh!t.


message:
How reliable is Arduino Uno Serial, via USB (ATmega16U2), CRC needed?

I have a question about the reliability of Serial communication, i.e. in particular if I need to implement CRC/checksum/ECC because of bit transmission errors?
I

I however think there is no general answer as there are different ways in which serial communication with the Arduino Uno's Atmega328P chip might work.

 - (a) The serial communication is between two Atmega328P Chips, and using rather long wires
 - (b) The serial communication is between two Atmega328P Chips, and using rather short wires
 - (c) The serial communication is between one Atmega328P and the ATmega16U2, who picks up and forwards the signals via USB protocol (e.g. to a PC)

My question is with regard to the ATmega16U2. The distance (wire/line length) on the Arduino R3 board is about 2cm/1" tops, which I expect to reduce the likeliness that a signal will become corrupted.
Assuming that the USB protocol which is further employed to transport the signal by itself provides by itself an ECC/CRC/checksums, I wonder if it is not rather superflous to implement a CRC when receving and sending messages via the serial communication in the case (c), while I however expect it to be *more* necessary for (b) and almost certainly necessary for (c).

Also, if this matters to respond to the question, I was wondering if the power supply (i.e. if Arduino Uno is powered by the USB provided voltage of ~4.5V or rather via an external 12V power adapter) would have an impact on the "corruptability" of the signals on the TX/RX serial lines?

body:
If you use the appropriate buffering of the 0/5V signal over the long wires, case A, no error detection and correction is needed. RS232, RS485, your data will be just fine (can be up to thousands of feet).

Shorter wires, from Atmega device to Atmega device, I've neved had to use anything, even at 115200 speeds, case B, case C.

16U2 to PC, that will depend on the quality of the USB cable. The +/-3V differential signal (similar to RS485 levels) is quite high speed, like 4 Mbits/second, so you want a good cable with good shielding.


message:
if two arduinos are connected by I2C and one of them is using an ethernet shield, does that grant both of them access to the internet?

i have two arduino mega and they send data to each other by an I2C connection. But one of those arduinos is connected to an ethernet shield which allows it to send data to a web server. Being both connected does that mean that they both can send or access the web server. Sorry if any ambiguity was found but I didnt find a better way to ask this question.

body:
It can but only if the one with the shield allows it (it acts like a router).

The only way for the arduino without the shield can communicate with the internet if it can send a message to the one with the shield and it will forward that message and return the replies back.


body:
I2C does not automatically share resources between two connected devices. You would not be able to share an Internet connection from a Mega connected via I2C to another Mega which has an Ethernet shield.

However, you **could** write code for both Megas that implements a two-way communication in which the non-shield Mega sends requests or commands to the one with the Shield, and then passes that data back to the non-shield Mega.

However, you, as the coder, would be responsible for designing such a protocol and implementing it. It would be quite a task probably.


message:
how to establish a connection between an arduino and a web server?

I want to establish a connection between my arduino mega ( which is connected to an ethernet shield so internet access is available) to a web server. Any idea how the code should be?
I searched for it but all I found was a local host connection establishment.
Thanks in advance.

body: The answer of this was already existing in the arduino examples which I forgot to check at first. Thanks Majenko for making me notice.