text:
How do I pull chip select pin up and down, when I have CAN shield and Newhaven Display 4.3CTP-SHIELD-N share the same chip select pin(10)?
I am currently working on an Arduino project, which must be able to listen to the data going through CAN bus and display it on the Touchscreen LCD Newhaven Display 4.3CTP-SHIELD-N.
Problem is that Sparkfun CAN shield and the LCD shield share the same chip select (CS/SS) pin 10. I've tried changing the chip select of the CAN shield by changing values in library headers, but it did not work and now I think that I should pull pin 10 low, when executing CAN code, then pull it up for the CAN shield. Afterwards, do the same for the LCD shield, but I do not know how to write the code for that. Is this the right way to think about the problem or am I missing something?
At this point, I am very confused because some people say that, if two shields have same chip select pin, it's impossible to stack them. Others claim that they succeeded in stacking two shields like that.
What other methods are there for stacking two shields with the same chip select pin?
I am using this CAN library: https://github.com/sandeepmistry/arduino-CAN/blob/master/API.md
This LCD library: https://github.com/NewhavenDisplay/FTDI_FT801

You will have to use a different chip select pin for one of the shields.  You should do it to the display shield since that goes on top.

Change the code to use a different chip select pin for the display shield
Break or cut off pin 10 from the display shield, and solder a wire from where pin 10 was to your newly chosen chip select pin.

Would it still work, if I didn't cut/break the pin 10 of the display, but connected it to another pin via a male-to-female jumper cable?

Sure, but it could be awkward. Just keep it away from the other shield's pin 10.


text:
Serial read multiple digits and always reading 10 at the end?
So I'm trying to make a program that allows you to enter a number in decimal and it displays it in binary, and it's going fairly well after some initial struggles (for some reason it read integers as 48 more than they are (5 read as 53)) but there's something I still don't understand, and I'm scared that it may be a hardware issue.
For some reason, I can't display two-digit numbers. For example, if I input 12, it displays 1, and THEN it displays 2. Also, to make things worse, it ALWAYS outputs 10 after I input ANY number. For example, if I input 5, it displays 5, and then ALWAYS 10.
    void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);

}

void loop() {
  // put your main code here, to run repeatedly:
  int number;
  if (Serial.available() > 0) {

    number = Serial.read();
    Serial.print("Number to display: ");
    Serial.println(number);

    if (number <= 15){
      int LEDPin = 2;
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
        for (int n = 0; n <= 4; n++){
          int binval = bitRead(number, n);
          Serial.println(binval);
          digitalWrite(LEDPin, binval);
          LEDPin++;
      }
    }
    else{
    Serial.println("Number must be less than 16!");
    }

    delay(1000);
  }
}

EDIT: And of course, after asking the question I re-ran the code and its AGAIN showing ints as 48 bigger than they are (5 as 53).
At this point, I'm extremely confused. Am I doing something wrong? Is this a hardware issue? What can I do?

It's called ASCII, and yes, '5' is the same as 53.

Possible duplicate of Why am I always getting 48 with serial communication?

I would suggest getting the user input with Serial.readBytesUntil(), store it in a char array, then use itoa() to get the integer value. Here is a modified version of your sketch.
char inputBuffer[5];
byte number = 0;

void setup() {
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
}

void loop() {

  if (Serial.available() > 0) {

    Serial.readBytesUntil('\n', inputBuffer, 4);
    number = atoi(inputBuffer);
    Serial.print("Number to display: ");
    Serial.println(inputBuffer);

    if (number <= 15){
      int LEDPin = 2;
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
        for (int n = 0; n <= 4; n++){
          int binval = bitRead(number, n);
          Serial.println(binval);
          digitalWrite(LEDPin, binval);
          LEDPin++;
      }
    }
    else{
      Serial.println("Number must be less than 16!");
    }
    delay(1000);
  }
}

or use parseInt()

Using parseInt() will produce the same result as readBytesUntil() with the input buffer and atoi(). Changing the OP's sketch to useparseInt() will be 2 lines less code, but will cost you and extra 98 bytes compile size. One of the benefits of using parseInt() would be the ease at which you can parse a comma separated list of integers from the serial monitor. If the OP plans on doing anything more complicated than entering one integer, then parseInt() is the way to go. Thank you for your comment Juraj.

for some reason it read integers as 48 more than they are (5 read as 53)

That's because you're not entering numbers, you're entering ASCII characters that represent numbers.
Everything you see on a computer or similar device is not really what is there. It is all translated into a form that we mere humans can see.  Every number is translated into readable characters, and readable characters have to be converted into numbers.
For example, the number 165 is the characters 1 (49), 6 (54) and 5(53).  When you enter that number you are sending those three individual characters.
You see the entire ASCII table here.
Another effect of sending individual characters is that you also send a marker to say "This is the end of the line". That can either be character 13 (Carriage Return), character 10 (Line Feed), or a combination of the two.  You can select which is sent in the Serial Monitor.
You should really use that line ending character or combination of characters to work out how many characters there are in your number so you can convert them into a proper integer value.
Some further reading:

Reading Serial on the Arduino (my blog)
The atoi() function

Regarding your "it ALWAYS outputs 10 after I input ANY number", I had the same problem using ASCII, and I think I finally figured it out. When you use Serial.println anywhere, it will output a line feed. In ASCII that is called newline and its value is 10. I have not yet figured a way to get around that.

byte ASCII_Number;

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

void loop() {
  Serial.println("Enter any single ASCII character:");
  while (Serial.available()==0) {}
  char ASCII_Character = Serial.read();
  ASCII_Number = (int)ASCII_Character;
  Serial.print("For your ASCII Character: ");
  Serial.print(ASCII_Character);
  Serial.print(" the ASCII Number is: [");
  Serial.print(ASCII_Number);
  Serial.println("] "); // print line always generates ASCII 10 (newline).
  //This runs the loop again with a newline for the character.
  delay (5000);
  ASCII_Number = 0;
}

As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

The original question is about getting LF on input. 2. Serial.println() outputs both a CR (13) and LF (10).

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
ESP8266 remapping or UART boot
I am trying to make an DFRobot Wifi Bee sleep periodically. The first run executes fine, but after the wakeup a lot of gibberish is shown in the serial monitor. I changed to baud rate to 74880 to see what was going on.
void setup() {
  Serial.begin(74880);
  Serial.setTimeout(2000);
  while (!Serial) { }
  Serial.println("Started.");
  delay(5000);
  Serial.println("Going to sleep.");
  delay(10);
  ESP.deepSleep(10e6);
}
void loop() { }

If I short-circuit D0 and RST, I get the following output
18:28:25.250 -> Going to sleep.
18:28:54.197 ->
18:28:54.197 ->  ets Jan  8 2013,rst cause:5, boot mode:(3,7)
18:28:54.197 ->
18:28:54.197 -> ets_main.c

Indicating that both GPIO0 and GPIO2 are high (which they should) and the cause of reset is power on and hardware watchdog reset.
A similar question has already been asked and answered ESP-01 not waking correctly up after deep sleep, but my issue is different, since I get the correct first boot parameter = 3 (both GPIO0 and GPIO2 are high)
I read here https://www.esp8266.com/viewtopic.php?f=6&t=8386#sthash.82ae9lvh.dpuf that the second boot parameter means
7 SDIO HighSpeed V2 IO  Uart1 Booting
6 SDIO LowSpeed V1 IO   Uart1 Booting
5 SDIO HighSpeed V1 IO  Uart1 Booting
4 SDIO LowSpeed V2 IO   Uart1 Booting
3 FLASH BOOT
2 Jump Boot
1 UART Boot
0 Remapping

I believe that I must change something to receive `boot mode:(3,3). If I remove the wire from GPIO16 to RST, I get almost the same result
18:41:25.250 -> Going to sleep.
18:41:54.197 ->
18:41:54.197 ->  ets Jan  8 2013,rst cause:5, boot mode:(3,0)
18:41:54.197 ->
18:41:54.197 -> ets_main.c

So now a Remapping occurs (or?).
I am running the module using an FDTI USB connector from SparkFun.
Any help is appreciated.

how do you wire io 16 to rst on this board?

They has a link showing that the XPD signal (GPIO16) and RST were connected to physical PIN 9 and 12. Just added a jumper wire.

The schematic link https://raw.githubusercontent.com/Arduinolibrary/DFRobot_Wifi_Bee_ESP8266/master/TEL0092%20Wifi%20Bee%20ESP8266%20SCH.pdf in this document https://www.dfrobot.com/product-1279.html shows how the signals are connected to physical PINS.

it doesn't match this. https://wiki.dfrobot.com/SKU_TEL0092_WiFi_Bee-ESP8266_Wirelss_module#target_2  it is a schematics for some diferent board

I just added a probe to the corner leg of the chip (XPD / GPIO16) and it is indeed connected to PIN9. DFRobot links to this diagram. If it doesn't match, they provide wrong information

@Juraj Thank you for the information. DFRobot apparently provides different information in different places. I managed to pull high DIO0 and use it to flash a LED. According to your link, this should be NC (impossible)h

I used PIN 12 (shown in lower corner of the schematic).... I could try 8 instead

Let us continue this discussion in chat.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Stepper Motor - Limit Switch for Position
I'm following this guide
https://howtomechatronics.com/tutorials/arduino/diy-motorized-camera-slider-pan-tilt-head-project/
My question is with the following piece of code used to calibrate the position values.
  // Move the slider to the initial position - homing
  while (digitalRead(limitSwitch) != 0) {
    stepper1.setSpeed(3000);
    stepper1.runSpeed();
    stepper1.setCurrentPosition(0); // When limit switch pressed set position to 0 steps
  }
  delay(20);
  // Move 200 steps back from the limit switch
  while (stepper1.currentPosition() != -200) {
    stepper1.setSpeed(-3000);
    stepper1.run();
  }
}

I understand the first while loop is to to get a zeroth position for calibration. But why move it 200 steps back and then set speed to -3000?[Q1] I don't understand that part.
And then later on in loop(), there is
// Limiting the movement - Do nothing if limit switch pressed or distance traveled in other direction greater then 80cm
  while (digitalRead(limitSwitch) == 0 || stepper1.currentPosition() < -64800) {}

I understand the first condition but why is second one there? Is it because 80cm is the max length of the slider/track and you don't want the stepper to move more than that? [Q2] Also how does 64800 = 80cm? [Q3]
Full Code: [Not mine - from link above]
/*
  DIY Camera Slider with Pan and Tilt Head
  by Dejan Nedelkovski
  www.HowToMechatronics.com

  Library - AccelStepper by Mike McCauley:
  http://www.airspayce.com/mikem/arduino/AccelStepper/index.html

*/

#include <AccelStepper.h>
#include <MultiStepper.h>

#define JoyX A0       // Joystick X pin
#define JoyY A1       // Joystick Y pin
#define slider A2     // Slider potentiometer
#define inOutPot A3   // In and Out speed potentiometer
#define JoySwitch 10  // Joystick switch connected
#define InOutSet 12   // Set Button
#define limitSwitch 11
#define inLED 8
#define outLED 9

// Define the stepper motors and the pins the will use
AccelStepper stepper1(1, 7, 6); // (Type:driver, STEP, DIR)
AccelStepper stepper2(1, 5, 4);
AccelStepper stepper3(1, 3, 2);

MultiStepper StepperControl;  // Create instance of MultiStepper

long gotoposition[3]; // An array to store the In or Out position for each stepper motor

int JoyXPos = 0;
int JoyYPos = 0;
int sliderPos = 0;
int currentSpeed = 100;
int inOutSpeed = 100;

int XInPoint = 0;
int YInPoint = 0;
int ZInPoint = 0;
int XOutPoint = 0;
int YOutPoint = 0;
int ZOutPoint = 0;
int InandOut = 0;

void setup() {
  // Set initial seed values for the steppers
  stepper1.setMaxSpeed(3000);
  stepper1.setSpeed(200);
  stepper2.setMaxSpeed(3000);
  stepper2.setSpeed(200);
  stepper3.setMaxSpeed(3000);
  stepper3.setSpeed(200);
  pinMode(JoySwitch, INPUT_PULLUP);
  pinMode(InOutSet, INPUT_PULLUP);
  pinMode(limitSwitch, INPUT_PULLUP);
  pinMode(inLED, OUTPUT);
  pinMode(outLED, OUTPUT);

  // Create instances for MultiStepper - Adding the 3 steppers to the StepperControl instance for multi control
  StepperControl.addStepper(stepper1);
  StepperControl.addStepper(stepper2);
  StepperControl.addStepper(stepper3);

  // Move the slider to the initial position - homing
  while (digitalRead(limitSwitch) != 0) {
    stepper1.setSpeed(3000);
    stepper1.runSpeed();
    stepper1.setCurrentPosition(0); // When limit switch pressed set position to 0 steps
  }
  delay(20);
  // Move 200 steps back from the limit switch
  while (stepper1.currentPosition() != -200) {
    stepper1.setSpeed(-3000);
    stepper1.run();
  }

}

void loop() {
  // Limiting the movement - Do nothing if limit switch pressed or distance traveled in other direction greater then 80cm
  while (digitalRead(limitSwitch) == 0 || stepper1.currentPosition() < -64800) {}

  // If Joystick pressed increase the Pan and Tilt speeds
  if (digitalRead(JoySwitch) == 0) {
    currentSpeed = currentSpeed + 50;
    delay(200);
  }
  // If Set button is pressed - toggle between the switch cases
  if (digitalRead(InOutSet) == 0) {
    delay(500);
    // If we hold set button pressed longer then half a second, reset the in and out positions
    if (digitalRead(InOutSet) == 0) {
      InandOut = 4;
    }
    switch (InandOut) {
      case 0:   // Set IN position
        InandOut = 1;
        XInPoint = stepper1.currentPosition(); // Set the IN position for steppers 1
        YInPoint = stepper2.currentPosition(); // Set the IN position for steppers 2
        ZInPoint = stepper3.currentPosition(); // Set the IN position for steppers 3
        digitalWrite(inLED, HIGH); // Light up inLed
        break;

      case 1: // Set OUT position
        InandOut = 2;
        XOutPoint = stepper1.currentPosition(); //  Set the OUT Points for both steppers
        YOutPoint = stepper2.currentPosition();
        ZOutPoint = stepper3.currentPosition();
        digitalWrite(outLED, HIGH);
        break;

      case 2: // Move to IN position / go to case 3
        InandOut = 3;
        inOutSpeed = analogRead(inOutPot); // Auto speed potentiometer
        // Place the IN position into the Array
        gotoposition[0] = XInPoint;
        gotoposition[1] = YInPoint;
        gotoposition[2] = ZInPoint;
        stepper1.setMaxSpeed(inOutSpeed);
        stepper2.setMaxSpeed(inOutSpeed);
        stepper3.setMaxSpeed(inOutSpeed);
        StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
        StepperControl.runSpeedToPosition(); // Blocks until all steppers are in position
        delay(200);
        break;

      case 3: // Move to OUT position / go back to case 2
        InandOut = 2;
        inOutSpeed = analogRead(inOutPot);
        // Place the OUT position into the Array
        gotoposition[0] = XOutPoint;
        gotoposition[1] = YOutPoint;
        gotoposition[2] = ZOutPoint;
        stepper1.setMaxSpeed(inOutSpeed);
        stepper2.setMaxSpeed(inOutSpeed);
        stepper3.setMaxSpeed(inOutSpeed);
        StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
        StepperControl.runSpeedToPosition(); // Blocks until all are in position
        delay(200);
        break;

      case 4: // If Set button is held longer then half a second go back to case 0
        InandOut = 0;
        digitalWrite(inLED, LOW);
        digitalWrite(outLED, LOW);
        delay(1000);
        break;
    }
  }

  // Joystick X - Pan movement
  JoyXPos = analogRead(JoyX);
  // if Joystick is moved left, move stepper 2 or pan to left
  if (JoyXPos > 600) {
    stepper2.setSpeed(currentSpeed);
  }
  // if Joystick is moved right, move stepper 2 or pan to right
  else if (JoyXPos < 400) {
    stepper2.setSpeed(-currentSpeed);
  }
  // if Joystick stays in middle, no movement
  else {
    stepper2.setSpeed(0);
  }

  //Joystick Y - Tilt movement
  JoyYPos = analogRead(JoyY);
  if (JoyYPos > 600) {
    stepper3.setSpeed(currentSpeed);
  }
  else if (JoyYPos < 400) {
    stepper3.setSpeed(-currentSpeed);
  }
  else {
    stepper3.setSpeed(0);
  }

  // Slider potentiometer
  sliderPos = analogRead(slider);
  // If potentiometer is turned left, move slider left
  if (sliderPos > 600) {
    sliderPos = map(sliderPos, 600, 1024, 0, 3000);
    stepper1.setSpeed(sliderPos); // Increase speed as turning
  }
  // If potentiometer is turned right, move slider right
  else if (sliderPos < 400 ) {
    sliderPos = map(sliderPos, 400, 0, 0, 3000);
    stepper1.setSpeed(-sliderPos); // Increase speed as turning
  }
  // If potentiometer in middle, no movement
  else {
    stepper1.setSpeed(0);
  }
  // Execute the above commands - run the stepper motors
  stepper1.runSpeed();
  stepper2.runSpeed();
  stepper3.runSpeed();
}

Q1: my guess is that it's just to move the slider a bit away from the limit switch, so it no longer reads LOW. Q2 I think you are correct. The original project you linked to only has a rail of around 80cm. And no limit switch on the other end. So he uses software to limit the travel. An alternative would be to add another limit switch, or simply change the value to reflect the size of rails you are using.

Q1: It is a common practice to move the stepper a bit away from the limit switch after a calibration, so that it can again be activated, if the stepper is moved into that direction. In most cases the limit switch marks a point very near or at a physical limitation, where the stepper cannot proceed and will hit some kind of wall. The limit switch can turn the motor off, before that happens. And your causal chain is incorrect. The code doesn't move to -200 and THEN set speed to -3000. Instead it checks in a while loop, if the position -200 is reached, and when not will set the speed and run the motor. When the position is finally reached due to the motor being run, the while loops exits.
Q2: The 80cm are used as a soft limit, meaning that the slider at this point will not hit a physical limit or a limit switch, only the software stops the slider to go further and finally hit a wall. This is often used to save limit switches in a physically confined situation and also not hit any physical walls, since a collusion is mostly undesirable (due to possible harm to people and the machine). The 80cm are known here (because the rail for the slider is no longer, than that).
Q3: The Stepper does not count in length (cm), but in the number of steps, that he has taken. Depending on the used stepper motor, 1 steps corresponds to a specific angle, that the motor will spin. And the mechanics determine, what angle of rotation corresponds to what distance on the rail. Most likely the author of the guide had calculated this for his specific build. You can calculated this yourself, so that you can use the correct conversion from steps to distance:
distance for 1 step = circumfence of the driving wheel / number of steps per revolution of the driving wheel

Or shorter:
d1 = C / N

Then you can calculate the steps for a specific distance d by
Nd = d / d1


text:
Software Gate on a PWM port
I'm using a PWM port and outputting a freq. Is it possible to pulse the PWM port using software to simulate a pulse gate. For example, I'd like to output a freq of 111hz, but would like to gate that freq at .5-7hz. Is this possible to do all in software without external hardware. I'm using a Teensy board which is similar to an Arduino, but has 3 independent PWM ports. Any ideas on whether this possible?

PWM is not for outputting different frequencies, but for outputting a square wave of a fixed frequency with different duty cycles. And it's not clear, what do you mean by "gate that freq at .5-7hz" What exactly you are trying to achieve?

You could use one timer for the 111Hz and another timer with interrupt. In the interrupt turn the other timer on and off. It is even possible to use the tone() for 111Hz and millis() in the loop() to create that .5 to 7Hz. Can you explain what this is for? Is it a modulated 111Hz? How accurate should it be?

Yes, I understand fully what the PWM port does and how it works and have been using it for years =) What I’m trying to achieve is how to change the shape of the freq by adding a controllable gate on the PWM port in software. I can do this by outputting the PWM freq into a collector of an 2N3904 transistor and drive the base of the transistor w/ another PWM acting has the gate freq and the emitter will have the newly shaped freq which seems to work, but would like to do it all in software using a timer on the PWM port. Is this possible?

btw, this is for a brain tuner circuit I'm building. The brain is stimulated at freqs of 111Hz and 1110HZ, but pulsing the freq slightly w/ a controllable gate will alter the shape to create different types of stimulation modes. This is what I'm trying to achieve using the freq gate on the PWM port. The accuracy should be as close as possible. Once the wave form is created, it will be put through another circuit that includes a transformer to create the final output signal. If I can do the gating in software that would be really cool =) Tnx for your help.

Jot 23, do you know of any good code examples using a timer interrupt on a PWM port to achieve what I'm looking for? Currently, I have 2 PWM ports 1 at running at 111Hz and 1 running at 1110Hz and both need a controllable gate of 5. to 7Hz applied to it. If the timer interrupt would be fast enough to work, that would be neat since I'd like to do this all in software if possible. In theory it should work. The Teensy v3.2 is a fast processor.

If you can configure the PWM to run at 111 Hz (I don't know how
this is done on the Teensy), then “gating” it is as simple as turning
the PWM on and off at the desired frequency:
uint32_t half_period;  // half the gating period in microseconds

void set_gate_frequency(float freq_in_hz)
{
    half_period = (1e6 / 2) / freq_in_hz;
}

void loop()
{
    static uint32_t last_toggle = 0;
    static bool pwm_is_on = false;
    if (micros() - last_toggle >= half_period) {
        if (pwm_is_on) {
            digitalWrite(PWM_PIN, LOW);
            pwm_is_on = false;
        } else {
            analogWrite(PWM_PIN, 128);  // PWM with 50% duty cycle
            pwm_is_on = true;
        }
        last_toggle += half_period;
    }
}

Thank you, I will try that. I assume this is possible to put into a timer interrupt routine as well, is that correct? So I can separate it from the loop function.
For reference on a Teensy this is how you would configure a PWM port to output a frequency.
analogWriteResolution(8); // 187500Hz resolution
analogWriteFrequency(pwmPin,FreqHz);
analogWrite(pwmPin,dutyCycle);

@Wildview: Yes, you could use an interrupt. However, for such low frequencies, you don't need to. Doing this in loop() should work just as well, and you can add whatever else you want to the same loop(). That is, it will work well unless you do something wrong like using delay()...

Thanks. I noticed in looking at the waveform running your example. There is no change to the frequency even w/ a gate freq of 50hz. It appears the digitalWrite is not working correctly to set the pin low. If I changed the digitalWrite to this analogWrite(PWM_PIN_PIN, 0)  it looks like it's pulsing now. I have a 1K pull up on that port a well. Does the analogWrite(PWM_PIN_PIN, 0) have the same effect as the digitalWrite would?

On the AVR core, digitalWrite() turns off any ongoing PWM. Maybe it doesn't do that on the Teensy, I don't know. analogWrite(PWM_PIN, 0) should do the same. If it works for you, keep it.


text:
Stabilitiy Problem for Interrupts Code related to Flow sensor
There is a problem with code related in link Interrupts Problem with Flow sensor. Code is working but when I stop the pumps, flow value on lcd is frozen until I reset the arduino. And when I start the pumps, flowmeter shows firstly 0.54 value, then begin to show real values. But always 0.54 down or up ( if flow is 5 lt/min, lcd show sometimes 5 lt/min, 5+0.54 lt/min or 5-0.54 lt/min ). When there are no oil flow into flow sensor, value of flow have fixed value that last readings. Could you help me ?
 #include <Wire.h> //I2C lib
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
 // LCD lib
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

const int pot_pin = A0;
const int pump_pwm = 3;

const int resetButton = 11;
byte press_pin = A1;

//flowmeter parameters
int flowPin = 2;  // input pin on arduino D2

volatile double flowRate;   // value intented to calculate
volatile double flowR; // flow value in lt
volatile double totalFlow; // total output of flow from system

byte sensorInterrupt = 0; // interrupt 0 on D2 pin Arduino Nano

volatile int count; ////integer needs to be set as volatile to ensure it updates correctly during the interrupt process.

int pot_init= 0;
int pump_init= 0;
int percentValue =0;

unsigned long previous_read;
void setup() {

  pinMode(resetButton, INPUT);
  digitalWrite(resetButton, HIGH);

  lcd.begin(20,4);  // A4 - A5 connection SDA - SCL
  lcd.backlight();
  Serial.begin(9600);

  pinMode( flowPin,INPUT); // Set D2 pin as an input

  attachInterrupt(sensorInterrupt,Flow,RISING); // Configures interrupt 0 ( pin D2 on Arduino Nano ) to run function "Flow"
}
void flow_control(void) {

  // Print the flow rate for this second in litres / minute
    Serial.print("Flow rate: ");
    Serial.print(int(flowRate));  // Print the integer part of the variable
    Serial.print("L/min");
    Serial.print("\t");       // Print tab space

    // Print the cumulative total of litres flowed since starting
    Serial.print("Output Liquid Quantity: ");
    Serial.print(totalFlow/1000);
    Serial.println("L");

 if(digitalRead(resetButton) == LOW)
  {
    totalFlow = 0;
    lcd.setCursor(0, 3);
    lcd.print("Resetting....        ");

}

else {
 lcd.setCursor(0,3);
  lcd.print("Total: ");
  lcd.setCursor(7,3);
  lcd.print(totalFlow/1000);
  lcd.print(" lt");

}
  lcd.setCursor(0,2);
  lcd.print("Flow: ");
    lcd.setCursor(6,2);
  lcd.print(flowRate);
  lcd.print(" lt/min");

}

void Flow(void)
{
  count++; // every time this function is called, increment  "count" by 1

  if(millis() -  previous_read > 1000){
    noInterrupts(); // disable interrupts on arduino nano
    int local_count = count;
    count=0;
    interrupts(); // enables interrupts on arduino nano
    previous_read += 1000;

  flowR = (local_count*8.93);   // 112 pulse/lt 423.84 pulse /gallon
  flowRate= flowR*60;     // convert seconds to minutes, new unit is ml/minutes
  flowRate= flowRate/1000; // convert ml to liters, new unit is lt/minutes

  totalFlow += flowR;
 //process flowrate based on local_count

  //calculation for flowmeter

  }
}

void loop() {

  pressure_cal();
  pump_control();
  flow_control();

}

void pressure_cal(void) {

  float sensorVoltage = analogRead(press_pin);   // sensor voltage A0
  float psi = ((sensorVoltage-102)/204)*25;  // Offset    0 PSI= 0.5V=102 unit, 50 PSI= 2.5, 100 PSI= 4.5V, 1 PSI= 0.04V

  // calibration
  float bar = psi*(0.0689475729);           // Conversion PSI to BAR

  lcd.setCursor (0,1);
  lcd.print (psi);
  lcd.print (" PSI");

  lcd.setCursor ( 10,1);
  lcd.print(bar);
  lcd.print( " BAR");

  //lcd.setCursor(17,1);
  //lcd.print(sensorVoltage);

  Serial.print("\t Sensor Value = ");
  Serial.print(sensorVoltage);
  Serial.print("\t Bar = ");
  Serial.print(bar);
  Serial.print("\t PSI = ");
  Serial.println(psi);

  delay (100);
}

void pump_control(void)

{

  // read the analog in value:
  pot_init = analogRead(pot_pin);
  // map it to the range of the analog out:
  pump_init = map(pot_init, 0, 1023, 50, 230);  //  duty cycle between %20 - %90: speed control , duty cycle between %0 - %20: turned off  , duty cycle between %90 - %100: full speed
  // map pump speed percent of full scale
  percentValue = map (pump_init, 50, 230,0,100);
  // change the analog out value:
  analogWrite(pump_pwm, pump_init);

  // print the results to the Serial Monitor:
  Serial.print("\t Speed Input = ");
  Serial.print(pot_init);
  Serial.print("\t Speed Output = ");
  Serial.print(pump_init);
  Serial.print("\t Pump Speed Percentage = ");
  Serial.println(percentValue);

  lcd.setCursor(2,0);
  lcd.print("Speed: ");
  lcd.setCursor(8,0);
  lcd.print("%");
  lcd.setCursor(9,0);
  lcd.print(percentValue);
  lcd.print("     ");

 //  delay after the last reading:
  delay(10);

}

It is about the variable flowRate? Where is that variable calculated? Spoiler: in the interrupt. When there are no interrupts, that value is not calculated. I don't see a simple solution. The interrupt counts and the flowR should use that count (even if it is zero). That means you have to calculate flowR in the Arduino loop, you can use millis to calculate the actual elapsed time to allow that it is sometimes longer than 1 second.

But I add the interrupt code in void loop and function called by main loop. Code dont work. The code I added works , but there is stability problem. When ı begin arduino, Flow sensor shows 0.54 lt/min on LCD. And when flow begin, flowrate changes with +- 0.54 error ( like 4.00 lt/min then 4.54lt/min then 3.46 lt/min and ) How can I solve this problem in void loop ?

if (millis() -  previous_read > 1000) { [...] previous_read += 1000; [...] }

The code inside this block is obviously meant to be executed every
second. However, since this belongs to the interrupt handler, it only
has a chance to execute when the flow-meter sends interrupts. If the
flow is zero or very weak, this will not execute often enough.

flowmeter shows firstly 0.54 value

It is no coincidence that 0.54 is what you get when count == 1.
The piece of code above should be moved to the main loop(), or to a
function called from loop(). This way it will execute consistently
irrespective of whether there is some flow or not, which is the only way
to reliably read a zero flow. Note that for better timing consistency
you should avoid doing something like...

delay(100);

Don't do this. Instead, use the same trick as above:
if (millis() -  previous_pressure_print > 100) {
    previous_pressure_print += 100;
    pressure_cal();
}

But I add the interrupt code in void loop and function called by main loop. Code dont work. The code I added works , but there is stability problem. When ı begin arduino, Flow sensor shows 0.54 lt/min on LCD. And when flow begin, flowrate changes with +- 0.54 error ( like 4.00 lt/min then 4.54lt/min then 3.46 lt/min and ) How can I solve this problem in void loop ?

@sapphire: Do not describe the code, show it! Edit your question and add the version of the code you are talking about.


text:
Interrupts Problem with Flow sensor
 #include <Wire.h> //I2C lib
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
 // LCD lib
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

const int pot_pin = A0;
const int pump_pwm= 3;

int press_pin =A1;

//flowmeter parameters
int flowPin = 2;  // input pin on arduino D2

double flowRate;   // value intented to calculate
double flowR; // flow value in lt
double totalFlow; // total output of flow from system

byte sensorInterrupt = 0; // interrupt 0 on D2 pin Arduino Nano

volatile int count; ////integer needs to be set as volatile to ensure it updates correctly during the interrupt process.

int pot_init= 0;
int pump_init= 0;
int percentValue =0;

void setup() {

  lcd.begin(20,4);  // A4 - A5 connection SDA - SCL
  lcd.backlight();
  Serial.begin(9600);

  pinMode( flowPin,INPUT); // Set D2 pin as an input

  attachInterrupt(sensorInterrupt,Flow,RISING); // Configures interrupt 0 ( pin D2 on Arduino Nano ) to run function "Flow"
}

void flow_control(void) {

  count = 0; // reset counter so it could start counting from 0

  interrupts(); // enables interrupts on arduino nano
  delay(1000); // wait 1000 msec
  noInterrupts(); // disable interrupts on arduino nano

  //calculation for flowmeter

  flowR = (count*8.93);   // 112 pulse/lt 423.84 pulse /gallon
  flowRate= flowR*60;     // convert seconds to minutes, new unit is ml/minutes
  flowRate= flowRate/1000; // convert ml to liters, new unit is lt/minutes

  totalFlow += flowR;

  // Print the flow rate for this second in litres / minute
    Serial.print("Flow rate: ");
    Serial.print(int(flowRate));  // Print the integer part of the variable
    Serial.print("L/min");
    Serial.print("\t");       // Print tab space

    // Print the cumulative total of litres flowed since starting
    Serial.print("Output Liquid Quantity: ");
    Serial.print(totalFlow/1000);
    Serial.println("L");

    lcd.setCursor(0,2);
  lcd.print("Flow: ");
    lcd.setCursor(8,2);
  lcd.print(flowRate);
  lcd.print("lt/min");

  lcd.setCursor(0,3);
  lcd.print("Total: ");
  lcd.setCursor(8,2);
  lcd.print(totalFlow/1000);
  lcd.print("lt");

}

void Flow(void)
{
  count++; // every time this function is called, increment  "count" by 1
}

void loop() {

  pressure_cal();
  pump_control();
  flow_control();
  lcd_control();
}

void pressure_cal(void) {

  float sensorVoltage = analogRead(press_pin);   // sensor voltage A0
  float psi = ((sensorVoltage-102)/204)*25;  // Offset    0 PSI= 0.5V=102 unit, 50 PSI= 2.5, 100 PSI= 4.5V, 1 PSI= 0.04V

  // calibration
  float bar = psi*(0.0689475729);           // Conversion PSI to BAR

  lcd.setCursor (0,1);
  lcd.print (psi);
  lcd.print (" PSI");

  lcd.setCursor ( 10,1);
  lcd.print(bar);
  lcd.print( " BAR");

  //lcd.setCursor(17,1);
  //lcd.print(sensorVoltage);

  Serial.println (sensorVoltage);
  Serial.println(bar);
  Serial.println (psi);

  delay (100);
}

void pump_control(void)

{

  // read the analog in value:
  pot_init = analogRead(pot_pin);
  // map it to the range of the analog out:
  pump_init = map(pot_init, 0, 1023, 50, 230);  //  duty cycle between %20 - %90: speed control , duty cycle between %0 - %20: turned off  , duty cycle between %90 - %100: full speed
  // map pump speed percent of full scale
  percentValue = map (pump_init, 50, 230,0,100);
  // change the analog out value:
  analogWrite(pump_pwm, pump_init);

  // print the results to the Serial Monitor:
  Serial.print("\t Speed Input = ");
  Serial.print(pot_init);
  Serial.print("\t Speed Output = ");
  Serial.print(pump_init);
  Serial.print("\t Pump Speed Percentage = ");
  Serial.println(percentValue);

  lcd.setCursor(2,0);
  lcd.print("Speed: ");
  lcd.setCursor(8,0);
  lcd.print("%");
  lcd.setCursor(9,0);
  lcd.print(percentValue);
  lcd.print("     ");

 //  delay after the last reading:
  delay(2);

}

I try to write code including flow sensor, pressure sensor and pump. I wrote the code. But When I use interrupt , code stop. I used functions in " void loop()" . I moved the interrupt code ( flow_control) between void setup and void loop. But I can see outputs in serial monitor but I cannot see on lcd. Could you help me fix the problem ?

What happens in lcd_control()? You forgot to include that function.

I thought that I can code all lcd command in a function. But the code I added , the function is not active. I forgot to delete it.

A lot of peripheral libraries requires interrupts to be enabled, especially when they use timing or the I2C/SPI pins. Instead of disabling interrupts for the majority of the sketch, what you want to do is isolate disabling the interrupts to just reading and resetting the count variable:
noInterrupts(); // disable interrupts on arduino nano
local_count = count;
count=0;
interrupts(); // enables interrupts on arduino nano

Also all that processing takes some time which will skew the timing so it's better to use timestamp and millis:
unsigned long previous_read;
if(millis() -  previous_read > 1000){
    noInterrupts(); // disable interrupts on arduino nano
    int local_count = count;
    count=0;
    interrupts(); // enables interrupts on arduino nano
    previous_read += 1000;

    //process flowrate based on local_count

}

Should I replacey count8.93 by local_count8.93 ? When I do, Arduino says local_count  was not declared in this scope? What should I do ?
flowR = (count8.93);   // 112 pulse/lt 423.84 pulse /gallon
flowRate= flowR60;     // convert seconds to minutes, new unit is ml/minutes
flowRate= flowRate/1000; // convert ml to liters, new unit is lt/minutes

that calculation should be inside the if (where the comment is), you only need to run it when processing the new count.

Thank you so much ratchet. I want to add a button to reset only total flow on lcd
void flow_control(void)  {
if(digitalRead(resetButtonA) == LOW)
{
totalMilliLitresA = 0;
lcd.setCursor(0, 1);
lcd.print("0L");
}

Thank you so much.  I want to add a reset button to reset only total flow  on lcd. Is this code true inside void flow(void) ?
 void flow_control(void)  {

  if(digitalRead(resetButton) == LOW)
  {
    totalFlow = 0;
    lcd.setCursor(0, 3);
    lcd.print("0L");
  }


text:
How to Work Two Linear Actuator Synchronously by Using Arduino and VNH5019 Motor Driver?
I am newbie and I want to build a project that contains two linear actuator that move synchronously. Two of them will lift up and down at same time. I use arduino mega and VNH5019 motor driver. I have thompson electrac ELD linear actuator. I have never tried to synchronize two linear actuator. Linear actuator have encoder output ( it is hall effect encoder -( not absolute. So it cannot keep last position in case of power cut )). Encoder type is hall effect type. Encoder output voltage levels low (logical zero), typical / max is 0.1/0.25 Vdc. Also it has output fully extented/retracted signal. I tested it with H-Bridge motor driver made of 4 SSR relays and push button switches to retract and extract. There is a synchronization problem.The system will stop when actuators extracted 500 mm ( actuators have 900 mm stroke length) How should I solve that synchronozation problem could you help me ? What should I do?

It sounds like you need to watch both encoder outputs and don't let one get ahead of the other. Naturally, they won't sync exactly (i.e., pulse simultaneously) but you can set a limit on how many counts to let them differ by, before pausing the faster actuator while the slower one catches up.
If you need to save positions across a power failure, you'll need to 1) provide enough backup power to keep the system alive past the supply failure to give you time to stop both actuators and store both of their positions in EEPROM; and 2) provide a signal to the Arduino that the supplied power (not the backup) is going down, so it can begin its orderly shutdown.


text:
fatal error: avr/io.h: No such file or directory
I'm compiling a project on Due that was working correclty using UNO. I get this error : 'avr/io.h: No such file or directory'. Searching across the web, it seams I'm not the only one to get that error when using Arduino Due but didn't clearly figured out why it appears.
Of course, the file is present where it should be, I verified ..\Arduino\hardware\tools\avr\avr\include\avr\io.h
I opened it and see something like that :
...

#if defined (__AVR_AT94K__)
#  include <avr/ioat94k.h>
#elif defined (__AVR_AT43USB320__)
#  include <avr/io43u32x.h>
#elif defined (__AVR_AT43USB355__)
#  include <avr/io43u35x.h>
#elif defined (__AVR_AT76C711__)
#  include <avr/io76c711.h>
#elif defined (__AVR_AT86RF401__)
#  include <avr/io86r401.h>
#elif defined (__AVR_AT90PWM1__)
#  include <avr/io90pwm1.h>
#elif defined (__AVR_AT90PWM2__)
#  include <avr/io90pwmx.h>
#elif defined (__AVR_AT90PWM2B__)
#  include <avr/io90pwm2b.h>
#elif defined (__AVR_AT90PWM3__)
#  include <avr/io90pwmx.h>
#elif defined (__AVR_AT90PWM3B__)
#  include <avr/io90pwm3b.h>
#elif defined (__AVR_AT90PWM216__)
#  include <avr/io90pwm216.h>
#elif defined (__AVR_AT90PWM316__)
#  include <avr/io90pwm316.h>
#elif defined (__AVR_AT90PWM161__)
#  include <avr/io90pwm161.h>
#elif defined (__AVR_AT90PWM81__)
#  include <avr/io90pwm81.h>

...

so I suppose that a line referring to my card is missing or something like that ?
I'm using Arduino 1.6.12

The Due is SAM architecture. avr/io.h is specific to the AVR architecture of the Uno's microcontroller. The compiler will not look in the avr tools folder for that file and even if it did it wouldn't help because that file is not compatible with the SAM architecture.
This error indicates that part of the code you're attempting to compile (probably a library) is AVR specific. You will need to either port that code to the SAM architecture or find an alternative that is already compatible with Due.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
How to test if PWM mode is working correcly?
I d'like to test if the PWM mode is working correctly on the pins of my Arduino Board. Do you know a simple schema to do this ?

There are my options:

The default way to do this is to use an oscilloscope. These can be quite expensive.
Use a logic analyzer if the voltage is logic/binary (0 and 3.3 or 5V). These are very cheap.
The easiest way to know if it works without the devices above, is to lower the speed drastically (using a divider in the software, like 1000 or more to get PWM widths of 100 ms to multiple seconds) and connect the PWM output with a resistor and a LED to GND. If the LED flashes faster, the PWM speed is high, otherwise low. By using a stopwatch you can roughly calculate the PWM speed (taking the divider into account) and after the test remove the divider.
If the PWM is controlled completely from your Arduino (probably not), you can use a software counter and print it out afterwards to see the speed.

ha ! I knew that this cheap Chinese oscillator i bought one day could finally be useful at something. thank you

Do you have a DSO150 (analog?) scope or a digital logic analyzer? Last are really easy (and much faster, 8 channels) and cost less than 10 dollars.

this is a DSO Shell from JYE Tech , really cheap and poor but should to the job :)

Sounds good, I don't have such a digital oscilloscope but planning to get one eventually. I have a very old analog one but it is very hard to use (bad CRT). Anyway with your oscilloscope it should be possible to find out the PWM speed.

I just tried it and my PWM works correctly : )

Good luck with your project.

You could just do a simple analogWrite, varying the duty cycle, with an LED/resistor. Fade the value up & down, see if the LED gets brighter & dimmer.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
More than 500 pins
For a project I need 400-1000 pins controlled by one arduino. Each pin should work similar as arduino pin, so something like 5V, 90mA. Is using dozens of shift registers a good idea? And what power source should I connect?
My idea is following:
So one shift register requires 3 input pins to control it, and if one shift register has 12 output pins, I can connect 4 more shift registers to one shift register. Is it a good idea and will it work?

Shift registers can be daisy chained. But why do you need so many pins...?

Please be more specific about what it is you try to make.

Why are you powering the Arduino and shift registers separately? And why the shift registers by batteries? 1000 pins at 90mA each will be at max 90A.

whatever you want to do, there has to be a simpler, better, and cheaper way of getting it done. tell us more and i doubt you'll regret it...

You don't connect shift registers as a tree. That would be awfully slow.
Instead, you connect them as chains. Shift registers are meant to be
chained by connecting the serial out of one register to the serial in of
the next one, while both registers share the latch and clock lines. You
can chain as many as you want this way: a chain of four 8-bit shift
registers behaves like a single 32-bit shift register. See for example
this Arduino tutorial on the
595 to see how the
chaining works.
There is an issue, however, in making long chains: whenever you want to
change the state of one single output you have to shift the whole chain
again. And the longer the chain the longer it takes. Thus it is more
efficient to put in a single chain outputs that you will likely want to
change together, and use independent chains for outputs that are most
likely going to change at different times.
As for the wiring, you need three Arduino pins to drive one chain of
registers: data, clock and latch. But you can share the data and latch
pins between many chains, as long as you have a dedicated clock pin for
each chain. You should then be able to drive n independent chains
using n + 2 Arduino outputs.
As for the power, you have to estimate your power consumption (not just
the shift registers, but also whatever they are sourcing current into)
and find a 5 V power supply big enough to power your whole circuit.

But will shift registers support analog and digital input output pins? And lets say there are 500 pins, what approximate time is needed to update pins state? Is this resulting delay takes microseconds, milliseconds or noticable fraction of a second to update pins? Thanks

@rint: My answer was written thinking in terms of digital outputs. You can find parallel-in serial-out shift registers that can do digital inputs. Neither type can do analog, but you can look into analog multiplexers for that purpose. You may want to time a loop of shiftOut() to get an idea of the time required (one call to shiftOut() outputs 8 bits).

Here is a whole different approach.
Look at how they built the motion-controlled coffee table:
http://www.evilmadscientist.com/?s=LED+coffee+table

It has hundreds and hundreds of connections, so they subdivided the board so they could have distributed Arduinos.
So it is possible to control that many pins, and it may be best to use multiple Arduinos.


text:
How do I use ultrasound to track a moving object?
I'm trying to create a small scale, dumb-downed version of the pitch tracking systems used to detect the speed and direction of baseballs.
I'm currently working with an HC-SRO4 sensor and an Arduino, but I'm unsure how to expand because a single sensor can't track an object that's not moving linearly (ie rising or falling as it moves). My team's idea was to make a grid of multiple HC-SRO4's connected to one Arduino, but we're worried that the delay will be too large if we try to turn them on sequentially to avoid interference.
How can we use ultrasound to track a moving ball?

I wouldn't worry too much about the path of the ball not being straight. If you assume it goes straight and it gets off-track by 8 degrees (which is quite significant), your speed calculation will be off by only 1%. And you probably won't be more accurate than that anyway. I would worry about the limited range of the HC-SR04 though.

Yes you can use ultrasound to track a moving target, but I really doubt it could be done with an Arduino.
You need to be able to ping the object at least 3 times in the time it takes to move your beam width.  3 times because if you know where it is with the centred ping you need to calculate the direction of travel by pinging either side of the centre to see if it is there.
You then need to track it in three dimensions.  To do this you will need multiple sensors ideally at least 3 for 2D and 3 for 3D, so at least 6.  3 sensors in a plane will give you a reasonable degree of accuracy, but you beam width is key to this, the narrower the better.
Now you have to triangulate the position of the object, well actually work out the area of probability (for both planes) you never 'know' where it is really.
Oh and all 6 sensors need to have different frequencies to prevent interference, you then need to add in reflection processing to reduce false signals.
Its just much easier to buy a Pixy camera and download the software that they have for visually tracking your balls.


text:
Recording and playback sound
I'm working in an art project, is some kind of loop between contact microphones and walkie talkies. I want to create some kind of noisy feedback.
I'm putting one walkie-talkie inside of a bottle, and in front of the speaker/microphone from the walkie I want to put another contact microphone attached to an Arduino, and record the sounds of the walkie talkie and played with some delay in some buzzer in front of another contact microphone attached to an amp with three speakers. To sum up, I have like 3 parts linked between them, the first one the walkie, the second one with an Arduino and the third one a simple mic whith an amp and three speakers.
Only the second part will be working with the Arduino and I want it to record sound and play it simultaneously with some delay.
I worked with a friend with some servo motors and music shields and I've been doing some research. I found 3 very interesting projects one is this, that it's practically what I want to do Space Replaybut there's so little information about it, and the other two are Arduino Audio Input and Arduino Audio Output
So, my questions are:

If I use a music shield I don't need a DAC or/and an amp? or only an amp if my speakers are too loud?
In the project Space Replay they only use this music shield so with only one music shield I can record and play music simultaneously? or I need two music shields?
That Adafruit Wave Shield is only for Arduino uno, but it will be better or easier to work with DUE or Arduino Mega and another music shields or making my own circuits like in the instructables Arduino Audio Input and Output?

I don't care too much about the quality of the audio, as I said the purpose is make some noise. The only thing is I want to create some kind of echo, or some kind of cannon, between the first sound of the walkie and the others pick up sounds.
Any other comment or advice will be much appreciated and welcomed.
Thanks

Try using this shield from Adafruit. I believe it can record and play audio, and they have versions with and without amps.
I do not know about near-simultaneous playback, so read up a bit before buying.

@user173724 Hello, thank you for the answer. I found an example project with the adafruit waveshield, which is realtime voice changer more information here, also  in the waveRP library includes a folder with how to connect a mic to the wave shield, so I'm working with the wave shield but I'll take a look to the Music Maker shield.


text:
memory usage "dos and don'ts"
Though I've written C/C++ code for a long time, the unseen limitations on how memory was consumed on various MCU and SOC programming platforms have often tripped me up. As I'm about to build up code for my first large project for my NANO boards, which will likely use a fair amount of its resources, I'd like to be better prepared for any surprising and unexpected "gotchas" to look out for.
For example, on another SOC I recently worked on extensively (The Pololu.com wixel) I was very surprised to learn that function/method arguments and auto variables, which I'd normally expect to be stack allocated and recovered when a function returns were in fact permanently allocated for the life of the program! Wow! so on that platform, where I'd normally hate to "overwork" variables or reuse variables after their names no longer make sense, I had to adjust my coding to what I'd normally consider BAD for readability. Not to mention realizing that simple loop variables were better off allocated globally. Yecch!
Can those of you who have run into such unexpected coding issues in the Arduino environment share some "special" guidelines about things like this?

auto changed from a storage duration specifier to a variable type specifier in C++11. For simplicity don't use auto.

a positive surprise for me is array allocation on stack with size from a variable https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html

Oh... gee... sorry... I never meant to infer I ever used the 'auto' keyword (forgot it even existed!). I just meant whatever the default allocation was for non static vars declared within a function.

As you have noticed yourself, this can be somewhat platform-dependent.
Since you are working on a Nano, my answer will be for the AVR
architecture, when compiled with gcc, the avr-libc, and the Arduino core
library.
First, let me reassure you: this weird behavior you saw of the Wixel
doesn't happen on this platform. Local variables get allocated mostly in
CPU registers, then on the stack.
Now, the first general rule may sound obvious: think twice about what
your program really needs to remember. Also, use each time the
smallest possible data type. The C99 types int8_t, uint16_t and co.
are useful for this.
Another rule you will often hear on this platform: avoid dynamic
allocation, i.e. malloc() and new, as quite often you cannot afford
heap fragmentation. Avoid also the String class, as it relies on
dynamic allocation. Prefer when possible static allocation, or stack
allocation for small things.
Don't forget to use const for constants: with this qualifier the
compiler can often optimize the constants out as immediate operands. For
arrays of constants, use PROGMEM. Yes, it's not comfortable
to use, but it can save you lots of RAM. The F() macro for printing
constant messages is a special case of PROGMEM.
Lastly, be very careful with recursion.

Thanks. Good points! I'll usually avoid malloc or 'new' in any embedded program, especially one that might be running unattended for a long time. And also, I too have used codespace memory for any struct or arrays that won't ever change. Or even EEprom structs for things like settings. But just the fact that function vars are stack based is VERY good news. I began to worry seeing so much example code, where the same var name was used again and again, even when its name no longer made sense.

That last point is interesting too! I wonder if a recursive function that went blow past its stack limits would make the poor board nearly unreachable, as it would always run itself into the same hole everytime it saw power.  Its not like the old devices that you could force to a halt with a stream of CTRL-C's sent during power up!

@Randy: There is no stack limit. If you overflow your stack, you will just start to overwrite the program's heap, if any, then the .bss section, then the .data section.

It's not accurate to say things do or do not happen on a particular chip when they are in actuality results of the toolchain or even the language specification, rather than the hardware.

@ChrisStratton: You are right. I added a clarification to my answer. On the other hand, the AVR was designed with compilation in mind. It would be silly (though certainly possible) for a compiler to not use the register file and the stack pointer as they were designed to be used.

Edgar's got some great tips, and I'll reiterate one before giving a few more:
avoid dynamic memory allocation
Don't use malloc. When you're designing a system, budget out your RAM like you do your monthly budget. Make sure you're able to do everything at once.
And a couple other tips:
global statics
Make full use of the BSS block; try to block out space for as much as possible in global static arrays. You may shudder or scoff at the idea of putting everything at a global level, but embedded is a paradigm shift, with its own set of rules.
Since you'll have so many variables at a global level, static helps you to avoid polluting your namespace too much.
avoid fancy C++ features
In fact, try to not use C++ at all. C++ takes you "farther from the metal," with its RAII and its constructors and its implicit type conversion... It's much harder to keep a tight inventory of all of your resources when your language does so much behind the scenes. If you really want to use a certain C++ language feature, try to keep the tone of your code more like "C with bits of C++" rather than "C++ shoehorned into an embedded system." That never goes well.
Especially avoid generics/templates, which will eat up lots of your memory. Every time you use a new type with a template in your code, another copy of the template class is compiled into your program, just for that one type. Ever wonder why C++ binaries can balloon to 20, 50, even 100 MB? Templates, man. Templates.
const
This keyword should go on as many variables as it can. Keeping this habit will save on both execution time and space consumption. Learn the difference between const T* foo, T* const foo, and const T* const foo.

Too much of this is nonsense to ignore. Some of this is good, but recommending a bunch of global state is just bad advice and many people use C++ for this kind of programming. Embedded is not an excuse to write hard to maintain code.

Additionally, C++ templates need not be as heavy-weight as you make them out to be. The key is to make sure you compile with link-time optimization, to prevent each individual object file from having its own copy of each template specialization it uses. 10 different copies of vector<int>, one in each of 10 source files, gets a little unwieldy, but with LTO, the compiler/linker can deduplicate them down to a single shared copy. If you need the functionality, the template specialized code (especially after LTO inlining) is often pretty similar in size to what you'd write by hand.

Do not make a variable global if it is only used in one function. Make it static if the value needs to be remembered from invocation to invocation. Allocation-wise, a static local is the same as a global.

Thanks for the tips. I see the merit in some of this for small systems. Though I've seen C++ compilers come a long way, I'm still reluctant to use "pure" C++, and be 100% OOP in every corner of my code.  Sometimes its overkill. But still, building well established functionality into classes you can tuck away in a library does make your application a lot simpler to follow.


text:
DC motors not running using PWM and L298N motor driver
I'm just beginning to understand Arduino. Please bear with me. I have a collision avoidance car running on Arduino Uno, WB291111 L298N motor driver, SG90 servo, Arduino Shield v5, and HC-SR04 ultrasonic sensor. Also, I have the entire setup running on 8.4v batteries. If I just use HIGH/LOW on the motors, it will run without any problems. But if I use the PWM to run the motors on different speeds, it will NOT run at all. The sensor and servo works, but not the motors.  See my codes below. Let me know if you need further details. Any help is greatly appreciated.
#include <Servo.h>
#include <NewPing.h>

//our L298N control pins
const int enA = 10;
const int in1 = 6;
const int in2 = 7;

const int enB = 9;
const int in3 = 4;
const int in4 = 5;

//sensor pins
#define trig_pin A2
#define echo_pin A1

#define maximum_distance 500
boolean goesForward = false;
int distance = 100;

NewPing sonar(trig_pin, echo_pin, maximum_distance);
unsigned int uS;

#define SERVO_PIN 11
Servo servo_motor;

void setup(){
  Serial.begin(115200);
  pinMode(enA, OUTPUT);
  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);

  servo_motor.attach(SERVO_PIN);

  servo_motor.write(115);
  delay(2000);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
}

void loop(){

  int distanceRight = 0;
  int distanceLeft = 0;
  delay(50);

  if (distance <= 20){
    moveStop();
    delay(300);
    moveBackward();
    delay(200);
    moveStop();
    delay(300);
    distanceRight = lookRight();
    delay(200);
    distanceLeft = lookLeft();
    delay(200);

    if (distance >= distanceLeft){
      turnRight();
      moveStop();
    }
    else{
      turnLeft();
      moveStop();
    }
  }
  else{
    moveForward();
  }
    distance = readPing();
}

int lookRight(){
  Serial.print("Look Right");
  servo_motor.write(50);
  delay(500);
  int distance = readPing();
  delay(100);
  servo_motor.write(115);
  return distance;
}

int lookLeft(){
  Serial.print("Look Left");
  servo_motor.write(170);
  delay(500);
  int distance = readPing();
  delay(100);
  servo_motor.write(115);
  return distance;
  delay(100);
}

int readPing(){
  delay(70);
  int cm = sonar.ping_cm();
  if (cm==0){
    cm=500;
  }
  return cm;

}

void moveStop(){
  Serial.print("Stop");

  digitalWrite(in3, LOW);
  digitalWrite(in1, LOW);
  digitalWrite(in4, LOW);
  digitalWrite(in2, LOW);
}

void moveForward(){

  //if(!goesForward){

    //goesForward=true;

    Serial.print("Forward");

    digitalWrite(in1, HIGH);
    digitalWrite(in3, HIGH);

    digitalWrite(in2, LOW);
    digitalWrite(in4, LOW);

    analogWrite(enA, 250);
    analogWrite(enB, 250);

  //}
}

void moveBackward(){

  //goesForward=false;

  Serial.print("Backward");

  digitalWrite(in2, HIGH);
  digitalWrite(in4, HIGH);

  digitalWrite(in1, LOW);
  digitalWrite(in3, LOW);

}

void turnRight(){
  Serial.print("Right");

  digitalWrite(in1, HIGH);
  digitalWrite(in4, HIGH);

  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);

  delay(200);

  digitalWrite(in1, HIGH);
  digitalWrite(in3, HIGH);

  digitalWrite(in2, LOW);
  digitalWrite(in4, LOW);

}

void turnLeft(){
  Serial.print("Left");

  digitalWrite(in2, HIGH);
  digitalWrite(in3, HIGH);

  digitalWrite(in1, LOW);
  digitalWrite(in4, LOW);

  delay(200);

  digitalWrite(in1, HIGH);
  digitalWrite(in3, HIGH);

  digitalWrite(in2, LOW);
  digitalWrite(in4, LOW);
}

According to the Servo reference page it's not possible to use Servo library and PWM outputs on the pins 9 and 10.

On boards other than the Mega, use of the library disables analogWrite() (PWM) functionality on pins 9 and 10, whether or not there is a Servo on those pins.

Thank you so much for your input. I will try to use other PWM pins on the arduino uno board. I'll update if it works.

@JayZapanta You can only hope that NewPing library doesn't affect Timer2, as Servo library affects Timer1


text:
'Class SdFat' error message with Adafruit wave shield
I'm using Arduino Uno and Adafruit Wave Shield, with the WaveRP library.
I was able to run the example programs of the waveRP library, but I try to connect a mic to the shield, didn't go well, so I returned to one of the examples to verify if the shield was working well and now is showing me this error message. I damaged the shield?
> Arduino:1.8.2 (Mac OS X), Tarjeta:"Arduino/Genuino Uno"
>
> Documents/Arduino/libraries/Adafruit_waverp/examples/dapRP/dapRP.pde:
> In function 'void setup()': dapRP:31: error: 'class SdFat' has no
> member named 'init'    if (!sd.init(SPI_FULL_SPEED))
> sd.initErrorHalt();
>
>            ^ Documents/Arduino/libraries/Adafruit_waverp/examples/dapRP/dapRP.pde:
> In function 'void play(SdBaseFile*)': dapRP:67: error: no matching
> function for call to 'SdBaseFile::readDir(dir_t&)'    while
> (dir->readDir(dirBuf) > 0) {    // Read every file in the directory
> one at a time
>
>                              ^ Documents/Arduino/libraries/Adafruit_waverp/examples/dapRP/dapRP.pde:67:29:
> note: candidate is: In file included from
> Documents/Arduino/libraries/SdFat/SdFile.h:24:0,
>                  from  Documents/Arduino/libraries/SdFat/SdFat.h:38,
>                  from Documents/Arduino/libraries/Adafruit_waverp/WaveRP.h:22,
>                  from Documents/Arduino/libraries/Adafruit_waverp/examples/dapRP/dapRP.pde:4:
> Documents/Arduino/libraries/SdFat/SdBaseFile.h:325:10: note: int8_t
> SdBaseFile::readDir(dir_t*)    int8_t readDir(dir_t* dir);
>
>           ^ Documents/Arduino/libraries/SdFat/SdBaseFile.h:325:10: note:   no known conversion for argument 1 from 'dir_t {aka
> directoryEntry}' to 'dir_t* {aka directoryEntry*}' exit status 1
> 'class SdFat' has no member named 'init'
>

No, you didn't break the shield. That is a software error - a problem in your sketch. If it's an unmodified example maybe you need to reinstall the library.

@Majenko I reinstalled both libraries the SdFat one and the WaveRP, but it keeps saying the same


text:
Servotimer2, detach "stop"
I'm still struggling with the Servotimer2 library
I have an Arduino uno board with a servo motor with the servotimer2 library because I'm using a music shield beside the servomotor and the music shield library and the servo.h wasn't compatible.
But finally I make the two of them working together with the servotimer2.h but now I want my servo to rotate 90 or 180 and then "stop" for a minute and come back again, rotate, stop, rotate,stop, rotate, stop... short of thing so I read this what is commonly done to stop a servo after reaching desired point and now I know that servo can't stop, but they can detach
so I tried making something like this
#include <ServoTimer2.h>  // the servo library
#define rollPin  9

ServoTimer2 servoRoll;

void setup() {
  servoRoll.attach(rollPin);

}

// this function just increments a value until it reaches a maximum
int incPulse(int val, int inc){
   if( val + inc  > 2000 )
      return 1000 ;
   else
       return val + inc;

}

void loop()
{
   mover();
   parar();

}

void mover() {
 int val;

   servoRoll.attach(rollPin);
   val = incPulse( servoRoll.read(), 2);
   servoRoll.write(val);
   delay(10);

}
void parar() {

  servoRoll.detach();
     delay(100);
}

but the servo is only moving very slow and I think is not detaching in any moment. I'm quite lost, I'm very noobie and in the post(what is commonly done to stop a servo after reaching desired point) they said things like making while(true){} loop in the setup? or use millis() and other things that I don't understand quite well
But someone tried to do something like control the time the servo is stopping with the delay, so I tried something like this
#include <ServoTimer2.h>  // the servo library

// define the pins for the servos
#define rollPin  9

int pos = 0;

ServoTimer2 servoRoll;    // declare variables for up to eight servos

void setup() {
  servoRoll.attach(rollPin);     // attach a pin to the servos and they will start pulsing

}

//from https://learn.adafruit.com/multi-tasking-the-arduino-part-1/a-clean-sweep

void loop()
{
 for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    servoRoll.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
  {
    servoRoll.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }

}

but with this code, my servo is only moving once, and then stops and don't move again
and I think that my servo with the servotimer2 library is only moving with this
   int incPulse(int val, int inc){
   if( val + inc  > 2000 )
      return 1000 ;
   else
       return val + inc;
}

void loop()
{
 int val;

   val = incPulse( servoRoll.read(), 1);
   servoRoll.write(val);
  delay(10);
}

so, any ideas of what I'm doing wrong?

my servo is only moving once, and then stops You mean it turns 180° then no more? Once it has reached 180° (or 2000 µs) you need to decrease val by one to go the other way (from 2000 to 1000). For example:
int direction = 1;  // 1 or -1
void loop()
{
   int val;

   val = incPulse( servoRoll.read(), direction);
   servoRoll.write(val);
   if (direction <= 1000 || direction >= 2000) {
      direction = -direction;
   }
   delay(10);
}

thank you! can you explain me or redirect me to some place where I can learn more about  this kind of expressions " if (direction <= 1000 || direction >= 2000) {
direction = -direction;"

@Egm That is a "logical or" which means only one of the conditions has to be true for the body of the if statement to be executed. Search for "c logical operators".


text:
Make a Robotic Arm move straight not curved
I am planning on a project that includes a robotic arm controlled by Arduino. A simplified program of this would be:

A robotic arm picks up an object
The robotic arm then moves the object in a straight line
The robotic arm releases the object

The problem with this is that every robotic arm that I have seen works with servos, which rotate precisely within 0 and 180 degrees. But, because the robotic arm moves with servos, it then moves in a curved path, rather than the desired straight path.
The two paths in this problem appear in this image. The one on the left is the desired, but the one on the right is the one that occurs when using any robotic arm.

Is there any way to make the robotic arm move in a straight path? Is there a specific robotic arm that moves in straight lines rather than curved lines?
Thanks for any help!
Here is the link to an example of a robotic arm picking up an object and moving in a curved path, and not a desired straight path.

can you not use stepper motors instead of servos? they can be moved in precise and non-fixed amounts

@dandavis Are there robotic arms or similar robots that can pick up objects run by stepper motors? And don't these motors also make the robot move in a circle, which doesn't solve the problem?

ahh, i see your question. look into CNC design. or maybe you could invent some sort of weird elbowed arm with carefully choreographed movements...

The formal term for this is "inverse kinematics"  - first you model how the arm responds to the angle of each motor, then you invert it to determine the sequence of angles that will produce the path you want.  If you have just a few motors you may be able to puzzle it out analytically without formal methods.

https://robotics.stackexchange.com/questions/tagged/inverse-kinematics

You need to learn about Inverse Kinematics.

In robotics, inverse kinematics makes use of the kinematics equations to determine the joint parameters that provide a desired position for each of the robot's end-effectors. Specification of the movement of a robot so that its end-effectors achieve the desired tasks is known as motion planning. Inverse kinematics transforms the motion plan into joint actuator trajectories for the robot.

By deciding how you want the end to move and calculating the joint positions for each point along that path you can get straight line movements, etc.

It requires doing some geometry.  Think about how you would do that with your arm.  You'd have to move more than one joint at a time.  So you have to define the line you want to follow, and back calculate from each point on the line what the angles of all the joints need to be in order to put the end there.  This will require a bit of trigonometry.  Is that something you've studied before?


text:
2.8 Touchscreen does not work with Proto Screw Shield
I am using the Arduino Mega and the 2.8 touch screen by Adafruit, and I can't get the screen to work on my Proto R3 Screw Shield
Here are the tools I am using:

2.8 inch touch screen
Proto R3 Screw Shield

When I put the touch screen onto the Arduino Mega, no wiring needed, and run the graphic test provided by the Adafruit_ILI9341, everything works perfectly. The touch screen runs the animation, and my serial monitor outputs the information of my touch screen.
However, when I put the touch screen on the screw shield, which I place on the Arduino Mega, the touch screen stays white, no matter if I press either reset button, unplug and replug the Arduino, restart the IDE, take off and put everything back on.
I explicitly followed the instructions by Adafruit here that say how to get the screw shield working.
There is no contact between each soldered pin, and I cut and soldered the ICSP and MEGA jumpers on the bottom of the touch screen accordingly, as shown in the picture on the bottom right:

I tried using an SD card as a test to see if the proto R3 screw shield was not working at all, and reading an image off of the SD card. I got proper, working results, so everything worked fine with the screw shield then. This means that the screw shield still works with it's 5V pin.
What could be the cause of the touchscreen staying white? Thanks in advance!

You are set to use the ICSP header for communication with the screen. That is good, when you are directly connected to a Mega.
However that is bad when you are going via a shield that doesn't have an ICSP header.
The ICSP header is the 6-pin (3x2) header in the right of your picture. It has SPI signals that the screen needs. Your screw shield lacks those pins.
You need to pass those signals through. The simplest way would be to add a 3x2 stackable header (or two 3x1 stackable headers) upside down through the correct holes to line up with the ICSP header.


text:
Define preset colors using FastLed library
I'm using an addressable 150 led strip and an Arduino Nano to control it, using FastLed library.
I'm tring do create a function turn_on_leds, which gets 4 parameters:
1) delay time for lighting a led in the loop, 2) direction ( not relevant for now), 3) color index for colors array , 4) brightness percentage.
Problem #1: a color array is defined to select from a preset definitions of colors (Fastled reference, but when selecting col_indx =2, meaning colors[2], leds are not lit in Red as they should, AND when setting leds[i]=0xFF0000, the right result is set.
Problem #2: at loop there is a for intended for raise bightness from 0 to 100, BUT the results are 0 for first iteration and 9 for all others.
Appreciate any HELP!!
Guy
Code:
#include <FastLED.h>

#define NUM_LEDS 10
#define BRIGHTNESS  55
#define DATA_PIN 7

char *colors[] = {0x000000,0xFFFFFF,0xFF0000,0x008000,0x0000FF}; // black, white,r,g,b
CRGB leds[NUM_LEDS];
int t = 0;

void setup() {
  Serial.begin(9600);
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  //  FastLED.setBrightness(BRIGHTNESS);
}

void turn_leds_on(int del_1, bool dir_1, int col_indx, int bright_1) {
  if (dir_1 == true ) { // start to end
    for (int i = 0; i <= NUM_LEDS; i++) {
      leds[i] = 0xFF0000;//colors[col_indx];
      FastLED.setBrightness(bright_1*255/100);
      FastLED.show();
      delay(del_1);
    }
  }
}

void loop() {
  Serial.println(t);
  turn_leds_on(50, true, 2, 100);
  delay(1000);
  //  turn_leds_on(50, true, 0, t);
  //  delay(1000);

  if (t < 100 ) {
    t += 10;
  }
  else {
    t = 0;
  }
}

Your colors array should be CRGB type, not char *.
CRGB colors[] = {0x000000,0xFFFFFF,0xFF0000,0x008000,0x0000FF}; // black, white,r,g,b

For your second problem - you are overflowing the bounds of your LEDs array:
for (int i = 0; i <= NUM_LEDS; i++) {
  leds[i] = 0xFF0000;//colors[col_indx];

You are going from 0 to 10 inclusive. That's 11 iterations. There is no such array slice as leds[10], so the value you write to it ends up overwriting the next two bytes in memory - and those happen to be occupied by the variable t.

thank you. that solved problem 1, what about 2 ?

@Guy.D You are overflowing the bounds of an array.

OMG , you are so RIGHT.  ThankYou!


text:
Regain WIFI connectivity
I wrote a code to be implemented in a SONOFF device (ESP8266 chip).
My question is regarding disconnection due to failure/ power fail in wifi network - when such event happens, does wifi connectivity try to reconnect or to over come this possibility - should I enter  inside void loop () to verify wifi connectivity ?
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// GPIOs on SONOFF board
int LED_SONOFF = 13;
int REL_SONOFF = 12;
int PIN_SW = 14;

const char* ssid = "Home";
const char* password = "12345678";
const char* mqtt_server = "192.168.2.113";
int last_sw_state = 0;

WiFiClient espClient;
PubSubClient client(espClient);

char msg[50];
const char* clientID = "Sonoff";
char *client_temp = "HomePi/Dvir/Windows/";
const char* outTopic = "HomePi/Dvir/Messages";
const char* outTopic2 = "HomePi/Dvir/Windows/ESP32";
const char* inTopic [strlen(client_temp) + 3];
const char* inTopic2 = "HomePi/Dvir/Windows/All";

String clock;

void start_wifi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  for (int i=0; i<3; i++){
    digitalWrite(LED_SONOFF,LOW);
    delay(50);
    digitalWrite(LED_SONOFF,HIGH);
    delay(50);
  }
}

My question is regarding disconnection due to failure/ power fail in
  wifi network - when such event happens, does wifi connectivity try to
  reconnect or to over come this possibility

use WiFi.setAutoReconnect(true); when initializing WiFi
other useful option is WiFi.setAutoConnect(). It controls if the esp8266 next time starts the WiFi connection with remembered setting, before your sketch starts.

at the end of void start_wifi() or void loop()?

at start when connecting


text:
ESP32 - NTP inaccuracy after deep sleep
I'm trying to create a sensor sampling project using ESP32 ( battery, solar panel and temperature affects are not part of test right now to reduce external effects that may cause/ increase such behaviour ).
In current phase, I'm only testing the sleep & waking up process.
A short description: System wakes up after deep sleep cycle, connects to Wifi, MQTT, NTP - and checks if wake up time ( wake up value is stored in ׳RTC_DATA_ATTR long calc_waketime׳ variable from previous cycle ), posting IFTTT, goes to deep sleep for another 10 min. cycle.
The phenomena I wish to share is: The longer deep sleep is the NTP has few seconds drift which gets longer (again - NTP sync has a drift and not RTC clock).
I'm aware that wake time/ RTC drifts during deep sleep ( especially in ESP8266 chips that wake up can be not accurate in terms of minute - I'm using ESP32). Since ESP32 uses RTC, waking up is very accurate ( matter of seconds ). In order to wake up in exact time ( 18:00, 18:10, 18:20... every hour ) code connects to Wifi& NTP, and verify that wake time was as intended (comparing the epoch value that was stored during the end of previous cycle and current epoch time ) if it woke up earlier, it will got to sleep for that missing time.
But - What puzzles me is why updated NTP time ( which is not related what so ever to RTC drifts ), is drifted the longer to sleep is ( for comparison : when less than a minute - almost no drift, when sleeping for 10 minutes, 3 seconds drift, 20 minutes get up to 5 seconds drifts ).
Please see NOTE(1) to witness the drift in 10 min sleep.
Posting terminal output:
some explantions: NOTE (1) displays the 3 seconds drift , NOTE(2) calculated time that was stored at previous wake cycle, NOTE (3) shows that that drift get synced during the code run - 594 sec for next wake 18:50:00.
18:39:58.032 -> 09B⸮⸮L⸮1U1V(⸮⸮⸮1m1m1F⸮Connecting to Xiaomi_D6C8 .... // WAKING UP
18:39:58.595 -> 192.168.3.186
18:39:59.013 -> now is: 1580575203               **// NOTE (1)**
18:39:59.013 -> sleep time was: 1580574611
18:39:59.048 -> expected wake time: 1580575200   // NOTE (2)
18:39:59.085 -> total time delta: 3
18:39:59.122 -> OK - WOKE UP after due time:
18:39:59.419 -> Attempting MQTT connection...connected
18:40:04.544 -> Connecting to maker.ifttt.com
18:40:04.855 -> Request resource: /trigger/send_reading/with/key/cFLymB4JT9tlODsKLFn9TA
18:40:05.376 -> HTTP/1.1 200 OK
18:40:05.376 -> Date: Sat, 01 Feb 2020 16:40:05 GMT
18:40:05.414 -> Content-Type: text/html; charset=utf-8
18:40:05.447 -> Content-Length: 52
18:40:05.480 -> Connection: close
18:40:05.515 -> X-Top-SecreTTT: VG9vIGVhc3k/IElmIHlvdSBjYW4gcmVhZCB0aGlzLCBFbWFpbCB1cyBhdCBqb2JzK3NlY3JldEBpZnR0dC5jb20uIFdlIHdhbnQgTWFrZXJzLg==
18:40:05.619 -> Server: web_server
18:40:05.619 ->
18:40:05.619 -> Congratulations! You've fired the send_reading event
18:40:05.689 -> closing connection
18:40:07.007 -> Last Sleep: 1580574611
18:40:07.007 -> Time left: 594                 // NOTE (3)
18:40:07.041 -> Going to DeepSleep for [594] sec

Relevant code:
void sleepNOW(int sec2sleep = 2700)
{
  char tmsg[30];
  sprintf(tmsg, "Going to DeepSleep for [%d] sec", sec2sleep);
  Serial.println(tmsg);
  // mqtt_pubmsg(tmsg);
  Serial.flush();
  esp_sleep_enable_timer_wakeup(sec2sleep * uS_TO_S_FACTOR);
  esp_deep_sleep_start();
}
bool getTime()
{
  delay(200);
  if (getLocalTime(&timeinfo))
  {
    time(&now1);
    delay(200);
    return 1;
  }
  else
  {
    return 0;
  }
}

bool check_awake_ontime()
{
  getTime();
  if (timeinfo.tm_year >= 120) // year 2020
  {
    if (lastsleeptime != 0)
    { // not first boot
      long current_boottime = now1;
      int t_delta = now1 - calc_waketime;
      // int t_delta1 = TIME_TO_SLEEP * 60 - (t_delta + TIME_AWAKE);
      Serial.print("now is: ");
      Serial.println(now1);
      Serial.print("sleep time was: ");
      Serial.println(lastsleeptime);
      Serial.print("expected wake time: ");
      Serial.println(calc_waketime);

      Serial.print("total time delta: ");
      Serial.println(t_delta);
      if (t_delta >= 0)
      {
        Serial.println("OK - WOKE UP after due time: ");
        return 1;
      }
      else
      {
        Serial.println("FAIL- woke up before time: ");
        sleepNOW(-1 * t_delta);
        return 0;
      }
    }
    else
    {
      return 1;
    }
  }
  else
  {
    return 0;
  }
}

inside setup()
#if USE_WIFI
  if (startWifi())
  {
    mqttConnect();
    startNTP();
#if USE_SLEEP
    check_awake_ontime();   // PLEASE PAY ATTN ONLY THIS LINE
#endif
  }

inside loop()
#if USE_SLEEP
  if (millis() >= TIME_AWAKE * 1000)
  {
    getTime();

    Serial.print("Last Sleep: ");
    Serial.println(lastsleeptime);

    long clockCount = TIME_TO_SLEEP * 60 - (timeinfo.tm_min * 60 + timeinfo.tm_sec) % (TIME_TO_SLEEP * 60);
    // Serial.print(timeinfo.tm_hour);
    // Serial.print(":");
    // Serial.print(timeinfo.tm_min);
    // Serial.print(":");
    // Serial.print(timeinfo.tm_sec);
    // Serial.println("");
    Serial.print("Time left: ");
    Serial.println(clockCount);

    lastsleeptime = now1;
    calc_waketime = now1 + clockCount;

    sleepNOW(clockCount);
  }

I'm not posting entire code, but only relevant parts.
Appreciate any help,

the NTP only sets the RTC. and NTP is not immediate

@Juraj would you recommend a delay ? since getTime() has 2 delays of 200 mili's

5 seconds is usually enough. you can do a trick. reset the RTC time to 0 and then you can check if it is set by NTP already

@Juraj can you please explain how?

sorry, I forgot that there is no API for setting the RTC time on esp32. https://arduino.stackexchange.com/questions/72010/set-the-wall-clock-time-or-change-gmt-offset-without-ntp-server/72019#72019

As Juraj commented, a 2.5 [sec] delay, solved it, and NTP update was correct.

It's OK to accept your own answer as the solution to the problem.


text:
Splitting a message
I have a string to be splitted into define chunks.
For example new_str="abcdefghjklmnopqrstuvwxyz, and my goal is to split it to chunks of split_size=5, so the result should be :abcde,fghij and so o.
new_str gets every time a different string.
split_size can be any size.
I have 2 questions:
1) Attached code does the job, but looks a BIT not elegant for a newbie like me. is there another way doing it ?
2)In code attached, output is Serial.println(tmp) and should be replaced with an output function to post each chunk to as a MQTT message. Ive rather that each chunk would be stored into a global array, to be sent later on in code out side msgSplitter.
So I wrote the following code:
int split_size=5;
char new_str[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
void setup() {

        Serial.begin(9600);
        Serial.print("String length: ");
        Serial.println(strlen(new_str));
        Serial.print("Split Size: ");
        Serial.println(strlen(split_size));

        msgSplitter(new_str, split_size, "Split #");

}
void msgSplitter( const char* msg_in, int chop_size, char *prefix){
        num=ceil((float)strlen(msg_in)/chop_size);
        char tmp[50];
        int pre_len;

        if (num > 1) {
                for (int k=0; k<num; k++) {
                  pre_len=0;
                        sprintf(tmp,"%s %d: ",prefix,k);
                        pre_len = strlen(tmp);
                        for (int i=0; i<chop_size; i++) {
                                tmp[i+pre_len]=(char)msg_in[i+k*chop_size];
                                tmp[i+1+pre_len]='\0';
                        }
                        Serial.println(tmp);
                }
        }
        else {
                Serial.println(msg_in);
        }
}

// concat version
void msgSplitter(const char* msg_in, int chop_size, char *prefix) {
  char tmp[50];
  int size = strlen(msg_in);
  for (int pos = 0, k = 0; pos < size; pos += chop_size) {
    int l = sprintf(tmp, "%s %d: ", prefix, k++);
    strncat(tmp + l, msg_in + pos, chop_size);
    Serial.println(tmp);
  }
}

// only value version
void msgSplitter(const char* msg_in, int chop_size, char *prefix) {
  char tmp[chop_size + 1];
  tmp[chop_size] = 0;
  int size = strlen(msg_in);
  for (int pos = 0; pos < size; pos += chop_size) {
    strncpy(tmp, msg_in + pos, chop_size);
    Serial.println(tmp);
  }
}

Can you answer my 2nd cquestion ?

the second version of the function in my answer is it. replace println with the publishing function

You Rock Juraj!

U2 :) ( cough cough )


text:
Higher precision logarithms
I need to produce a log to base 10 with at least 4 decimal places. However, the log10 inbuilt function is giving the output with only two decimal places. What do I do? Is there a different function or a library that I can use?

How are you displaying the values? The number of decimal places you are seeing is probably a byproduct of the way you are converting them to strings, not of the underlying math. Most Arudino math is done with the float type, which should have about 6 or 7 decimal digits of precision.

I was just using a Serial.print without specifying any precision. This works, thanks

You should be able to get 6 or 7 decimal places out of the Arudino float type. Try using Serial.print for floats with a number of decimal places. Something like this:
float x = log10(3.141592658);
Serial.print(x, 6);


text:
Connecting DAC output from Arduino Due to another arduino
I have an Arduino Due and I want to connect the output from the DAC as an input to an Arduino Uno's analog input pin. From this link http://forum.arduino.cc/index.php?topic=164763.0, user DuaneB suggested that a resistor should be used in series with the DAC output to prevent an excessive flow of current that could damage the pin. But he was talking about this when the question was about powering a motor using the current generated from the DAC's voltage.
However, is this series resistor required when simply connecting the output of the pin to the input of another pin? I haven't seen any issue when connecting the output of my Raspberry Pi's GPIO to an arduino's input.

The inputs to Arduino pins are CMOS inputs, and present very high impedance.  (There is a tiny capacitor on every CMOS input, and the only current into the input is the very small amount needed to charge that capacitor.)
You don't need resistors when connecting inputs and outputs (digital or analog) between Arduinos. Should be the same with Raspberry Pi GPIO lines, or any other CMOS devices.

Do you mean the gate-channel capacitor in the MOSFETs or something totally different?

I’m not an electrical engineer, and don’t remember the specifics. Google CMOS and read up on it. CMOS inputs present very high impedance to DC, and only require a tiny flow of current to switch states.


text:
What should the cut-off frequency be?
To convert a PWM signal to a DC voltage it must be filtered with a low pass filter. How can you know which cut-off frequency should be used and how do you calculate the values for the resistor and capacitor belonging to that cut-off frequency. I do know that the cut-off frequency needs to be much higher/lower in comparison to the PWM signal, for example a factor 100 lower/higher.

https://arduino.stackexchange.com/tour

program the cut-off based on how fast you need to change set voltage, not by PWM frequency. If you need to adjust in 100ms, aim for that, and you won't be disappointed. Also, you can use a 2nd stage to drastically improve the smoothing at a given resistor size, which can help response times by using a  higher-frequency cut-off but still getting enough smoothing.

Note also this will not work exactly as expected depending on how much current is sink on Uout

The PWM frequency on the Arduino is about 500Hz by default, so you want your -3dB frequency to be below that. How far below? That's subjective. Lower gives a smoother output but a lower response speed. Since you want DC out then you can afford to go very low, unless you need it to respond to changes in the set point quickly.


text:
MIDI keyboard controlled LED strip
My objective is to light a led on a strip corresponding to a keyboard note.
I have Arduino Uno with MIDI in module hooked up to a serial port. Piano is hooked with a standart midi cable, Led Strip is powered using Arduino's 5v (Figured i don't need more because Max 10 leds will be active at a time).
My setup works but not accurately. All is fine when only 1 note at a time is played, but the denser the music becomes (faster or more notes are played simultaniously) more inaccuracies show - more leds don't turn off or on, or the notes I didn't play light up.
At first i used software serial and there were even more mistakes, when i switched to hardware it became better.
Could it be that Arduino UNO is just not powerfull enough and cannot keep up with incoming midi input or is there another problem?
Here is the code:
#include <MIDI.h>
#include <Adafruit_NeoPixel.h>

MIDI_CREATE_DEFAULT_INSTANCE();

#define STRIP_PIN 11
#define STRIP_NUM_PIXELS 88

Adafruit_NeoPixel strip = Adafruit_NeoPixel(STRIP_NUM_PIXELS, STRIP_PIN, NEO_GRB + NEO_KHZ800);

void handleNoteOn(byte channel, byte pitch, byte velocity)
{
  strip.setPixelColor(pitch - 21, strip.Color(50, 50, 50));
  strip.show();
}

void handleNoteOff(byte channel, byte pitch, byte velocity)
{
  strip.setPixelColor(pitch - 21, strip.Color(0, 0, 0));
  strip.show();
}

// -----------------------------------------------------------------------------

void setup()
{
    MIDI.setHandleNoteOn(handleNoteOn);
    MIDI.setHandleNoteOff(handleNoteOff);
    MIDI.begin(MIDI_CHANNEL_OMNI);
    strip.begin();
}

void loop()
{
    MIDI.read();
}

I would collect events until a gap in stream of note events and show them at once

Missing notes or releases could be due to timing but the notifications of notes you didn't play is more worrying. Try removing the neopixel stuff and just recording the notes - does the midi stuff work reliably on its own? (You might have to think of some clever way to get the data out since you're using the serial port.)

Yeah i dont really know how to properly debug. I think the notes that i didnt play are because midi packet was read incorrectly so some other parametres were read as notes somehow. When i tested through SoftwareSerial everything seemed to work fine on the input when i just read midi data.

Also consider the problem is not inside your sketch, but inside your circuit; First try to just print the values, and check if all MIDI on/off messages are received. If you are sure that the circuit (and sketch regarding MIDI input is ok), add the LED strip code again.

The biggest problem is that updating the LEDs is an intensive task.

Hand-crafted assembly is written to get the timing right
Interrupts are disabled while the update is running
88 LEDs take a (relatively) long time to update.

At about 1.2µS per LED plus 50µS for the reset pulse, you're looking at about 155µS that the Arduino can't be doing anything else at all. That includes receiving anything through serial.  And since you update for every note you receive, if there is a second note coming in with 155µS of that one, it will be missed.
You may get better results with the FastLED library instead of the Adafruit Neopixel library, but ideally you want to work with a board that is fast enough to not need to do such tight bit-banging for the protocol, so that interrupts can still be enabled for receiving data.

Thanks for this knowledge! I need it to work perfectly without missing a beat... do you think Arduino DUE will be up for this task?

Only if the LED library you use allows it to work without disabling interrupts. The FastLED library might have a DMA mode that operates completely asynchronously, but I don't know if it works on the Due. Some more research would be needed.


text:
Rfid module on nodemcu
I am trying to connect a mfrc522 module with nodemcu. I have tried all tutorials available in youtube. Everytime it shows firmware version: 0x89 (unknown}.

Can you assume that no one else has tried all the tutorials on youtube, and post your code and how you have it hooked up in your particular situation?

What exactly did you do that resulted in the error to occur. And where does it show "firmware version: 0x89 (unknown}"

well, the "valid" versions of mfrc522 (at least according to the MFRC522 library) are 0x88 for the Fudan Semiconductor FM17522 clone, 0x90 for MFRC522 firmware 0.0, 0x91 for MFRC522 firmware 1.0 and 0x92 for MFRC522 firmware 2.0 - 0x89 is not known in that library, and therefore that library won't deal with it - use the PCD_DumpVersionToSerial to see if your device is supported

Please post an actual question. So what that the firmware version is 89?

My device has a rc522 chip manufactured by nxp. Pcd_dumpverisontoserial shows the version as 0x89. I have done some projects with both nodemcu and arduino. So i am sure about the connections.


text:
Update `char* `
I have a class containing few char* variables:
char* msgTopic     = "myHome/MSGS";
char* groupTopic   = "myHome/All";
char* errorTopic   = "myHome/Err";

but, I wish to have it defined outside the class and not hardcoded (update only prefixTopic outside the class,
char* prefixTopic  = "myHome";
char* msgTopic     = ""; // also tried-->  char* msgTopic = "AAAAAAAAAAA";
char* groupTopic   = "";
char* errorTopic   = "";

and then, down the code to have it defined as:
sprintf(msgTopic  ,"%s/Messages",prefixTopic);
sprintf(groupTopic,"%s/All",prefixTopic);
sprintf(errorTopic,"%s/Errors",prefixTopic);

BUT
both ways ( when defining variables as "", or just filled it up with chars to allocate space) caused topics to be defined with errors ( mostly - one variable contained both topics ).
Appreciated any help
( I don't think context of class is relevant )

Not a duplicate, but the answers to “deprecated conversion from string constant to 'char*'” should provide the answer you are looking for (and more).

First, you have to think about using dynamic or pre-allocated strings. Dynamic memory is not recommended for Arduino, so I will use pre-allocated strings.
In that case you need to think about the maximum length, I will take 32 for now:
#include <stdio.h>

class YourClass
{
  static const int MaxTopicLength = 32;

  char _msgTopic[MaxTopicLength];
  char _groupTopic[MaxTopicLength];
  char _errorTopic[MaxTopicLength];

  void FillStrings(const char* prefixTopic);
};

Than create in your class a function to fill the strings (untested):
void YourClass::FillStrings(const char* prefixTopic)
{
  snprintf(_msgTopic  , MaxTopicLength, "%s/Messages", prefixTopic);
  snprintf(_groupTopic, MaxTopicLength, "%s/All"     , prefixTopic);
  snprintf(_errorTopic, MaxTopicLength, "%s/Errors"  , prefixTopic);
}


text:
Create a library when using PlatformIO
(1) I'm trying to work with libraries in PlatformIO format", for , of a library, located in Arduino's libraries, where code is llocated under \src directry.
(2) Any other library, not it "PlatformIO format" as I call it, has to contain inside libraries/EXMPLE lib a EXMPLE.h, and EXMPLE.cpp file.
(3) Now, when I try to create a "PlatromIO format" library (since I want to move to PlatfromIO)
compilation fails, saying .h file was not found (an error you would get since .h .cpp was not located in their parent directory), as noted in 2 . see library ABCD in  (which contains only library structures).
Appreciate any help
Guy

You're describing "1.5.x" format libraries, not "PlatformIO". This arrangement for a library was created for Arduino IDE version 1.5.0.
The critical part of this library format is the library.properties file which describes the library, and also identifies it as being a library (and which you seem to be lacking). The format of the file is described here.

Well I suspected so, but it have to an url to GitHub ?

@guyd No, but if there is a web page associated with the library it should be included. It doesn't have to be github, that's just an example. I think url= is optional anyway.