text:
Need help with the basics on serial control
I am struggling to get my head around why this just won't work. In my simple mind this simple sketch should do as it's told. But I am obviously missing something fundamental.
If anyone could shed some light on what I am doing wrong that would be very good!
The sketch is just to control a relay by typing on or off into the serial monitor. However although it uploads, all I get is the Serial.println repeating and no action on the physical relay.
I can manage to control things over serial by using the switch, case statements but I wanted to try it using full words rather than single chars and also using IF statements etc.
Thanks in advance!
EDIT
I just changed the string inputs to a char input and serial.readstring to just serial.read and it works with just entering a 1 or a 2 for example. So to re-ask my question - how can I get it to respond the same but using words? Thanks!
int relay=8;
String serialInput;

void setup() {
  Serial.begin(9600);
  pinMode(relay, OUTPUT);
}

void loop() {
  Serial.println("To toggle relay enter on or off");
  while (Serial.available()==0) {}
  serialInput = Serial.readString();
  if(serialInput=="on") {
    digitalWrite(relay, HIGH);
  }
  if(serialInput=="off") {
    digitalWrite(relay, LOW);
  }
}

This should give you some clues to help fill in your missing knowledge: https://hackingmajenkoblog.wordpress.com/2016/02/01/reading-serial-on-the-arduino/

Yes thank you! this certainly helps, how I thought serial comm's works and how it actually works are different things. This helped a lot! Thanks.

You are assuming that Serial.readString() will magically know how long a string you meant to send, and wait until it's all there.  It doesn't guarantee that.
If your PC uses Linux or Mac, you can use Serial.readStringUntil('\n'), which will read until a line end, and send on<ENTER> as your command.
If you use Windows, the line endings are \r\n so it's a bit more awkward.  Build up your string piece by piece, perhaps
int relay=8;
String serialInput;

void setup() {
  Serial.begin(9600);
  pinMode(relay, OUTPUT);
}

void loop() {
  if (Serial.available()) {
    char c = Serial.read();   // get one byte from serial buffer
    if ('\r'==c || '\n'==c) {
      // End of line - process the string
      if(serialInput=="on") {
        digitalWrite(relay, HIGH);
      } else if (serialInput=="off") {
        digitalWrite(relay, LOW);
      }
      serialInput = "";
    } else {
      serialInput += c;     // add it to readString
    }
  }
}

Brief description of how it works:
The string SerialInput starts empty.  We do the following repeatedly:

If there is a character available on the serial port, read it.
If it is not an end-of-line character, add it to the end of our string
If it IS an end-of-line character, we know we've got to the end of the line, so...

check whether it matches one of our "target" strings, and act on it if so
clear it back to an empty string

Many thanks for you reply! Not fully understanding your code, but i'll research it some more. I tried to run you code, but it won't compile. I think 1 error was with a missing ' after ('\r'==c  so I added that but it still wont run. the error mentions serialInput not declared in this scope. I tried entering that also as a variable in the loop but still didn't work. any ideas? Thanks again for your time!

Very welcome. Whoops, typos fixed, and also added the first part of the code (which is an exact copy of yours). Also added an explanation of the code, which I hope helps.

Mark, thank you again!!! I really appreciate you taking your time here to help me understand. And I think it's starting to click! Your code works a treat now. Lastly if you don't mind to check that it has clicked with me... the C variable is just a random letter? it could be anything I liked? and the \r is simply waiting until i press enter\return on the serial monitor before checking then against the arguments set. And the \n is that like a double check for a return or specifically a newline? So it might work without that if you so desired? Honestly thanks again for your help!!

Glad it's helpful! Yes, char c could have been char theNewCharacter or anything you like. \r is a carriage return, \n is a new line. Windows puts both on the end of a line, Unix-like OSs put only \n. Rather than worrying about whether we'll get one or both, we just say "whenever we get a character which is part of a line-end, we know we have the whole line, so process it". On Windows you'll get both so you'll process the "real" line, then immediately try to process an empty string, which won't match "on" or "off", so nothing will happen - no harm done.

Fantastic explanation Mark! I GET IT!!! WOOO!!! I don't suppose you do private paid tutoring on Skype etc? I have a lots questions I have struggled with in programming for years and can never seem to get passed the basics. My end goal is to have DIY IOT capability with anything in the house I want, with a nice custom web interface to control or view these things. 3D printed parts and arduino's hooked into everything! But when I struggle so much with the basics it does seem like that goal is unreachable at times. Thanks again!


text:
How can I deal with rapid fluctuation of Anemometer readings?
In my little weather station I collect temperature, humidity, MQ-2 smoke sensor, and wind speed readings for display on a 20x4 LCD display, every 500 ms.
The Anemometer readings jump up and down by quite a bit.
Initialization of variables before Setup is like so:
// Wind Speed Anemometer
const int sensorPin = A3;
int sensorValue = 0;
float sensorVoltage = 0;
float windSpeed = 0;
float voltageConversionConstant = 0.004887586;  // (5/1024)
float voltageMin = .33;   // 0.4 in the documentation
float windSpeedMin = 0;
float voltageMax = 1.5;   // 2.0 in the documentation
float windSpeedMax = 32;

// 20 x 4  LCD Display
#include <LiquidCrystal_I2C.h>
// set the LCD address to 0x3F for a 20 chars 4 line display\/ Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

Then in Setup I initialize the LCD and flash the backlight.
lcd.begin(20,4);
lcd.clear();
for(int i = 0; i< 3; i++) {
  lcd.backlight();
  delay(250);
  lcd.noBacklight();
  delay(250);
  }
lcd.backlight(); // finish with backlight on

In Loop, I paint the initial screen then take readings and display them
void loop() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Weather");

  ...etc... to display time and show temp and humidity

  // Wind Speed
  sensorValue = analogRead(sensorPin);
  sensorVoltage = sensorValue * voltageConversionConstant;
  if (sensorVoltage <= voltageMin) windSpeed = 0;
  else windSpeed = ((sensorVoltage-voltageMin)*windSpeedMax /(voltageMax-voltageMin)*2.23694);
  lcd.setCursor(0,3);
  lcd.print(windSpeed);
  lcd.print(" MPH  ");

  ...etc... to display smoke detection...

  delay (500);
  }  // end loop

So the question is:  How can I slow down the Wind Speed fluctuations?  It jumps up and down quite widely.

A:  Use a running average
In the initialization I include an array to hold 10 values
// Wind Speed Anemometer
const int sensorPin = A3;
int sensorValue = 0;
float sensorVoltage = 0;
float windSpeed = 0;
float voltageConversionConstant = 0.004887586;  // (5/1024)
float voltageMin = .33;   // 0.4 in the documentation
float windSpeedMin = 0;
float voltageMax = 1.5;   // 2.0 in the documentation
float windSpeedMax = 32;

float ws[10] = { };      // (initializes all to zero)
int wsIndex = 0;
float wsTot = 0.0;
float wsDisplay = 0.0;

Then in the Loop I fill the array with values and display the average of the 10 readings stored there
  // Wind Speed
  sensorValue = analogRead(sensorPin);
  sensorVoltage = sensorValue * voltageConversionConstant;
  if (sensorVoltage <= voltageMin) windSpeed = 0;
  else windSpeed = ((sensorVoltage-voltageMin)*windSpeedMax /(voltageMax-voltageMin)*2.23694);

  if (wsIndex<9) {
    ws[wsIndex] = windSpeed;
    wsIndex++;
    }
  else {
    wsTot = 0.0;
    for (int i=0;i<=9;i++) wsTot = wsTot + ws[i];
    wsDisplay = wsTot / 10.0;
    lcd.setCursor(0,3);
    lcd.print(wsDisplay);
    lcd.print(" MPH  ");
    wsIndex = 0;
    ws[wsIndex] = windSpeed;
    }

Depending on the nature of the fluctuations, a median filter may be way more efficient than a running average. 2) An exponentially weighted running average is simpler and less resource intensive than the “flat” average you are doing.

Interesting comment.  Median is interesting but takes more code.  In your #2 part I am not sure how you would decide to weight it.  And again, it would take more code.  I like how my averaging algorithm is implemented in two lines of code.  It is easy to read.  My favorite code is of the self-documenting type.

Median is indeed more complex, but it's worth the trouble if you have “spiky” noise. It is no better than averaging if your noise is white and Gaussian. The exponentially weighted running average takes less code and less memory: output += constant * (input - output). It's the standard low-pass filter for when you want simplicity and efficiency. You choose the constant as a function of how much smoothing you want. constant = 1.0/N; is roughly equivalent to an N point running average.

Ah.  Thank you for explaining that.  I see your point.  I will remember this.  My original readouts were wildly variable and I would say they are white and Gaussian.        btw, I have doubled the length of my array to 20 and it is very nice to see a good stable readout with much less variability.

How about this one, it supposed to press fluctuations of your sensors reading
void loop(){
..
...
....
last_reading = sensorValue2; //

sensorValue = analogRead(sensorPin);
sensorVoltage = sensorValue * voltageConversionConstant;
if (sensorVoltage <= voltageMin) windSpeed = 0;
else windSpeed = ((sensorVoltage-voltageMin)*windSpeedMax /(voltageMax-voltageMin)*2.23694);

sensorValue2 = (sensorValue+last_reading)/2;
....
...
..
}

That certainly is less code - very readable.  It would be like my solution but as if I had an array of 2 entries.  If this works for you, then that's great.

you can also combine it with averaging method, but it will lessen the sensitivity. Not advised if used in quickly changing environment

source: Stack Exchange

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

sort: votes


text:
Need to set an output pin without it going LOW during initalization
For a control system I am using a relay module that controls a larger relay for high-current electrical stuff, as part of a battery protection circuit for my solar plant.  This module switches 120 VAC for the larger one.  The larger one is set up to latch the power off until a button is pressed manually.
I have several Adafruit relays, (single, dual, quad) and they all seem to be active-LOW.  I am using one of them for this project.
My problem is that I can't seem to prevent my Arduino Nano code from briefly setting the output pin LOW in setup, setting in motion the cascade involving latching the power off.
If at all possible with this hardware, I would like to prevent the need to manually reset the latch when uploading code changes.
Here is how I am initializing that pin in my setup code:
pinMode(12,OUTPUT); digitalWrite(12,HIGH);

All in one line.  The LOW pulse is just long enough to trigger the other relay.
I know I can probably find parts like an inverter chip or maybe a different relay, but really want this working yesterday.
So my question is:  Is there any way to prevent it from pulling it LOW during initialization?  Or, is there a different approach I should take in relation to this relay output?
Thanks in advance

All in one line or not does not matter to C.  It will execute the first expression (before the ";") first and the second expression second. You might try swapping the expressions and testing the results.

Most embedded processor initialize to inputs.  You did not specify which Arduino you were using.  Different Arduinos use different processors.  Assuming this default behavior, you might add a pull up resistor to prevent the output of the processor (input to the relay driver) from going low while it is in the high impedance input state.  This will add to the current drain.  But only by a small amount.  Let me know if either of these ideas work and I'll copy the text to an answer.

I edited the post to say it is a Nano.  Hey, @st2000, that was genius.  I first set it high, then set it as output, then just for good measure set it high again and voila, no low pulse!  If you write that up as an answer I will upvote and accept for sure.  Thank you very much.  I can't help but think your second answer might work also, but don't have time to test it at the moment.  Thanks again.

I think this sets a record for such a short time between asking and getting the correct answer.  I'm glad you caught this one.

Happy coincidence, just happen to be looking through the questions.

What if you write HIGH and then set it to output? And make sure to have a pull-up resistor.

fwiw, a capacitor can slow down relay transitions, fit to size...

Arduino sketches are actually (somewhat constrained) C programs.  As such, what is true for C is usually true for sketches.  In C, a segment of code usually ends with a ";".  It matters not if there are two (or more) of these on a single line.  The computer will execute the segment before the first ";" first and the segment after the first ";" second.
In this case you are setting a register inside the Atmel processor on the Nano to the "out" direction.  So it will force the associated pin to what ever the data in already set up in that pin's data register.  Then you are setting that pin's data register to high or 1.
Instead, try setting the data register to 1 before setting the direction register to "out".  Do this by switching the order of the code segments.
In case this does not work.  Or in case you find the relays acting randomly on power up, consider the relay driver inputs to be high impedance and susceptible to any noise prior to the Nano taking control of the relay driver control pins.  In such a case, consider adding pull up resistors small enough to ensure the inputs of the relay drivers are held at a known voltage but high enough such that the Atmel processor in the Nano can easily over power the pull up resistor when necessary.

The first option worked perfectly.  I first set it to HIGH then set it to output then set it to HIGH again for good measure.   Voila, no LOW pulse at all.  Totally solved the problem.  Thank you very much, @st2000 !

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


text:
How can i provide enough power on an UNO to use the HC-12 wireless module?
Scenario:  The Uno is being powered by USB for programming, and the HC-12 wireless communications module is wired correctly.  But it will not work.
In reading through the web literature, it is mentioned that to use the HC-12 in the high-power (100 mW) mode requires a power supply in excess of what the laptop's USB port will provide.
I am finding nothing on Stackexchange that addresses this issue.
So the question is, how do I get the power to run the Uno with the HC-12?  I need to be able to periodically update the programming and test it while that auxiliary power is applied, and need to know it is safe to do so.

There two options I have found that work well.
First is a simple wall-wart that provides 12 Volts to a barrel connector, like for a CCTV camera.
Or, if I want to run the Uno from a separate higher-amperage USB charging port I have found that there are "USB A Male to CCTV male" cables that work.
Doing the latter means the Uno is running at 5V instead of utilizing the on-board regulator to drop a higher-voltage input, which only matters if your circuit expects to find more than 5 Volts on the Vin pin (although that is not supposed to be an output pin, of course).
Through thorough experimentation I've proven that both methods work.
The best part is that the Uno can easily tolerate having both CCTV-style power and also being plugged into the laptop for programming and testing (like using the serial monitor).
Lesson learned:  The HC-12 simply will not work without auxiliary power, and it is safe to provide such power while also plugging the serial port into a laptop.


text:
Arduino Nano randomly resetting
I am currently struggling with an intermittent problem with an Arduino project.
Background
I am using a LabVIEW program to control a few pieces of hardware. One of them is a NEMA 17 stepper motor that drives a rack and pinion actuator. I am using a genuine Arduino Nano with an (official) EasyDriver motor driver to drive the NEMA 17. The Arduino listens for the state of a DI pin, and if it is pulled high it moves out the rack until a U-shaped sensor sends a high input signal at the outermost position, it then listens for that DI pin to be pulled low and retracts the rack until a proximity sensor sends a high input signal.
The Problem
I noticed that my actuator was either becoming unresponsive to the input signals from the LabVIEW DAQ, or that it was getting stuck mid actuation (motor has plenty of torque for this application). After changing up the code to print updates to the serial port, I realized that after a few cycles the Arduino resets and re-enters the Setup() function.
I changed out the Nano and it made no difference. I am using a timeout feature for the first time and I was wondering if the memory usage of this feature could be causing problems - however I commented out this part of the code and the Arduino still reset. The code is below - would really love to hear any thoughts on whether this is likely to be a hardware or software issue. I am powering the Arduino with a 7V line from a Power Supply into the Vin port. The prox sensor operates at 24V but I divide the output signal's voltage so that the input voltage is ~4.8V (I have measured this). I am using the same U-shaped sensor with a few other Arduinos and I am not seeing this issue. I have powered Arduinos with the same 7V line in the past and have also never seen them reset like this.
Let me know what you think, thank you!
 const int uSensor = 12;
const int proxSensor = 10;

const int labViewHomePin = 9;
const int labViewInputPin = 8;

const int labViewOutFeedback = 7;
const int labViewInFeedback = 6;

const int StepperStepPin = 2;
const int StepperDirectionPin = 3;
const int ENPin = 13;

enum {IdleState, ForwardState, BackwardState} State;            // this switch case is used to call the correct function that turns the motor in the desired direction

boolean rampDone = false;
boolean pusherIn = false;
boolean pusherOut = false;
boolean homingDone = false;

boolean updateGiven = false;

int motorSpeed = 300;
int rampStartSpeed = 500;
int rampStepCountNo = 800;

boolean boolInitialMove = true;
unsigned long timeInitialMove = 6000;
unsigned long startTime;
unsigned long endTime;

void setup() {
  Serial.begin(9600);
  pinMode(uSensor, INPUT);
  pinMode(proxSensor, INPUT);
  pinMode(labViewHomePin, INPUT);                                  // initialising input pins
  pinMode(labViewInputPin, INPUT);                                  // initialising input pins

  pinMode(StepperDirectionPin, OUTPUT);                             //Direction
  pinMode(StepperStepPin, OUTPUT);                                  // Step
  pinMode(ENPin, OUTPUT);                                           // Enable

  Serial.println();
  Serial.println("Setup phase called");
  Serial.println();

  pinMode(labViewInFeedback, OUTPUT);
  pinMode(labViewOutFeedback, OUTPUT);

  State = IdleState;
  digitalWrite(ENPin,HIGH);                                         // Disable the drive by default

  homingDone = false;
}

void loop() {
  if ((digitalRead(labViewHomePin) == HIGH) && (homingDone == false)) {
    Serial.println("Homing Pin High Detected");
    homingRoutine();
    homingDone = true;
    Serial.print("Homing Done = ");
    Serial.println(homingDone);
    State = IdleState;

    if(digitalRead(proxSensor) == HIGH) {
      digitalWrite(labViewInFeedback,HIGH);
      digitalWrite(labViewOutFeedback,LOW);
    }
    else if(digitalRead(uSensor) == HIGH)  {
      digitalWrite(labViewInFeedback,LOW);
      digitalWrite(labViewOutFeedback,HIGH);
    }
    else {
      digitalWrite(labViewInFeedback,LOW);
      digitalWrite(labViewOutFeedback,LOW);
    }

  }

  switch (State) {
    case IdleState:
    boolInitialMove = true;
    digitalWrite(ENPin,HIGH);

      if(updateGiven == false) {
        Serial.println("I am in IdleState");
        Serial.print("Pusher Out Boolean = ");
        Serial.println(pusherOut);
        Serial.print("Pusher In Boolean = ");
        Serial.println(pusherIn);
        Serial.print("Prox Sensor status: ");
        Serial.println(digitalRead(proxSensor));
        Serial.print("U-Sensor status: ");
        Serial.println(digitalRead(uSensor));
        updateGiven = true;
      }

      if ((digitalRead(labViewInputPin) == HIGH) && (pusherOut == false) && (homingDone == true)) {
        digitalWrite(ENPin,LOW);                                    // Enable drive
        State = ForwardState;
        Serial.println("LabVIEW High detected. Case switched to ForwardState");
        Serial.println("");
        updateGiven = false;
      }
      else if ((digitalRead(labViewInputPin) == LOW) && (pusherIn == false) && (homingDone == true)) {
        digitalWrite(ENPin,LOW);                                    // Enable drive
        State = BackwardState;
        Serial.println("LabVIEW Low detected. Case switched to BackwardState");
        Serial.println("");
        updateGiven = false;
      }
      else {
        //do nothing
      }

      if(digitalRead(uSensor) == HIGH) {
        pusherOut = true;
        pusherIn = false;
      }
      else if(digitalRead(proxSensor) == HIGH) {
        pusherOut = false;
        pusherIn = true;
      }
      else {
        //do nothing
      }

      break;

    case ForwardState:

    if(updateGiven == false) {
        Serial.println("I am in ForwardState");
        Serial.print("LabVIEW Actuate Pin = ");
        Serial.println(digitalRead(labViewHomePin));
        updateGiven = true;
      }

    if(boolInitialMove == true) {
        digitalWrite(StepperDirectionPin, LOW);
        rampUpCosineWave(rampStartSpeed, rampStepCountNo, motorSpeed);
        startTime = millis();
        endTime = startTime;
        boolInitialMove = false;
      }

      endTime = millis();
      rotateForward(motorSpeed);                                            // this calls the function ForwardState which starts pushing out the pusher

      if (digitalRead(uSensor) == HIGH) {
        digitalWrite(labViewInFeedback,LOW);
        digitalWrite(labViewOutFeedback,HIGH);
        Serial.println("U-Sensor High detected. Case switched to Idlestate");
        Serial.println("");
        updateGiven = false;

        pusherOut = true;
        pusherIn = false;
        State = IdleState;
      }
      else if((endTime-startTime) > timeInitialMove) {
        digitalWrite(ENPin,HIGH);
        digitalWrite(StepperStepPin, LOW);
        digitalWrite(StepperDirectionPin, LOW);
        digitalWrite(labViewOutFeedback,HIGH);
        digitalWrite(labViewInFeedback,HIGH);

        Serial.println("");
        Serial.println("**TIMEOUT DETECTED**");
        Serial.println("");

        State = IdleState;
      }
      break;

    case BackwardState:

    if(updateGiven == false) {
        Serial.println("I am in BackwardState");
        Serial.print("LabVIEW Actuate Pin = ");
        Serial.println(digitalRead(labViewHomePin));
        updateGiven = true;
      }

    if(boolInitialMove == true) {
        digitalWrite(StepperDirectionPin, HIGH);
        rampUpCosineWave(rampStartSpeed, rampStepCountNo, motorSpeed);
        startTime = millis();
        endTime = startTime;
        boolInitialMove = false;
      }

      endTime = millis();
      rotateBackward(motorSpeed);

      if (digitalRead(proxSensor) == HIGH) {
        digitalWrite(labViewInFeedback,HIGH);
        digitalWrite(labViewOutFeedback,LOW);                                // Disable drive
        Serial.println("Prox Sensor High detected. Case switched to Idlestate");
        Serial.println("");
        updateGiven = false;

        pusherOut = false;
        pusherIn = true;
        State = IdleState;
      }
      else if((endTime-startTime) > timeInitialMove) {
        digitalWrite(ENPin,HIGH);
        digitalWrite(StepperStepPin, LOW);
        digitalWrite(StepperDirectionPin, LOW);
        digitalWrite(labViewOutFeedback,HIGH);
        digitalWrite(labViewInFeedback,HIGH);

        Serial.println("");
        Serial.println("**TIMEOUT DETECTED**");
        Serial.println("");

        State = IdleState;
      }
      break;

  } // end switch
}

void rotateForward(int mtrSpeed) {
  digitalWrite(StepperDirectionPin, LOW);
  digitalWrite(StepperStepPin, HIGH);
  delayMicroseconds(mtrSpeed);
  digitalWrite(StepperStepPin, LOW);
}

void rotateBackward(int mtrSpeed) {
  digitalWrite(StepperDirectionPin, HIGH);
  digitalWrite(StepperStepPin, LOW);
  delayMicroseconds(mtrSpeed);
  digitalWrite(StepperStepPin, HIGH);
}

void homingRoutine() {
  digitalWrite(ENPin,LOW);
  Serial.println("Homing Routine called");
  bool firstCycle = false;
  bool secondCycle = false;
  bool thirdCycle = false;
  bool fourthCycle = false;

  while(digitalRead(uSensor) != HIGH) {
    rotateForward(rampStartSpeed);
  }
  delay(500);
  Serial.println("First home movement completed");
  while(digitalRead(proxSensor) != HIGH) {
    rotateBackward(rampStartSpeed);
  }
  delay(500);
  Serial.println("Second home movement completed");
  while(digitalRead(uSensor) != HIGH) {
    rotateForward(rampStartSpeed);
  }
  delay(500);
  Serial.println("Third home movement completed");
  while(digitalRead(proxSensor) != HIGH) {
    rotateBackward(rampStartSpeed);
  }

  delay(500);

  homingDone = true;
  pusherIn = true;
  pusherOut = false;

}

  int rampUpCosineWave(int startSpeed, int rampUpSteps, int maximumSpeed) {
  int countedSteps = 0;
  float amp = ((startSpeed-maximumSpeed)/2);
  for(int currentSpeed = startSpeed; currentSpeed > maximumSpeed; currentSpeed = (int)((amp + maximumSpeed)+(amp*(cos((PI/rampUpSteps)*countedSteps))))) {
    digitalWrite(StepperStepPin, LOW);
    delayMicroseconds(currentSpeed);
    digitalWrite(StepperStepPin, HIGH);
    countedSteps++;
  }

  return countedSteps;
}

Can you monitor the Vin and +5V lines with a scope while the stepper is running? Electric motors can make power supplies noisy and unstable.

Your meter may also have a MIN mode that tracks the minimum voltage seen since started.  It's not as good as a using a scope as Edgar suggests, but sometimes it can help.

Thank you all for your contributions. I managed to find the issue and solve the intermittent reset. I was expecting to find a hardware problem as the root cause, but just in case it was software related I wanted to check as well. It turned out to be hardware
Gil is certainly questioning the correct piece of hardware. It was indeed the wiring of the Prox sensor. I had connected both the data and power common rails to facilitate the prox sensor but on inspection, I decided to keep these separate and voltage divide the prox sensor away from the rails and instead bring a direct 4.8V line into the Arduino. Whatever noise the stepper motor was creating was unable to impact the data lines of the Arduino, and I haven't seen the issue return since.
Really appreciate the help everyone. I didn't scope the power lines to the Arduino, as the issue continued regardless of me powering the arduino through only the COM port of a PC, a combo of both the COM port and 7V to the Vin line (presume the Arduino draws from the 7V line but I am unsure) and just the 7V line. Appears to have been noise disrupting the data common rail of the Arduino.

I expect you have a lot going on with your design.  Dividing down is never a good voltage (power) supply regardless of what you measure unless you are using a good scope to measure and it is well bypassed. Consider a Buck regulator from one of the China suppliers they are just a few bucks and will stabilize your circuit. If the prox sensor draws just a few mills consider powering it with the Arduino 5 volts. Motors like other inductive devices generate lots of transinents that are both conducted and radiated, something like that may be getting into your system possibly via the prox sensor. This should get you started.

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


text:
Any way to use DMA to transfer data to SD Card in ESP8266
I'm using ESP8266 at speed of 160 MHz to record ADC results into SD card, I need to do this at rate of 8 KHz. Means that i should save it on the SD Card or i'll run out of memory before 4 Sec passes.
I used timer1 to trigger sampling, but my problem is that surprisingly ESP8266 can not do this fast enough and the maximum sampling rate i get is about 7 KHz. I also tried to write data in ESP8266 Flash using littleFS in hope of acceleration but there was no luck. Here is my code:
#include <SPI.h>
#include <SD.h>

File dataFile;

int flag = 0;
int count = 0, level = 0, se_count = 0;

void inline analogReader() // Sampling and Recording processed which is done sequentially :(
{
  uint16_t dataByte = (uint16_t) analogRead(A0);
  dataFile.write((uint8_t*) &adcBuf, 2);

}

void ICACHE_RAM_ATTR onTimerISR() { // Timer sets the flag every 0.125 MS
  flag = 1;
}

void setup() {
  pinMode(A0, INPUT);
  pinMode(D0, OUTPUT);

  Serial.begin(115200);

  if (!SD.begin(D0)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

  File root = SD.open("/");

  if (SD.exists("real_test.bin"))
  {
    SD.remove("real_test.bin");
  }

  dataFile = SD.open("real_test.bin", FILE_WRITE);

  if (dataFile) {
    Serial.println("File created!");
  }
  else
  {
    Serial.println("Failed to create file!");
    return;
  }

  // Setting the timer so that timer interrupt fires every 0.125 MS
  timer1_attachInterrupt(onTimerISR);
  timer1_enable(TIM_DIV1/*from 80 Mhz*/, TIM_EDGE/*TIM_LEVEL*/, TIM_LOOP/*TIM_SINGLE*/);
  timer1_write(10000); /* ( 80 / 1 ) * 125 */
}

void loop() {
  if (flag) // To check whether its time to sampling or not, because of the low speed of the process
  {         // The flag is set again before one iteration ends.
    flag = 0;

    if (se_count < 10)
      analogReader();

    count++;
    if (count == 8000) // When 8000 sample & write process done notify using serial monitor. (it is
                          always more that 1 Sec. for example 1.3 Sec.)
    {
      count = 0;
      level = !level;
      Serial.println(level);

      se_count++;
      if (se_count == 10) // When we done 8000 * 10 sample & write we close the file. it supposed to
                          // be done in almost 10 sec. but it takes more time in practice. for
                          // example 13 Sec.
      {
        dataFile.close();
        Serial.println("Write ended");
      }
    }

  }
}

I even used a faster method system_adc_read_fast(buf, num, clk_div) that is available in ESP-SDK, So i'm desperately seeking for one or two of approaches bellow if possible:

To use a non-blocking approach: If there is any possibility to hand SD writing to DMA so that i only fill the ADC buffer for DMA, or an interrupt for ADC complete so that i write to SD and when interrupt fired put the result in the buffer and return back to SD writing.
Yet faster approach for both ADC sampling and writing: Can i increase the SD write speed of SD library? for example by configuring SPI for maximum speed rate.

I also tried SDFat library but it does not recognize my SD Card. The whole process is odd to me that even by using a 160 MHz CPU and hardware i can not record ADC data at rate of 8000 Sample/S. I have TIME limitation so please help me.
Any suggestion is appreciated. Thanks in advance.

Please help me guys, There is no suggestion? How possible!

It's not clear to me where your performance bottleneck is happening.  In your code you have an interrupt set a flag but your loop() function takes its sweet time doing things, especially things like writing serial that will likely take longer than the interval to the next interrupt.  I suspect the problem is the overhead of an SD card write operation.  Perhaps you might batch them up so that you write more data to the SD less often.

Thanks. I put the code in loop() instead of interrupt routine itself because it takes longer time than 125 MS or 1/8000 Second to be done. So before finishing interrupt routine the interrupt line reasserted. So CPU never returned to loop() and that watch dog timeout happened. even though i tried to feed the dog in the interrupt routine :) . Ok i agree with you. May be batching can help improving the performance. I'm trying it. I'll report the result.

One problem with your loop() architecture is that if you don't complete the loop before the next interrupt happens, you will miss a reading.  You might redesign this so that the interrupt reads the ADC and stores the result in a buffer.  Then you loop can watch that buffer until it get full, grab that data and start writing to the SD card.  In that case you have N interrupts to complete the task.  N is the number of readings your buffer can hold.

Putting the code in loop() is good. Your line int flag = 0; should be volatile int flag = 0;. This lets the compiler know that flag may change unexpectedly, so it will know to reload it from memory more often. Otherwise flag might change and the loop code might miss it because the value is cached in a register.

Hey guys have you tried to read ADC and put the result into buffer in the timer interrupt service routine? I can not do this and ESP8266 keeps resetting at the timer rate of 8000 Hz which i configured in the code i'v posted, I actually faced this problem before but i thought that it is because i am doing both sampling and writing to SD and it takes long time so watch dog keeps resetting MCU. but now i just tried to sample ADC and put result into RAM. I think this is not taking that long time.

So, sorry for late response, i figured it out. Because it took lots of time for me and it might be a prevalent issue, i think it worth to contribute my experience for further similar issues.
As mentioned buffering can do the job, here are some constraints that should be satisfied to have right buffering mechanism;

Writing to SD card SHOULD NOT be handled in the Timer ISR, but store ADC data into a buffer, aka int[] which is normally kept in SRAM (Your Timer ISR should be as short and fast as needed)

Handle reading from buffer to SD outside of Timer ISR in, for example in loop().

priority of ISR should be more than loop(), and it is so by default.

It's a good practice to divide your buffer into chunk of 512 or 1024. for example 2 chunks of 1024 Bytes making your buffer. you check for "filled" flag to be set in the loop() and when this happens call SDFile.write(..) for corresponding filled chunk and then reset the flag.

By conforming to these constraints you enjoy these benefits:

you can be sure that no ADC on time sampling missed because of sluggish SD write process.

by buffering and pilling data and then storing, you have chance to avoid byte wise write to SD, which is  really inefficient. and instead handle write in chunks of 512 or 1024 bytes. which is equal to sector size of SDs. so you have faster SD write process too.

This way you can easily handle voice recording up to 16 ksps even without using DMA.
I have added the code to my github, in this repository; https://github.com/A-R-S-D/WAVRecorder

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


text:
Ways to detect if a ball has reached the wall?
I'm building a kind of pin ball machine, and I need to detect when the ball has hit the wall with the sensor attached.
The ball will hit the wall with a small impact, not large enough to push a button probably. What sensor would be the best to use in this case?
I thought about ultrasonic but I'm not a fan of the constant chirping. Can a light sensor be used here? Eg if there's 10% light left, we assume the ball has reached the wall.

You could use a light barrier (using a small laser diode), which is aligned along the wall. The ball will get into the light ray and will disrupt the light barriers signal. Or you could attach a vibration/sound sensor to the wall to detect the impact.

If you want to write an answer, please write only one solution in one answer. If you have more ways to solve this, please write multiple answers so we can vote for the solutions separately.

The ball will hit the wall with a small impact...

Consider using the well proven pinball bumper design omitting the hammer feature:

In many pinball machines a "rubber ring" is stretched in front of one or more "leaf switches".  When the ball hits the "rubber ring" one or more of the "leaf switches" closes (or opens depending on if the "leaf switch" is N.O. or N.C.).  There are many example for connecting switches to an Arduino.


text:
How to implement brown out detector arduino ESP32?
We are using ESP32 with arduino sdk for developing our application. In our application we need to implement BOD to detect with specific voltage level.
Basically we want to set specific voltage level and when device goes to power off it will detect and trigger interrupt. How I can set interrupt for brown out detect?
we have only this code:
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"

void setup() {
  Serial.begin(115200);
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 1); //enable brownout detector
}

void loop() {
  Serial.println("Start BOD");
  delay(1000);
}

You need to explain a bit better what you're trying to do. Do you want to execute some code when the power fails? Without additional hardware, that could be difficult, since when the power is off, the board is off, too.

The ESP32's on-board BOD is mainly intended to inhibit operations that might cause corruption if they happened with too low a voltage.  There is a very unpredictable amount of time for the code in the ESP32 to do anything but effectively halt.
If that's what you want, then you have enabled it in your code above.
If you want to detect a power outage, for example, and log something, then you need two things:

A reliable detector that the power has failed.
A battery or capacitor-based circuit that will continue the ESP32's power for long enough for you to do what you need to do.

So when "1" happens you set a GPIO pin on the ESP32 which triggers your interrupt and you do what you need to do while the power remains stable.

Are you talking mains power or some other source of power (AC or DC)? Is the ESP powered from that source or another source? How much time will be left from when the power browns out until you lose control? Do you plan on using the A/D or an external comparator?


text:
How to re-solder the resistor in order to reprogram the Atmega8U2
As I see here I need to reprogram the ATMEGA8u2: https://www.arduino.cc/en/Hacking/DFUProgramming8U2 I need to solder a 10k resistor into a specific place.
In a previous attempt I did that and resulted the following marks:

So How I can resolder the resistor in order to reprogram the atmega8u2?

Ouch. Looks like your iron was too hot and you lifted one of the pads.  Recoverable if you are careful.

Have you tried without the resistor? The guide seems to suggest that that resistor is only needed on the rev.1 version of the UNO.

you have to carefully scrape away the solder mask before soldering components. ... the solder mask is the blue and white "paint". ... it is covering the pads. ... scrape a small area on the corner of the board as a test.

Looks like you ripped a pad off. To prevent that in the future, try using more flux and dropping the temp (Max around 320*C/610*F). The iron shouldn't be in contact with the board for more than about 3 seconds. No force should be necessary to remove components.
Not to worry though. Common beginner's mistake and not too hard to fix.
To prep this for repair:

Gently clean the area up with 91% isopropyl alcohol and cotton swabs.
Carefully scrape away the solder mask (blue paint) on what's left of the copper trace all the way back to the via (little hole). Try to remove all the solder mask from the via. Straighten and flatten the pulled up trace.
Clean, flux, and tin (apply as thin layer of solder) to the trace and remaining pad. Filling in the via is OK as it will give better surface area to attach the repair.
Flux and solder the resistor to the remaining pad to keep it in place and properly aligned for the repair.

To repair the damage:

We need to bridge the gap created by the damaged pad. A globby solder bridge may work, but wire is much better.
Find a piece of thin gauge solid core wire (30-22AWG. Some 24AWG from an ethernet cable would do fine).
Orient the wire so that it's directly over the remaining trace and also making contact with that end of the resistor.
You can trim it to size now or after soldering. It may be easier to keep in place if you trim it after soldering as long as you have some fine flush cut pliers. Either way, leave enough that it covers the entire cleaned and tinned portion of the trace.
Flux and solder the wire to both the resistor and trace. This will complete the circuit.
Clean again with alcohol. Let dry. Test the board.

Give this Adafruit article a read. I've got extensive professional soldering training and endorse it fully as the best beginners soldering guide I've found.

Does 70% Alcohol do the job?

@DimitriosDesyllas 70% Alcohol means 30% water. It will clean and remove flux, but if any gets under a component it will take much longer to dry and you'll have conductive corrosive flammable liquid risking your circuit. I definitely would not recommend it. 91% Isopropyl is readily available and cheap at any drug store right next to the 70%.

I woinder If I can use another arduino to program the AtMegaU8 without the need for much solder.

@DimitriosDesyllas You can use another Arduino to program the AtMegaU8. You will need to connect directly to the ICSP header closer to the USB port and "AREF" (if your board version has one). Not completely sure how critical that resistor is going to be though.

That pad connects to the same place as the circuit used for resetting the ATMega328P chip - that is, pin D7 on the ATMega8U2.
It just pulls the pin PD7 down to ground with more "force" than the internal pullup of the pin itself.
You can attach that resistor to anywhere along that line, and probably the most convenient place would be to the ATMega16U2 side of capacitor C5.
That capacitor has one end linked to the RESET pin on the main Arduino header, so you can connect a DMM in continuity test to that pin and "buzz out" each capacitor until you find the one point where it beeps (I think it's one that's right next to "Reset EN").
Carefully solder your resistor to the opposite side of the capacitor to the side that beeps (the side nearest the ATMega8U2 chip, probably), and connect the other end of the resistor to GND on one of the main headers.
By the way - get yourself a flux pen and apply flux to where you are soldering before you start soldering. It should help you avoid these kind of problems in the future. Also get a proper temperature controlled soldering iron (I use 350C for mine most of the time) and some solder wick to help recover from solder messes.  All part of the standard EE's toolkit.


text:
I2C connection with MT9D111 camera module, strange results after writing registers via i2C
I am currently working on a camera platform based on the MT9D111 module from Micron. The first thing to do is to write the configuration to the numerous registers of the chip which is done via an i2C connection.
I adapted the code from here for testing this with an Arduino Uno. 3.3V supply and 8MHz clock are also provided by the Arduino.
Everything seems to work fine, but there are some odds which I don't know the reason for.
So here is the code (I just added the soft reset sequence according to the Developers Guide):
const int freqOutputPin = 9;   // OC1A output pin for ATmega328 boards

#define TMR1 0

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

void setup() {
  pinMode(freqOutputPin, OUTPUT);
  Serial.begin(9600);

  TCCR1B |= (1 << CS10);  //selecting prescaler 0b001 (Tclk/1)
  TCCR1B &= ~((1 << CS12) | (1 << CS11)); // turn off CS12 and CS11 bits
  TCCR1A |= ((1 << WGM11) | (1 << WGM10)); //Configure timer 1 for TOP mode (with TOP = OCR1A)
  TCCR1B |= ((1 << WGM13) | (1 << WGM12));
  TCCR1A |= (1 << COM1A0); // Enable timer 1 Compare Output channel A in toggle mode
  TCCR1A &= ~(1 << COM1A1);
  TCNT1 = 0;
  OCR1A = TMR1;

  delay(500);  //Initial delay
  Wire.begin(); // join i2c bus as master
  Serial.begin(9600);
  Serial.println("MT9D111 Camera Module + Arduino");
  Serial.println("Read and Write 16-bit register value example");
  Serial.println("*  Read expected value = 0x1519 from Register 0x00");
  Serial.println("*  Write value = 0xA5F0 to Register 0x20:1");
  Serial.println();
  init1(); //execute code just 1 time
}

void loop() {
}

void init1() {
  int16_t a;

  delay(500);  //wait until start
  Serial.print("Soft reset first");
  Serial.println();
  soft_reset();//do a soft reset at startup

 //***************Configuration here!****************//
  Serial.print("Read result from register 0x00");
  a = read_reg(0);
  Serial.println();
  Serial.print("0x");
  Serial.println(a, HEX);  //print result
  Serial.println();
  Serial.print("Read original data from register 0x0a, should be 11");
  Serial.println();
  a = read_reg(10);
  Serial.print("0x");
  Serial.println(a, HEX);  //print result
  Serial.println();

  //Enable this part for writing register
  //Some example reads and writes follow
  Serial.print("Writing 0xA5F0 in register 0x20:1");
  Serial.println();
  write_reg(32, 1, 165, 240);
  Serial.print("Read new value from register 0x20:1");
  Serial.println();
  a = read_reg(32);
  Serial.print("0x");
  Serial.println(a, HEX);  //print result
  Serial.println();
  Serial.print("Writing 0xA1F3 in register 0x20:1");
  Serial.println();
  write_reg(32, 1, 161, 243);
  Serial.print("Read new value from register 0x20:1");
  Serial.println();
  a = read_reg(32);
  Serial.print("0x");
  Serial.println(a, HEX);  //print result
  Serial.println();
}

//Write 2Byte register
void write_reg(int reg_address, int page, int data_msb, int data_lsb) {
  delay(5);  //5ms
  Wire.beginTransmission(93); // transmit to device 93, Camera Module
  Wire.write(240);   //page register address
  Wire.write(0);
  Wire.write(page);   //select page 0/1/2
  Wire.endTransmission(1);    // stop transmitting
  Wire.beginTransmission(93); // transmit to device 93, Camera Module
  Wire.write(reg_address);   //register address 8bit, decimal
  Wire.write(data_msb);  //msbyte
  Wire.write(data_lsb);  //lsbyte
  Wire.endTransmission(1);    // stop transmitting
}

//read 2Byte register
//be careful about selected register page
int16_t read_reg(int reg_address) {
  int16_t err;
  delay(5);  //5ms
  Wire.beginTransmission(93); // transmit to device 93, Camera Module
  Wire.write(reg_address);   //register address 8bit, decimal
  err = Wire.endTransmission(1);    // stop transmitting
  Serial.println(err);
  Wire.requestFrom(93, 2, 1); //request value form device 93, 2 bytes with stop bit
  int16_t result = ((Wire.read() << 8) | Wire.read());  //read 16 bits
  return result;
}

//Perform Soft reset, required at startup
void soft_reset(){
  write_reg(101, 0, 160, 0);//write registers according to dev guide
  write_reg(195, 1, 5, 1);
  write_reg(13, 0, 0, 33);
  delay(5);
  write_reg(13, 0, 0, 0);
  delay(5);//wait for i2c to be ready again
}

Running this code gives me the following result on the serial monitor:

So here are the questions:

Do you have any ideas why I get an extra FFFF when reading a register after writing it? (underlined in blue)
Why are there some extra zeros in the output? (marked in yellow)

How did you get this to work. I tried the same code with OV2640 but I always get error as 2 and value read as 0xFFFF. Please help me.

Would you still happen to have the MT9D111 Dev Guide? I can't seem to find it online.

Found it here: https://files.niemo.de/aptina_pdfs/MT9D111_Dev_Guide.book.pdf

The 0 comes from your code:
Serial.println(err);

It's printing the error code. 0, hence no error.
As for the extra FFFF I'd say it's because you are using signed integers. Change your a declaration to uint16_t and see if that fixes it.

Thanks, that was some fast help. Solved the problems :-)

Happy to help :-)


text:
RF24 tranceivers: trouble with two way communication
I am using RF24 modules with my two Arduinos Leonardo with the RF24 library. My goal is to be able to press a button on the first Arduino which will light up an LED on the second Arduino, and be able to press a button on the second Arduino to light up an LED on the first Arduino. I was easily able to figure this out as a one-way transmission with the first Arduino only transmitting and the second only receiving, but I am unable to make it a two-way transmission, where each Arduino can transmit and receive at the same time.
This is my code so far:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>

int msg[1];
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
const uint64_t pipe2 = 0xF0F0F0F0AA;
void setup(void){
  Serial.begin(57600);
  pinMode(A0, INPUT);
  radio.begin();
  radio.openWritingPipe(pipe);
  radio.openReadingPipe(1,pipe2);
}

void loop(void){
  int charToSend[1];
  charToSend[0] = digitalRead(A0);
  if (!radio.write(charToSend,1)) {Serial.println('didn\'t send');}
  radio.startListening();
  if (radio.available()){
    bool done = false;
    done = radio.read(msg, 1);
    Serial.println(msg[0]);
    digitalWrite(13, msg[0]);
  }
  radio.stopListening();
  radio.powerDown();
  delay(10);
  radio.powerUp();
}

But the radio.write() is returning false and therefore not sending.

Please update your library to github.com/TMRh20/RF24. That way you'll get a faster and more stable library.

The main thing that I can see wrong with your sketch is that the logic of your methodology is backwards.
You are spending most of your time either with the radio asleep, or not in listening mode, so it can not receive anything.
Instead you need to spend all your time in listening mode waiting for messages to arrive, and only when the button changes state do you want to switch off listening mode and send a packet to the other end. As soon as you have done that you then go back to listening.
You can't listen while the radio is powered down, so using powerDown() and powerUp() is just nonsense.


text:
Why can't I include a library in another one?
I am trying to create a new library that uses another existing library.
The original library declares a way to create an object called Multiserial that can be created in the main file and the program is correctly compiled.
However, when I include this library in a second one and I try to build the program, then the IDE returns an error that says:

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:27:0,
                   from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h:26,
                   from MultiSerial.h:17,
                   from maqMODBUSmst.h:5,
                   from maqMODBUSmst.c:1:
  C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Printable.h:25:1: error: unknown type name 'class'
   class Print;

Even if the library only contains the include of the first one.

I am absolutely stupid. The fail was that ai was trying to use classes in a .c instead creating a .cpp

Nested includes lead to these convoluted error messages and are in general, a PITA for the next reader to follow & understand. It is better practice for the dependent library to test, at compile time, for the existence of its required libraries and for each one found missing, issue:
#error DepLibe.h: Missing required include file ReqLibe.h

Most .h files guard against multiple-inclusion by
#ifndef _REQLIBE_H_
#define _REQLIBE_H_
// library definitions here

or some variant of it. DepLibe.h can test for these guard symbols. DepLibe.h should document the dependencies in prominent comments.


text:
In Linux, how to identify multiple Arduinos connected over USB?
If I have multiple Arduinos connected over USB to a Linux computer, and they show up as

/tty/ACM0
/tty/ACM1
/tty/ACM2

How can I identify which Arduino is which without connecting to them via serial connection? Is there a serial number or a unique id on the Arduino?
Thank you for your time.
Situation: Uno R3, Mega, Leonardo with /ttyACM[1,2,3]
lsusb output with devices in the order mentioned above:

...
Bus 001 Device 011: ID 2341:0043
Bus 001 Device 013: ID 2341:8036
...
Bus 001 Device 014: ID 2341:0042

lsusb -d vendor:device -vvv shows for each one
Uno

Bus 001 Device 014: ID 2341:0042
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            2 Communications
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x2341
  idProduct          0x0042
  bcdDevice            0.01
  iManufacturer           1 Arduino (www.arduino.cc)
  iProduct                2
  iSerial               220 55330313735351910141
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           62
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xc0
      Self Powered
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      1 AT-commands (v.25ter)
      iInterface              0
      CDC Header:
        bcdCDC               10.01
      CDC ACM:
        bmCapabilities       0x06
          sends break
          line coding and serial state
      CDC Union:
        bMasterInterface        0
        bSlaveInterface         1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval             255
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      0
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
Device Status:     0x0000
  (Bus Powered)

Leonardo:
Bus 001 Device 013: ID 2341:8036
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x2341
  idProduct          0x8036
  bcdDevice            1.00
  iManufacturer           1 Arduino LLC
  iProduct                2 Arduino Leonardo
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength          100
    bNumInterfaces          3
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Association:
      bLength                 8
      bDescriptorType        11
      bFirstInterface         0
      bInterfaceCount         2
      bFunctionClass          2 Communications
      bFunctionSubClass       2 Abstract (modem)
      bFunctionProtocol       1 AT-commands (v.25ter)
      iFunction               0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      0 None
      iInterface              0
      CDC Header:
        bcdCDC               1.10
      CDC Call Management:
        bmCapabilities       0x01
          call management
        bDataInterface          1
      CDC ACM:
        bmCapabilities       0x06
          sends break
          line coding and serial state
      CDC Union:
        bMasterInterface        0
        bSlaveInterface         1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.01
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength     101
          Report Descriptor: (length is 101)
            Item(Global): Usage Page, data= [ 0x01 ] 1
                            Generic Desktop Controls
            Item(Local ): Usage, data= [ 0x02 ] 2
                            Mouse
            Item(Main  ): Collection, data= [ 0x01 ] 1
                            Application
            Item(Local ): Usage, data= [ 0x01 ] 1
                            Pointer
            Item(Main  ): Collection, data= [ 0x00 ] 0
                            Physical
            Item(Global): Report ID, data= [ 0x01 ] 1
            Item(Global): Usage Page, data= [ 0x09 ] 9
                            Buttons
            Item(Local ): Usage Minimum, data= [ 0x01 ] 1
                            Button 1 (Primary)
            Item(Local ): Usage Maximum, data= [ 0x03 ] 3
                            Button 3 (Tertiary)
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0x01 ] 1
            Item(Global): Report Count, data= [ 0x03 ] 3
            Item(Global): Report Size, data= [ 0x01 ] 1
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Global): Report Count, data= [ 0x01 ] 1
            Item(Global): Report Size, data= [ 0x05 ] 5
            Item(Main  ): Input, data= [ 0x03 ] 3
                            Constant Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Global): Usage Page, data= [ 0x01 ] 1
                            Generic Desktop Controls
            Item(Local ): Usage, data= [ 0x30 ] 48
                            Direction-X
            Item(Local ): Usage, data= [ 0x31 ] 49
                            Direction-Y
            Item(Local ): Usage, data= [ 0x38 ] 56
                            Wheel
            Item(Global): Logical Minimum, data= [ 0x81 ] 129
            Item(Global): Logical Maximum, data= [ 0x7f ] 127
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x03 ] 3
            Item(Main  ): Input, data= [ 0x06 ] 6
                            Data Variable Relative No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Main  ): End Collection, data=none
            Item(Main  ): End Collection, data=none

            ......

      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
Device Status:     0x0000
  (Bus Powered)

And Mega256:
Bus 001 Device 014: ID 2341:0042
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            2 Communications
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x2341
  idProduct          0x0042
  bcdDevice            0.01
  iManufacturer           1 Arduino (www.arduino.cc)
  iProduct                2
  iSerial               220 55330313735351910141
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           62
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xc0
      Self Powered
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      1 AT-commands (v.25ter)
      iInterface              0
      CDC Header:
        bcdCDC               10.01
      CDC ACM:
        bmCapabilities       0x06
          sends break
          line coding and serial state
      CDC Union:
        bMasterInterface        0
        bSlaveInterface         1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval             255
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      0
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
Device Status:     0x0000
  (Bus Powered)

lsusb -vvv says?

Can you unplug one and see which one disappears?

Not really, i want to do this for a remote solar-powered sensor array that will be very far away for someone to do that when it reboots.

Ignacio Vasquez-Abrams - how can I map the information from lsusb -vvv to /dev/ttyACM ? IS there something in the lsusb output i can parse? Thank you for the idea!

Do you have another Arduino you can compare output with?

Added two more arduino types - all 3 connected at once.

What also puzzles me is that the leonardo has iSerial = 0, while the others have a serial number.

Does this article from my personal website help? http://wirespeed.xs4all.nl/mediawiki/index.php/Udev_rules_file_for_Arduino_boards  I am curious if other Leonardo's have the same 0 serial number, it seems odd to me.

What happens if you use sudo lsusb -s............?

Assuming your distro is using udev:
udevadm info --query=all --name=/dev/ttyACM0

You might need root privileges to run this(sudo / su). It will output a list of information like this:
P: /devices/pci0000:00/0000:00:1d.2/usb4/4-2/4-2:1.0/tty/ttyACM0
N: ttyACM0
S: serial/by-id/usb-Dean_Camera_LUFA_USB-RS232_Adapter_74133353537351403012-if00
S: serial/by-path/pci-0000:00:1d.2-usb-0:2:1.0
E: DEVLINKS=/dev/serial/by-id/usb-Dean_Camera_LUFA_USB-RS232_Adapter_74133353537351403012-if00 /dev/serial/by-path/pci-0000:00:1d.2-usb-0:2:1.0
E: DEVNAME=/dev/ttyACM0
E: DEVPATH=/devices/pci0000:00/0000:00:1d.2/usb4/4-2/4-2:1.0/tty/ttyACM0
E: ID_BUS=usb
E: ID_MM_CANDIDATE=1
E: ID_MODEL=LUFA_USB-RS232_Adapter
E: ID_MODEL_ENC=LUFA\x20USB-RS232\x20Adapter
E: ID_MODEL_FROM_DATABASE=Uno R3 (CDC ACM)
E: ID_MODEL_ID=0043
E: ID_PATH=pci-0000:00:1d.2-usb-0:2:1.0
E: ID_PATH_TAG=pci-0000_00_1d_2-usb-0_2_1_0
E: ID_REVISION=0001
E: ID_SERIAL=Dean_Camera_LUFA_USB-RS232_Adapter_74133353537351403012
E: ID_SERIAL_SHORT=74133353537351403012
E: ID_TYPE=generic
E: ID_USB_DRIVER=cdc_acm
E: ID_USB_INTERFACES=:020201:0a0000:
E: ID_USB_INTERFACE_NUM=00
E: ID_VENDOR=Dean_Camera
E: ID_VENDOR_ENC=Dean\x20Camera
E: ID_VENDOR_FROM_DATABASE=Arduino SA
E: ID_VENDOR_ID=2341
E: MAJOR=166
E: MINOR=0
E: SUBSYSTEM=tty
E: UDEV_LOG=3
E: USEC_INITIALIZED=751387324986

This is for an Uno with modified firmware on the atmega16u2(usb to serial). The lines of interest are probably ID_MODEL_ID and ID_MODEL_FROM_DATABASE.

Thank you. I am using OpenWrt in this case with hotplug2 by default but I will try to switch to udev and test this.

On Ubuntu 16.04 (and maybe previous versions or other distribs too), you can do:
> ls /dev/serial/by-id

which displays (on my box where an Arduino UNO is connected):
usb-Arduino__www.arduino.cc__0043_A4139363931351318241-if00

You can easily spot the Device ID 0043 (UNO) here.
This file is actually a link to /dev/ttyACM0 in my box.

Use ls -la /dev/serial/by-id to see the link

You can add an alias for each. Then you know which is which. Here is a nice tutorial on how to set this up.
Here is a snippet that I wrote based on the tutorial. In the below example, I am using a FTDI RS232RL USB to Serial adapter, which I believe is what the Arduino uses too.

In order to assign an alias to a USB-Serial device, we need to find some info on the device
Plug in the usb. This assumes you have already install the drivers for this use be device and the device is visible when typing:

lsusb

We are going to need the following
a.    The vendor id
b.    The product id
c.    The device serial number
To do this, it takes a little bit of hunting. All your devices log entries in '/var/log/messages'.

Therefore we can read this file and find the correct USB:
grep "ftdi" /var/log/messages

You can also use "usb"

This is find all messages tagged with ftdi:
Next to ftdi_sio, there is a number like 1-1.2. This is the USB device

grep "usb 1-1.2" /var/log/messages
Or you can use:
dmesg | grep "usb 1-1.3"

This gives us all the info we need:

Now with the list of serial numbers in hand let’s create a UDEV ruleset that’ll make a nice symbolic link for each of these devices. UDEV rules are usually scattered into many files in /etc/udev/rules.d. Create a new file called 99-usb-serial.rules and put the following lines in there:

In this example my alias is called 'lcdbox'
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A601ERJJ", SYMLINK+="lcdbox"

SYMLINK is the name of your alias. In this case my alias is lcdbox.
Save the file and type
sudo udevadm control --reload-rules
Type
ls –l /dev/lcdbox

lrwxrwxrwx 1 root root 7 Jan  1  1970 /dev/lcdbox -> ttyUSB0

This shows that my lcdbox alias is mapped to ttyUSB0

This is quite easy! You have to customize the ftdi chips firmware and add an udev rule:
First, get ftdi_eeprom via apt-get or from the sources. Identify your device via lsusb and get the id:

lsusb

Bus 001 Device 005: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC
....

Prepare a config and make sure, that vendor_id and product_id match. Customize the strings in the Strings section to get a unique id for your device.

vendor_id=0x0403    # Vendor ID
product_id=0x6001   # Product ID

max_power=50        # Max. power consumption: value * 2 mA. Use 0 if self_powered = true.

###########
# Strings #
###########
manufacturer="FTDI"     # Manufacturer
product="Arduino Nano"      # Product
serial="arduino1"       # Serial

###########
# Options #
###########
self_powered=false  # Turn this off for bus powered
remote_wakeup=false # Turn this on for remote wakeup feature
use_serial=true     # Use the serial number string

# Normally out don't have to change one of these flags
# BM_type_chip=true         # Newer chips are all BM type
in_is_isochronous=false     # In Endpoint is Isochronous
out_is_isochronous=false    # Out Endpoint is Isochronous
suspend_pull_downs=false    # Enable suspend pull downs for lower power
change_usb_version=false    # Change USB Version
usb_version=0x0200      # Only used when change_usb_version is enabled

########
# Misc #
########

filename="eeprom.old"   # Filename, leave empty to skip file writing
cbus0=RXLED#
cbus1=TXLED#

Dump the current ftdi-firmware:
ftdi_eeprom --read-eprom
This command creates ${pwd}/eeprom.old, which contains the current firmware on the ftdi. Backup this file before continuing, because during flash-eeprom the file gets rewritten. After the backup, flash the ftdi:
ftdi_eeprom --flash-eeprom myconfig.conf

Now, create an udev rule, like so
SUBSYSTEMS=="usb", ATTRS{idProduct}=="6001", ATTRS{idVendor}=="0403", SYMLINK+="$attr{serial}", OWNER="bananapi", GROUP="pi", MODE="0777"

in /etc/udev/rules.d/90-arduino-usb.rules and restart udev.
service udev restart

Unplug and re-plug your device and try
ls -lah /dev/arduino1

Where arduino1 is the string defined under serial in the above .conf.
See also: Risks of ftdi_eeprom? - TX always high after flashing

I would have used a script to make an alias under /dev/ and also set group and rights on it with udev like the other answers.
But if I didn't have udev I would pipe lsusb into grep or awk, like lsusb|grep -e "idProduct".
Anyway, with udev rules or with lsusb and grep to identify USB devices, use idVendor, idProduct and iSerial in Device descriptor part of lsusb to make the proper idenification.  The idVendor tells you the manufaturer, idProduct should indentify the product from the manufacturer but sometimes they use the same product id for more than one product.  Lastly, if needed, the iSerial should be a unique id for each example of that product.

You can always make some kind of id print via serial in void setup(). After the certain board is connected it will send this id to your USB interface (which you are listening with some kind of daemon app on your linux box). Once you receive id you can map it to it's path
 'Arduino1' : '/dev/ttyACM0',
 'Arduino2' : '/dev/ttyACM1',
 'Arduino3' : '/dev/ttyACM2'...etc
Be aware that when device is disconnected for some reason it can change it's physical path so you might have to remap all of them. For this case it might be good to write separate function ex: get_id() which you can call any time (not only on startup).

I'd be mighty tempted to identify some other way, like having the sketch itself respond to a special identify command, just to avoid USB's odd ways of identifying devices.

Overview

One way as ansi_lumen mentioned in his answer is to flash ftdi
chip EEPROM to have unique serial number which then could be
identified by UDEV rules.
But turns out it won't work on cheap chinese Arduinos which instead
of FTDI has CH340G chip which doesn't have EEPROM to store
unique ID (CH340B should work).
This answer suggests to write UDEV rule with special script
which asks Arduino to send its unique ID via serial. Problem with
that is that you need to modify Arduino sketch and in general it's
quite complex.

Identifying by port
So the easiest way I found was to use UDEV rules and identify Arduinos by the usb port (devpath)
so connecting Arduino to the same port (even in nested usb hubs) will create persistent name.
TLDR setup:
Modified version of this

Find Arduino idVendor and idProduct:

lsusb
You will get something like this:
...
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 124: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Bus 003 Device 123: ID 214b:7000
Bus 003 Device 122: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Bus 003 Device 121: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Bus 003 Device 120: ID 1a40:0101 Terminus Technology Inc. Hub
...

By connecting/disconnecting Arduino find which one it is (I have 3 connected). We are looking for its ID. In my case "...ID 1a86:7523 QinHeng...". So idVendor=1a86, idProduct=7523

Create new UDEV rules file:

sudo nano /etc/udev/rules.d/99-usb-serial.rules

Modify idVendor and idProduct values by what you found in previous step on copy paste it in the rules file we have created:

SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="ttyUSB-arduino%s{/devpath}"

Reload UDEV rules

sudo udevadm control --reload

Replug Arduinos and now it will have unique name. To test it type:

ls /dev/ttyUSB*

Which will output:
/dev/ttyUSB1  /dev/ttyUSB3  /dev/ttyUSB-arduino2.1  /dev/ttyUSB-arduino2.4
 /dev/ttyUSB2  /dev/ttyUSB4  /dev/ttyUSB-arduino2.2  /dev/ttyUSB-arduino3
As you can see we still get /dev/ttyUSBx as before which are always changing depending which one was connected first. But now we also have /dev/ttyUSB-arduino{port} which are always the same for same port and only for Arduinos. To analyze what "..arduino2.4" means: 2 refers to the second port of laptop and 4 to the fourth port on usb hub.
To better see it type:
lsusb -t

Output:
...
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
    |__ Port 1: Dev 5, If 0, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 1: Dev 5, If 1, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 2: Dev 84, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 1: Dev 85, If 0, Class=Vendor Specific Class, Driver=ch341, 12M
        |__ Port 2: Dev 86, If 0, Class=Vendor Specific Class, Driver=ch341, 12M
        |__ Port 3: Dev 87, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 4: Dev 88, If 0, Class=Vendor Specific Class, Driver=ch341, 12M
    |__ Port 3: Dev 89, If 0, Class=Vendor Specific Class, Driver=ch341, 12M
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/6p, 480M
...

By connecting/disconnecting you can see which devices are on which ports


text:
Am I able to connect an anti static wrist strap to the ground pin on the Arduino uno?
So you have the pin on the arduino uno which is ground, are you able to use a jumper wire to send the ground source out the other end of the wire to the alligator clip for the antistatic wrist strap?

Maybe see Connect anti-static wrist strap to earth wire?

Like @NickGammon I exercise sensible precautions when handling electronic components. However I have NEVER used a wrist strap, and in over 40 years of designing and building microelectronics have NEVER damaged a chip with static (lots damaged with wrong voltages, wrong connections). If you are going to use one the 0V pins (incorrectly labelled Gnd), or any equivalent,  is the best option. Modern chips are a lot more robust than the 1970s vintage MOS chips.

I was about to write that I wouldn't do that, but in view of the post I linked to - I am changing my mind.
The point to the wrist strap it to have you, and the thing you are touching, at the same potential (whatever that is relative to the known Universe). Now if you connected the strap to the earth on your power point, that would not achieve anything unless your Arduino was also grounded (eg. via a USB cable).
So using the ground wire on the Arduino sounds sensible enough. Personally I don't usually do that, however if I have moved around (and might have shuffled over some carpet, etc.) I always touch some metal part to ground myself (for example, a metal switch on a lab power supply) and discharge any static that might have built up by moving around on the floor.


text:
No message got sent
I used this code:
void setup() {
  Serial.begin(4800); //Baud rate of the GSM/GPRS Module
  Serial.print("\r");
  delay(1000);
  Serial.print("AT+CMGF=1\r");
  delay(1000);
  Serial.print("AT+CMGS=\"+918281537478\"\r");
  //Number to which you want to send the SMS
  delay(1000);
  Serial.print("Test SMS -Jay\r");
  //The text of the message to be sent
  delay(1000);
  Serial.write(0x1A);
  delay(1000);
}

void loop() { }

In the serial monitor AT commands were printed but no message was sent. Someone please help.

Maybe you need to send the messages to a GSM shield instead of your PC?

Welcome to Arduino SE.  Please be sure to take the tour at https://arduino.stackexchange.com/Tour

I have the same code and it's working fine. But in my code, I set my baud rate 9600 means you have to change
Serial.begin(4800);

to
Serial.begin(9600);

And few question... which GSM Model you used? GMS SIM 300 or someone else. Becuase mine is GSM SIM 300. If you have someone else then maybe you have received some document with it, in that specific baud rate is defined. Just set it.
And then fist of all, check your GSM board is really working or not? Becuase I have this problem but that time my GSM module is not working. So, I replace and then everything working fine.
Put your SIM CARD on GSM and then make a call. If the buzzer is ringing that mean your GSM board working fine. Be sure about your arduino connection with GSM shield.
I hope this will help you.

Serial.print is designed to print out to the serial (programming) port.
If you are seeing these commands there then that means they are not being sent to the GSM module.


text:
Three or more Arduino slaves sending bytes to 2 different I2C devices
I'm trying to connect 3 Arduinos with this scheme: Arduino1 Master, Arduino2 Slave, Arduino3 Slave. The slave devices need to communicate with each other and I'm trying to programming Arduino2 and transmit bytes to the other slave device Arduino3 and Master Arduino1 at the same time. Is that possible?
Master CODE:
#include <Wire.h>

void setup() {
  Wire.begin();
}

void loop() {
  Wire.requestFrom(0x04, 2);
  while (Wire.available()) {
    var1 = Wire.read();
    var2 = Wire.read();
  }
}

Arduino1 Slave:
#include <Wire.h>

void setup() {
  Wire.begin(0x05);
  Wire.onReceive(receiveEvent);
}

void loop() {
}

void receiveEvent(int howMany) {
  var1 = Wire.read();
  Serial.print("VAR1 is : ");
  Serial.println(var1);
}

Adrduino2 Slave code:(Where I think I'm wrong)
#include <Wire.h>
int var = 123;
int var2 = 123;
int var3 = 123;

void setup() {
  Wire.begin(0x04);
  Wire.onRequest(requestEvent);
}

void loop() {
  Wire.beginTransmission(0x05);
  Wire.write(var);
  Wire.endTransmission();
}

void requestEvent() {
  Wire.write(var1);
  Wire.write(var2);
}

Is this the correct way to make the Arduino2 send to 2 devices?

I hope I can ask a 'side' question ... in my project I eventually also want to make use of a master and some slaves Arduino's ... I2C seems very appropriate. Wonder if Wire might be better than I2C.

As soon as an Arduino starts writing data, it is a Master. Do you use Arduino Mega 2560 and Arduino Uno and Nano boards ? In theory those ATmega microcontrollers can handle collisions in a multi-Master bus, and in theory the Wire library handles collisions as well. However, everyone tries to avoid that, because it causes a lot of problems. You would even have to program a complete new layer in the code to re-transmit data until it was received without collision.
Select one Arduino board as Master, and use the Master to read and write data. If you want to transfer data from one Slave to the other Slave, then use Master to read the data from one Slave and write the data to the other Slave.
It is possible to use other busses between the two Slave Arduino boards.


text:
AVR software reset without watchdog
I wrote a generic avr program wrapper which already use the watchdog timer to restart - and after the watchdog reset - recover the the bad situation.
After this recover process i have to restart the avr. Everything i've found in topic "software reset arduino" is about to set the shortest watchdog (15ms) timeout, then spins the CPU (for(;;);) until it cause watchdog reset.
But this results to enter the recovery process which is already done in this point.
It is any elegant way to achieve this?
Some non or less elegant way:

I can bind a digital pin to the reset and pull up with a resistor.
I can write to a fixed address in the flash or eeprom (but this maybe happens frequently) before soft restart, to prevent entering to recovery mode.

Is there any register that "survives" soft resets?
Edit:
I add mock example code to hint what i trying to do.
In the actual code, in the recovering the microcontroller connect to the serial bus, waits for commands then resets itselft in oder to return to application mode.
/*************************** Application wrapper ******************************/

//define call_application and call_recover as weak empty functions
//so they can be rewritten.

bool isWatchdogReset()
{
    return MCUSR == 8;
}

void softwareReset()
{
    //  wdt_enable(WDTO_15MS);for(;;);// (this way enters recovery mode)
    //or
    //  asm ("jmp 0x0");// (this way function registers not being resetted)
}

bool isSoftwareReset()
{
    //???
}

int main()
{
    bool needRecover = isWatchdogReset() && !isSoftwareReset();
    MCUSR = 0;
    init_board();
    wdt_enable(WDTO_1S);
    while(1)
    {
        if(!needRecover)
        {
            call_application();
        }
        else
        {
            call_recover();
        }
        wdt_reset();
    }
}

/********************************* Application ********************************/

void call_application()
{
    if(randomTrue())
    {
        //stuck more that 1 secounds, that results WDT reset
    }
    else
    {
        //proper operation
    }
}

/********************************** Recover ***********************************/

void call_recover()
{
    //initialize UART, attach interrupts, Write flash and EEPROM, modify
    //function registers.

    //recovering completed, returning to the original application as like
    //nothing's happened.
    softwareReset();
}

Edit:
I try explain short to spot the point:
1) I already use the watchdog timer to detect when the application code is flawed.
2) soft reset is an inproper solution, because it doesn't reset the registers. So onyl the program will be resetted, the state of the microcontroller doesn't.
3) To commit a proper reset, the solution is to timeout the watchdog timer. But see point 1), it is already used, so how can you make the difference of a requested reset and a flawed code recovery reset?

and why is the second wdt reset a problem? or why you can"t continue without reset?

I've read you question three times, but I still don't get what it is you are describing. What is this "recovery process" you are talking about? Are "recovering" stuff in a WDT interrupt routine.

The reset is basically jumping to the reset vector address 0x0000 (if you don't have the bootloader, or you don't want to start it).
There is also the MCUSR register, indicating which reset source caused the reset. It won't be set if you do simple jump to the reset adress.
The memory is also preserved, but C/C++ init code takes place and initialize your global variables. This can be ommited by placing variable/variables into the .noinit section. But it's not defined, what is there after the reset. With combination with MCUSR register you can init the variables for regular reset sources and keep it unchanged if you jump to the reset vector address.
Also the regular reset sources jumps to the bootloader, so it can use the same memory locations as your .noinit variables and trash them.

I check MCUSR register right after start to identify the source of reset/power up. Now I've tried this way of reset (void sw_reset(){asm("jmp 0x0");}). It's works, but - as i disassembled - it just resets the stack pointer, which results to start the program again from the main(), but  port, timers, UART settings are remains

@DankóDávid So you don't want to restart it? Maybe it's an XY Problem?

Note also that a hardware reset sets all the I/O registers to their initial value, which a jump to 0x0000 doesn't. Only very few registers, like MCUSR have no defined initial value.

@EdgarBonet yes, that might be a problem in the middle of TWI communication or so. But initialization code should be written as there is already something configured. Definitely in this case.

I've edited the question and added an example what the exact problem i trying to solve. 1) I already use the watchdog timer to detect malfunction. 2) I'd like to reset the AVR completely (resetting all function register what the recovery function touched and i can't track), but the only way i've found is to use WDT timeout which results not just to restart, but to recognise as a "malfunction restart". More simplified: I need a malfunction reset (WDT) and an intentional software reset, which not share the same mechanism of reset. Or differentiate the two way of resetting the AVR.

The logic of you applications is wrong. You set the needRecover at the beginning of main, but test it in your infinite while (1) loop. The needRecover value will not change in the loop.
Do your initialization first no matter if normal power-up or watchdog restart and then do stuff in the infinite loop.
You could put the initialization in a function called setup and the infinite loop in a function called loop. And have a main function like this:
int main( void )
{
  setup();

  for (;;)
  {
    loop();
  }

  return 0;
}

wait, a saw this somewhere already :-)

The recovery process should restart the microcontroller. But now this uses watchdog timer to do this. Which cause to enter again into the recovery mode and not to the application mode.

@DankóDávid, use watchdog interrupt instead of watchdog. make the arrangements in the interrupt and then reset with wdt_enable(WDTO_15MS); my is here: https://github.com/jandrassy/Regulator/blob/b6ef120c6f8963979268d8d17b56e5632336f317/Regulator/Watchdog.ino#L24

you could use this library https://github.com/nadavmatalon/WatchDog I plan to replace my watchdog handling with it


text:
How to multitask while writing on Serial
I am trying to send real-time data taken from an ADC by Arduino Uno (SPI) to Arduino IDE through a USB cable. I found that one byte takes around 70 microseconds when Serial.write() is used at a baud rate of 115200. My question is that if I send 14400 bytes (which would be the maximum limit at this baud rate), can I perform any other tasks? Does Arduino allow multitasking while the serial buffer is busy writing data?

why do you say that 14400 bytes is a limit?

Until you fill the transmit buffer (64 bytes by default but can be recompiled to enlarge it if you need to), Serial.print() or Serial.write() will return immediately. The characters in the buffer will be transmitted by an interrupt service routine, so essentially, the Arduino is double-tasking for that purpose. If the buffer is full when you call Serial.print() or Serial.write() or Serial.print() fills it before having sent all of its characters, those calls block (won't return) until there is buffer-space for their remaining characters.
So yes, you can do other things while the writing happens, as long as you haven't filled the buffer. You can call Serial.availableForWrite() to find out how many characters you can send without blocking.
By the way, at 115200 baud, or 11520 bytes/second, each character should take 1/11520 seconds or 86.8 microseconds, not 70 milliseconds.

Thanks @JRobert. I will use serial.available and find out the time periods taken by serial.write and then I will get back.

I think baud rate specifies bits per second. So, to write a byte, it should take 1/115200*8 seconds, which comes out to be around 70 microseconds which is what exactly I found. Sorry for the typo earlier, I wrote milliseconds by mistake.

But in fact, serial transmission takes 10 or 11 bits (1 start bit, 8 data bits and 1 or 2 stop-bits; 1 is most common) to send an 8 bit byte. So you need to divide by ten instead of by 8.

Yes you are right. I will recheck the time values.

JRobert said Serial.availableForWrite not Serial.available. They are totally different things.


text:
DHT 11 temp. And hum. Sensor always 0 values

I am trying to get my DHT 11 from the official arduino store to work (https://store.arduino.cc/grove-temperature-humidity-sensor).
I am following this guide right here:
http://wiki.seeedstudio.com/Grove-TemperatureAndHumidity_Sensor/
But I'm only getting invalid output of 0 humidity and 0 degrees.
I hope the image helps in identifying my problem.
On a side note, my sensor looks like a part is missing which is very strange and makes me doubt the right product was sent to me.
Some more information:
- Black to GND
- Red to 5v
- White is wmpty
- Yellow to d2
- Using an arduino Uno
- Output does not change whether the sensor is actually connect or not.
- Total noob at this.
Help would be appreciated a lot!

that's not a DHT-11 in the photo. Why would they break out a non-connected pin like that? Also, you link to a DHT22 (white plastic), not an 11 (blue plastic)...

Well yeah the top cover is missing.. Does it carry an electrical connection though? Can you upload a detailed picture of the DHT11 module from above?

@Maximilian Gerhardt I have added an image. How do I know if it carries an electrical connection?

That is a Grove temperature and humidity sensor module with the si7005 made by seeed studio: http://wiki.seeedstudio.com/Grove-TemptureAndHumidity_Sensor-High-Accuracy_AndMini-v1.0/ They also make a module with a DHT sensor, but that is an other one.

Okay, this is not a DHT11 board. This thing has an I2C bus. Either you ordered the wrong product or they sent you the wrong product. You bought the "Grove - TH02 - I2C temperature and humidity sensor" (https://botland.com.pl/en/grove-series-for-arduino/4413-grove-th02-i2c-temperature-and-humidity-sensor.html)

You haven't bought a DHT11 module but the Grove - Temperature&Humidity Sensor (High-Accuracy & Mini) / TH02 module.

Thus you should use the example code here or follow the guide at seedstudio wiki.
Datasheet of the sensor: https://www.silabs.com/documents/public/data-sheets/Si7005.pdf

That's upsetting. It's not what I ordered. I'll try to follow the guide you suggested and will let you know how that turns out. :)

@JonasBergner The sensor on this board has a superior accuracy (+- 0.5°C) when compared to the DHT11 (+- 1 °C) so I wouldn't exactly complain^^

ok this actually seems to be the product I have here with me. But i have trouble getting it to work following the instructions. I do understand that I need to connect Red to 5V and black to ground, but what does it mean to connect white to "SDA" and "SCL" to yellow? I'm kinda lost :D. I know youve already helped me a lot. I really appreciate it! @Maximilian Gerhardt

@JonasBergner SDA (Serial-DAta) and SCL (Serial CLock) are the 2 signals of the I2C bus. The Arduino Uno has its I2C pins on A4 (SDA), A5 (SCL), this is where the cables need to go. (https://www.arduino.cc/en/Reference/Wire)

heck yeah i got it to work! without burning my house down! Thank you so much!

How does the Grove TH02 compare to the DHT22?

@DuncanC Refer to the specifications of the Si7005 (https://www.silabs.com/documents/public/data-sheets/Si7005.pdf) and the DHT11 sensor (https://www.mouser.com/ds/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf), especially the parameters accuracy, resolution and range.

I asked how it compared to the DHT22, which is also more accurate than the DHT11. I haven't had enough coffee yet this morning to pour over data-sheets. If you know the differences off the top of your head, cool. If not I'll wait until I am more awake and slog through some data-sheets.

It looks like the DHT22 is more accurate.The DHT22 data sheet says ±2% RH, and ±0.2°C temp, where the Grove TH02 says ±4.5%RH and ±0.5°C typical (±1.0°C max).

@DuncanC oh okay I just read DHT11 instead of DHT22; yes in that case DHT22 beats this board.

The OP was trying to buy a DHT11. I started out using DHT11s and then moved to DHT22's, So I was curious as to how they compared.


text:
Not detecting Arduino Mega 2560. It worked before but now not detecting
I am using Windows 8.1 64 bit. I have an Arduino Mega 2560. I configured and installed it with the Merlin firmware before. I had a system format in between. I tried to connect my Arduino again.
I have the following problems:

Not detecting any hardware when plugging in the Arduino board: the green LED is on and the yellow LED is blinking. I checked the Device manager. It doesn't come in either COM ports or other devices. (The last time it came in COM ports as Arduino Uno). I installed legacy hardware on COM 3 (which was used before) and tried to update the driver from a newly downloaded version of Arduino. No success. I disabled the certification signature requirement from boot menu and tried: again no success.
The serial port on Arduino is greyed out.

I need some help. I am running out of ideas. I tried uninstalling COM port. I cleaned the registry with CCleaner. I uninstalled all Arduino software. I rebooted the system. I downloaded everything again, then connected the board. Still not detecting the new hardware. :P
Help me out.

Step 1: try it in someone else's computer to see if it's your computer or the Arduino that is at fault.

its not reading at any other computer as well. Tried using different usb cables as well no success

Then chances are it's the Mega that is at fault.  I have seen a number of posts recently about Arduinos failing to be recognised by the PC - maybe there is something going wrong with the USB interface common to them all.  All I can suggest is try re-flashing the USB interface microcontroller (ATMega16U2 IIRC) with a new firmware.

can you confirm if the previous program you uploaded is still running?

A useful reference for troubleshooting (most tips apply to the Mega as well as the Uno) https://arduino.stackexchange.com/questions/13292/have-i-bricked-my-arduino-uno-problems-with-uploading-to-board/

What you said has happened to me before.This happened to me as I supplied over 20v to the arduino.Did you supply a higher voltage than recommended or pull too many amps from the board?If you did so,it is almost futile to try to repair it.

Assuming the board is not fried...
Sounds like 'USB <--> serial' chip issue. Not sure which chip it is, could be CP2102 or FT232 or CH340G. If it is FT232R and not a genuine one and you are using a specific version of the driver - you could have bricked the USB <--> serial converter.
Without assumptions, I would start with a bootable USB pen-drive with some flavour of Linux - I prefer Linux Mint/Ubuntu. Here is how I would go:

Boot the system with the pen-drive with Arduino disconnected
Open terminal and tail the system log (e.g. tailf /var/log/syslog)
Attach the Arduino board and see what shows up.
If Arduino is detected, there will be a message with the serial port device name (e.g. /dev/ttyUSB0)
Arduino IDE could run on Linux. If the port is detected, run Arduino IDE and see if it detects the board.

If not detected, the board is still useable, but you might need to find a way to connect external USB <--> Serial converter and disconnect the on board one. That means cutting traces and probably soldering some pins.

It's possible it's fried - but I have had recovered some boards like this that the boot software had gotten corrupted.
It's easy enough to reapply the bootloader to the device - you will need either a second arduino:
https://www.arduino.cc/en/Tutorial/ArduinoISP
or an usbasp programmer (about $10 on eBay).
There is also a tutorial on reflashing the USB chip (link below) - but I would try the above first.
https://www.virtuabotix.com/how-to-cure-sudden-uno-death-syndrome/