text:
Multithreading with Arduino
Well I've just started learning the concept of multithreading with C++ and immediately a bunch of questions came to mind about the possibility of using multithreading with microcontrollers in general and Arduino specifically.
So, is it possible to use multithreading on any type of Arduino boards?

By multithreaded, do you also mean concurrent? If you don't, Interrupt routines triggered by a timer at even intervals can cover a lot of similar functionality on AVR processors.

You could try this library https://github.com/mikaelpatel/Arduino-Scheduler

In Cosa you can find the following support for concurrent programming:

Events, interface interrupt service routines
Jobs, delayed, periodic or alarm functions with us, ms and seconds level timers (Watchdog, RTT or RTC).
FSM, object-state function
ProtoThreads, object-state pointer
Threads, Semaphores, etc, multiple stacks
UML Capsules and Connectors, dependency driven programming

There are plenty examples on how to use these. A good starting point is the Blink sketches. There is even a multi-threading Blink example with a thread that does the LED on/off and a controller thread that periodically changes the blink period. The thread stack size is only 64 bytes and it runs even on an ATtiny.
With all the AVR internal hardware modules (such as SPI, TWI, UART, etc) there is plenty of opportunities for concurrency.
A Scheduler library for the Arduino core is also available. This is a port of the Cosa Threads. Please see github for further details.
Cheers!

Of what order is the memory overhead of Cosa? 100 KB flash and 20 KB RAM?

Depends on what you use/include. In general the "overhead" is less than the Arduino core for similar functionality. Best way to find out is to run some of the example sketches.

The really quick answer is "maybe" – it depends on what you mean by "Arduino" and what you mean by "thread." The answer is likely to be different for the AVR based Arduinos (Uno et al.) vs. the ARM based Arduinos (Due et al.) – I would expect there to be much better hardware support for "real" threads on the ARM processors. Another question you'd want to answer is "why threads?" Do you want the abstraction to help you organize your code? Or do you actually need "real" threads?
Before there was hardware thread support (e.g., the mid-80s) there are user thread implementations, it seems possible that they might be adaptable to run even on an AVR. I would expect it to be something of a project.
There is a threads package called Protothreads which may be interesting. The description says "Protothreads are extremely lightweight stalkless threads designed for severely memory constrained systems." I found another question asking about simple usage of Protothreads, so it seems that you may find some other users of the package.
You may also find some useful information in this Stack Exchange question on threads, a quick search for "C user threads" found this implementation on the first page – and I'm sure there are many more.
A search on "Arduino threads" found several more interesting looking links:

How can I create multiple running threads?
Arduino Thread package on GitHub
http://www.kwartzlab.ca/2010/09/arduino-multi-threading-librar/
http://forums.trossenrobotics.com/showthread.php?5923-Multithreading-(Parallel-loops)-on-an-Arduino

If you just want threads, a small and inexpensive board, and I/O pins it might be worth considering a Raspberry Pi – Linux has thread support.

Good answer. It also might be worth noting that even with hardware thread support, an OS or at least some software will layer will probably need to manage and schedule the threads.

@Mlagma: As far as I can tell, each link in this answer shows an implementation of threads that are statically compiled into the user's program. The Arduino runs only that one program. Can you give even one example of an OS or other software layer, other than the user program?

@Mlagma, it could be as simple as something like coroutines and interrupts. I'm not expecting to find much beyond maybe a library that implements a basic scheduler – but I haven't found even that.

There's one Arduino-like product that certainly could enable multi-threading, as it is multi-core: the Shield Buddy TC275.

So basically you have three setup() functions, and three loop() functions. True multi-threading.

+1 for finding this. Excellent board, but not cheap. However, it would give AeroQuad a new lease of life..!

Yeah it's been on my radar for a while but the cost... I hope Chinese clone-makers find it soon :-)

It's not as compatible as I initially thought though, for reasons that are, now, obvious. A simple recompilation may not be sufficient. It will depend on the complexity of the code, i.e. if assembler has been used. See Has anyone used a Shield Buddy (en lieu of a Arduino Mega2560) as the RAMPS 1.4 host board?

Yeah, ASM could be a problem. Plus, adjusting the code to a 3-core environment, even without ASM, would require some work. But I think for a new project, it could be indeed interesting.

I use Atomthreads on Atmega128, it is very lightweight with minimum overhead. Have task scheduler, mutex, semaphores and queue. Code is portable but might require some configuration to use with Arduino IDE (I use Atmel Studio). I primarily use task scheduler, never had problems. Just checked, the development is still active.

Re: "very lightweight". Can you quantify that? Is it 8 KB of flash and 600 bytes of memory?


text:
I'd like to make RC car and remote controller via bluetooth (HC06)
At first, I tried to make whole code for an RC car and remote controller, but I realized that it's difficult for me since I have few ideas about C++. So, I changed a few things like turning on the LEDs with switches and servomotors with potentiometer. Here are my code.
Remote controller
#include <SoftwareSerial.h>

SoftwareSerial BTSerial(2,3);
int sw1=13;
int sw2=12;

void setup() {
  BTSerial.begin(9600);
  Serial.begin(9600);
  pinMode(sw1, INPUT_PULLUP);
  pinMode(sw2, INPUT_PULLUP);
}

void loop() {
  int a = analogRead(A0);
  int map_a=map(a,0,1023,0,255);
  int state1=digitalRead(sw1);
  int state2=digitalRead(sw2);

  BTSerial.print('S');
  BTSerial.print(map_a);
  BTSerial.print(',');
  BTSerial.print(state1);
  BTSerial.print(',');
  BTSerial.print(state2);
  BTSerial.print('E');
  delay(100);
}

< RC CAR >
#include <SoftwareSerial.h>

SoftwareSerial BTSerial(2,3);

byte buffer[255];
int bufferPosition;

void setup() {
 BTSerial.begin(9600);
 Serial.begin(9600);
 bufferPosition=0;

}

void loop() {
  {
    if(BTSerial.available()>0){
    unsigned char data = (unsigned char)BTSerial.read();
    buffer[bufferPosition++]=data;
    Serial.println(data);
    delay(100);
    }
}
}

When I checked the result from Serial.println(data) from RC car code,
it was trash...
Can you instruct me what's wrong with this code?

Why the delay(100) in the RC CAR part? And what happens when the buffer is full? Seems incomplete. BW: Please use a code tag.

i was expecting this result
S map_a, state1, state2, E
S map_a, state1, state2, E
S map_a, state1, state2, E
....
after i receive this result, i would like to proceed more...and sorry, i didn't know how to use a code tag,,it is first time to ask a question here...

Please post what you actually get in the serial monitor - one man's "trash" is another man's really-easy-answer.

Wait, why are you casting to unsigned char ? Serial.print() very expects a 'regular' char.

There are some fundamental problems in the code - bufferPosition never stops increasing (until it reaches 32768) and so buffer will overflow. However, neither of these two problems are causing the 'trash', as you are outputting the result of reading the serial, not anything from the buffer.
The problem lies in the casting of the result from BTSerial.read() to unsigned char.
Serial.print() does not like this. Actually it doesn't care, but it won't give you what you expect. It just prints out the value stored - so 'a', which is 97, will come out as '97' on the serial monitor. Serial.print() only outputs ASCII characters when you give it a char or char[].

thank you so much. I just started to study C language. So i've got confused with char or int or unsigned char. I'm trying to learn those things from some examples..thanks again. I will try to fix some codes you mentioned and post again later :)

source: Stack Exchange

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

sort: votes


text:
Understanding values from an MPU6050
I'm trying to understand the values that I'm getting from my MPU6050. I believe that there is a problem with my code. I'm not entirely sure how the code is supposed to look like. There doesn't seem to be very many examples on the MPU6050.
What is wrong?
After taking a look at the system print I found that the numbers that are written out is the time and not the values of the MPU6050. Why am I getting the zeros and nan for?
I also had a library problem thats fixed now.
I got the code from a site and I've modified it because it didn't run for me.
This is my code:
// collect readings
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

// apply gyro scale from datasheet
gsx = gx/gyroScale;   gsy = gy/gyroScale;   gsz = gz/gyroScale;

// calculate accelerometer angles
ary = -(180/3.141592) * atan(ax / sqrt(square(ay) + square(az)));
arx =  (180/3.141592) * atan(ay / sqrt(square(ax) + square(az)));
arz = (180/3.141592) * atan(sqrt(square(ay) + square(ax)) / az);

// set initial values equal to accel values
if (i == 1) {
grx = arx;
gry = ary;
grz = arz;
}
// integrate to find the gyro angle
else{
grx = grx + (timeStep * gsx);
gry = gry + (timeStep * gsy);
grz = grz + (timeStep * gsz);
}

// apply filter
rx = (0.1 * arx) + (0.9 * grx);
ry = (0.1 * ary) + (0.9 * gry);
rz = (0.1 * arz) + (0.9 * grz);

 Serial.print(ax);   Serial.print("\t");
 Serial.print(ay);   Serial.print("\t");
 Serial.print(az);   Serial.print("\t\t");
 Serial.print(gx);   Serial.print("\t");
 Serial.print(gy);   Serial.print("\t");
 Serial.print(gz);   Serial.print("\t\t");
 Serial.print(arx);   Serial.print("\t");
 Serial.print(ary);   Serial.print("\t");
 Serial.print(arz);   Serial.print("\t\t");
 Serial.print(grx);   Serial.print("\t");
 Serial.print(gry);   Serial.print("\t");
 Serial.print(grz);   Serial.print("\t\t");
 Serial.print(rx);   Serial.print("\t");
 Serial.print(ry);   Serial.print("\t");
 Serial.println(rz);

This is the output im getting
2   1.00    61.00   0.06000     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
3   61.00   139.00  0.07800     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
4   139.00  219.00  0.08000     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
5   219.00  300.00  0.08100     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
6   300.00  380.00  0.08000     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
7   380.00  462.00  0.08200     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
8   462.00  543.00  0.08100     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
9   543.00  624.00  0.08100     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
10  624.00  705.00  0.08100     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
11  705.00  788.00  0.08300     0   0   0       0   0   0       nan nan nan

...
41  3223.00 3307.00 0.08400     0   0   0       0   0   0       nan nan nan nan nan nan     nan nan nan
42  3307.00 3392.00 0.08500     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
43  3392.00 3476.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
44  3476.00 3560.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
45  3560.00 3645.00 0.08500     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
46  3645.00 3729.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
47  3729.00 3813.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
48  3813.00 3897.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
49  3897.00 3982.00 0.08500     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
50  3982.00 4066.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
51  4066.00 4150.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
52  4150.00 4234.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
53  4234.00 4319.00 0.08500     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
54  4319.00 4403.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
55  4403.00 4487.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
56  4487.00 4571.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
57  4571.00 4656.00 0.08500     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
58  4656.00 4740.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
59  4740.00 4824.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan

Ever increasing values suggest code which is trying to integrate an acceleration measurement to determine velocity, something that it not realistically workable with a budget sensor.  Your question is insufficiently specified to ask here, as you neglect to include the code generating the output columns, so no one can have any idea beyond guesses as to what they represent.

"After taking a look at the system print i found that the numbers that are written out is the time and not the values of the MPU6050. Why am i getting the zeros and nan for?"

@ChrisStratton I have added the entire output + the print.

@ChrisStratton Chris?

Your data is clearly flawed - look how the values in ax, ay, az turn up in a different position in the next row.  Are you passing the correct type of pointer?  Remove all the rest of the code and just focus on getting valid values for those as a start.  Or maybe you should go back to the original code and figure out why exactly it didn't run.

I think the best choice for you is to read raw data from the sensor using Wire library.

First of all, you have to include the "Wire.h" library:
#include "Wire.h"

Next step is to start the I2C communication by calling the following function in setup()
Wire.begin();

Now that the master joined the I2C bus, all you have to do is to set the power mode of the module by setting the register 0x6B to 0x0. You can use the following function:

int sendCommand(int8_t register_address, int8_t register_value) {
Wire.beginTransmission(mpu_address);
Wire.write(register_address);
Wire.write(register_value);
int statusCommand = Wire.endTransmission(true);
Serial.print("I2C Address: "); Serial.print(mpu_address, HEX);
Serial.print(" Register address: "); Serial.print(register_address, HEX);
Serial.print(" Register value: "); Serial.print(register_value, HEX);
Serial.print(" Status command: "); Serial.println(statusCommand);

return statusCommand;
}

Please note that the default I2C address for the MPU6050 is 0x68. You can use the I2C Scanner to find its address.
To actually set the register 0x6B to 0x0 you have to call the sendCommand like below:
sendCommand(0x6B,0x0);

Request the raw data from the MPU6050. You can check the MPU6050 Register Map for additional information.  Accelerometer can be found from 0x3B to 0x40, temperature from 0x41 and 0x42, and finally, the gyro from 0x43 to 0x48. IMPORTANT!!! Every register's value occupy 1 byte (int8_t), so you have to get the values of two registers (2 bytes) and store them in an int16_t.

Here is the full code to get the angles from the sensor:
#include "Wire.h"

int8_t mpu_address = 0x68;
int sendCommand(int8_t register_address, int8_t register_value) {
  Wire.beginTransmission(mpu_address);
  Wire.write(register_address);
  Wire.write(register_value);
  int statusCommand = Wire.endTransmission(true);
  Serial.print("I2C Address: "); Serial.print(mpu_address, HEX);
  Serial.print(" Register address: "); Serial.print(register_address, HEX);
  Serial.print(" Register value: "); Serial.print(register_value, HEX);
  Serial.print(" Status command: "); Serial.println(statusCommand);

  return statusCommand;
}

void setup() {
  //join the I2C bus
  Wire.begin();
  //start serial communication
  Serial.begin(115200);
  delay(1000);

  /* sendCommand can return 5 possile values:
   * -> 0:success
   * -> 1:data too long to fit in transmit buffer
   * -> 2:received NACK on transmit of address
   * -> 3:received NACK on transmit of data
   * -> 4:other error
   */
  while(sendCommand(0x6B,0x0) != 0){
    delay(1000);
  }

  Serial.println("MPU6050 started");
}

void convertRawDataToAngle(int16_t AcX, int16_t AcY, int16_t AcZ) {
  int minVal = 265; int maxVal = 402;
  int xAng = map(AcX, minVal, maxVal, -90, 90);
  int yAng = map(AcY, minVal, maxVal, -90, 90);
  int zAng = map(AcZ, minVal, maxVal, -90, 90);

  int x = RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
  int y = RAD_TO_DEG * (atan2(-xAng, -zAng) + PI);
  int z = RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);

  Serial.print("X angle: "); Serial.print(x);
  Serial.print(" Y angle: "); Serial.print(y);
  Serial.print(" Z angle: "); Serial.print(z);
}

void readData(int8_t register_address) {

  int bytesReceived = -1;
  int statusCommand = -1;
  do {
    Wire.beginTransmission(mpu_address);
    Wire.write(register_address);
    statusCommand = Wire.endTransmission(false);
    bytesReceived = Wire.requestFrom(mpu_address, 6, true);
    Serial.print("I2C Address: "); Serial.print(mpu_address, HEX);
    Serial.print(" Register address: "); Serial.print(register_address, HEX);
    Serial.print(" Status command: "); Serial.print(statusCommand);
    Serial.print(" Bytes received: "); Serial.println(bytesReceived);
  } while (statusCommand != 0 && bytesReceived != 6);
  //check if MPU6050 sent all the requested data
  //in total 6 bytes, 2 bytes for each axis
  if (Wire.available() == 6) {
    int16_t AcX = Wire.read() << 8 ;
    AcX |= Wire.read();
    int16_t AcY = Wire.read() << 8 ;
    AcY |= Wire.read();
    int16_t AcZ = Wire.read() << 8 ;
    AcZ |= Wire.read();
    convertRawDataToAngle(AcX, AcY, AcZ);
  }
}
void loop() {
  //put your main code here, to run repeatedly:
  readData(0x3B);
  delay(100);
}

In Wire.read() << 8 | Wire.read(), it is unspecified which Wire.read() is executed first. You may get lucky with a particular version of the compiler, but the only safe way of getting the bytes in the right order is to do the reads in two separate statements.

Well, I did it that way because I request 6 bytes of data, starting from register 0x3B. I expect to receive them in the order I requested. Am I right? If not, can you provide me tips how to replicate what you said, to get the bytes in the wrong order?

I cannot, as I likely use a compiler version not too far from yours. My point is that the fact that it does work with the compiler we are using now does not mean the code is correct. The correct version would be AcX = Wire.read() << 8; AcX |= Wire.read();

Oh, I get now what you mean. Thank you for the suggestion. I will update it soon! If there is anything that might go wrong, I am open to fix them. I still have a lot to learn!

The output MPU 6050 does need filtering/processing before you can get any sense from it.  I have used the library "MPU6050_6Axis_MotionApps20.h" with success, it is located here: MPU6050_6Axis_MotionApps20.h
I have written an example here: MPU 6050 for MicroView.

Does your code also get the values?

The library does its magic, and you can get Euler angles simple and reliable (these are orientation angles).  Other measurements such as acceleration are also easy to obtain.

Im getting a ton of errors from the library. Ive added the errors to the code above. Ive been busy thats why it took so long.

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

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


text:
What's the difference between pow and sqrt in this code?
I'm not the best at Arduino so I'm sorry for my "noobiness".
I'm extending some code that I found online to work on the gyroscope that I'm building.
I'm wondering what the difference is between pow and sqrt in this code.
I'm also wondering what the 180/pi is used for. I haven't gotten my mind around this part yet.
arx = (180/3.141592) * atan(ax / pow((ay, 2) + pow(az, 2));

What's the difference here?
ary = (180/3.141592) * atan(ay / sqrt(square(ax, 2) + square(az, 2)));

pow(x, 2)  is the second power, so x² or x*x. sqrt(x) is the square root of x, so $\sqrt x$. A whole circle is 360 degrees or 2π when measuring in radians. So this ratio of 180/3.141592 is used to convert an angle in radians to an angle in degrees.

@Gerben That should be an answer, n'est pas?

@Gerben Do you know why im getting this error?                                                              In function 'void loop()':
error: too few arguments to function 'double pow(double, double)'
GettingValues:41: error: at this point in file
error: too many arguments to function 'double square(double)'
GettingValues:42: error: at this point in file
error: too many arguments to function 'double square(double)'

Your parentheses are wrong. Change pow(( to pow(.

Converting Gerben's comment into an answer:

pow(x, 2) is the second power, in other words:

sqrt(x) is the square root of x, that is:

A whole circle is 360 degrees or 2π when measuring in radians. So this ratio of 180 / 3.141592 is used to convert an angle in radians to an angle in degrees.


text:
PID not working correctly
I'm currently working on a project where I need to use PID to get the correct speed for a motor when it is angled a certain amount.
The problem is that I'm only getting 0.00 and 255.00 as the speed. Nothing in between. The code is supposed to activate when the angle value is more than 1300 and less than -1300. The ax variable is from an MPU6050 sensor.
int16_t ax, ay, az;

double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
double Kp=2, Ki=5, Kd=1;
PID myPID(&Input, &Output, &Setpoint, Kp,Ki,Kd, DIRECT);

void setup() {
  Input = analogRead(ax);
  Setpoint = 100;
  //turn the PID on
  myPID.SetMode(AUTOMATIC);
}

void loop() {
  accelgyro.getAcceleration(&ax, &ay, &az);
  int a=ax+10900;
  //Here I set the used variable to around 0. ax is actually around -10900
  //This is always true, this won't be in the final code. This is just making it work.
  if(1) {
    int val;
    val = map(a, -1300, 1300, 0, 1023);
    Input = val;
    myPID.Compute();
    Serial.println(Output);
  }
}

I suggest adding the symptom to the title as in the rejected edit http://arduino.stackexchange.com/review/suggested-edits/13084  The PID is working as configured, however these configuration parameters of the PID makes it oversensitive to the inputs, resulting in bang-bang operation and overshoot.   This failure mode is distinct from other PID failure modes in the 'Related' PID questions, and with a better title could help a user find or exclude this question and answer from their search.

If the values of 'a' and 'val' aren't used/useful for other purposes, you can control 'ax' directly.  If you want 'ax' controlled to the -10900 value, you can use ax as input and Setpoint as -10900 and avoid the offset, and mapping.  E.g.  PID myPID(&ax, &Setpoint,kP, Ki, Kd, DIRECT);  Setpoint=-10900;

How fast is your system compared to the loop() sampling time?  Does (100-map((ax+10900),-1300,1300,0,1024)) change appreciably during the sub-millisecond loop()?
With kI=5, an error of only 10 will saturate your 0-255 speed output in 26 iterations of loop(), potentially producing the behavior you see.  If you don't have control of your sampling time, the integral error can wind up (or down) to the process limits very quickly.
From https://www.arduino.cc/en/Reference/Map map() only linearly transforms the input data to the output data, but does not constrain() it to those limits.  If ax=-9000, then val would be greater than 1024.   Still, taking the normal working range of ax+10900 to be (-1300,1300) which is then mapped into  (0,1024), the Kp=2 term with a setpoint of 100 would produce a range of (-200,2048) constrained to the default (0,255) limits.
Working backwards from the setpoint of 100, through the 0-1024 map is 0.0975 along the (-1300 to 1300) range, or val = -949, or ax = -11849.  And the kP=2 times the mapping factor of 1024/2600 would change the output by 2*1024/2600=0.79 points for each step difference of ax from -11849.
The http://playground.arduino.cc/Main/MPU-6050 pages says the acceleration registers are 16 bit with high sensitivity, and suggests that 50 points of noise is a small variation.  If the sensor set for 16 bits for +/-2G into ax, then, each step change 60 micro-G.  If that is the source of your ax, then the small variations could easily saturate your control system, making it bang-bang between its output limits with only milli-G variations at the sensor.
Slow down your sampling time, reduce kI, and think of your Kp, Ki, and Kd as conversions of your measured and translated variable ax errors into output space (0-255 speed).
Also, in choosing a sampling time, consider how often you want the PID to make adjustments to the process.

Please respect others by presenting code that is readable. By doing that you may also find obvious errors in your code. Let me clean up the loop() and you will see what I mean.
void loop() {
    int a = ax + 10900;
    if (1) {
      int val;
      val = map(ax, -1300, 1300, 0, 1023);
      Input = val;
      myPID.Compute();
      Serial.println(Output);
    }
  }
}

So what is "int a = ax + 10900"? "ax" is not defined but the other use of it is as an analog pin number "Input = analogRead(ax)". And "a" is not used.
There is a condition that is always true "if (1)" and so on.
Cheers!

That was my fault when putting in the code but i fixed it.

It was supposed to be like it now. ( doesnt work)

Looks like you have much more to fix. How about the format? And the "ax" variable.

The format??? The ax variable is taken from an MPU6050 sensor.

Try to use indentation so that you code is more readable. This will also help you understand where you are going wrong. Here is a good reference on typical C++ style rules. https://google.github.io/styleguide/cppguide.html. Please post more of your code. Right now "ax" is not taken from MPU6050 sensor. That is not in your snippet. How could anybody guess that?

Ive added the code that you asked for.

And i do write out that i get ax from the mpu6050 sensor and that the value of ax is -10900. so the code is quite unnecessary.

So what do you think is the problem?

I believe that the PID is constantly overcompensating.

Because these are maybe too big? double Kp=2, Ki=5, Kd=1;

Where did these numbers come from? Estimation? Example code? Guesstimate?

What happens when output == 255 or output=0?

@Marc - so the code is quite unnecessary... that is quite incorrect... The code is necessary for us to fully understand what it is that is happening. Many times we have seen an OP emphatically stating that his code does "x, y and z" but then the code shows that it is actually doing "a, b and c", i.e., something quite different from what the OP expected and/or stated...


text:
How can I assign a variable to a function output in Arduino?
I'm trying to assign the output of my function (which adjusts a DAC output) to a variable so I can print and display it in my serial monitor. Here's the code
#include <Wire.h>
#include <Adafruit_MCP4725.h>

Adafruit_MCP4725 dac;

int volza;

void setup() {
  Serial.begin(38400);
  Serial.println("Hello!");
  dac.begin(0x60);
}

void loop() {
    volza = dac.setVoltage(1095, 1); // THIS IS THE PROBLEM
    Serial.println(volza);
}

I am receiving an error because of the commented line. I think it's because I am trying to return a value while inside a void loop. How do you fix this?

I know it's because I am trying to return a value while inside a void loop ... how do you know this?

From researching the problem I've come across several threads that mention having a "void" means you cannot have a return value. Please correct me if I'm wrong

that is correct, however that would be the value returned by loop() ... loop() never exits, therefore it is not returning to any caller

I see.. thanks!

The setVoltage method has the following prototype:
void setVoltage( uint16_t output, bool writeEEPROM );

This means it does not return a value.
If you expect to return 1095, why not write:
volza = 1095;
setVoltage(volza, 1);
Serial.println(volza);

Some background information:
Assume you want to have the library a getVoltage method, than this is possible (you have to make a copy in your own project of the file and add the method. However, I'm not sure how easy it is to get the value from the EEPROM. If it is not easy, there is some programming work to do. Another solution is to store the value in memory, but that means some extra bytes from the scarce free SRAM. Also, in theory the content could be changed already (if another MCU would have access to the EEPROM too).

Great, thank you so much for the clarification. The "1095" I have is just a dummy example, I plan on having an analog input actually adjust this value, therefore I was interested in reading it by assigning it to a variable. Would you say I could use an analogRead instead of trying to assign it to a variable?

Probably, however, it depends on the implementation of setVoltage what actually happens.

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


text:
How to debug "No device found on cu.usbserial, An error occurred while uploading the sketch"
I am testing a project on Arduino Nano. I copy-paste the code on the Arduino IDE and click "Upload". I see:
No device found on cu.usbserial-<unique id>
An error occurred while uploading the sketch

The computer sees the board: when I disconnect the board from the USB socket, the list of ports in Tools > Port no longer shows this port.
The error thing happens:

if I press the reset button first, then click "Upload"
if I change the USB cable (I tried 5 different ones, one of which worked a few years ago, the last time I used this same board)
if I use a simple blink code
if I connect to a different USB port
if I upgrade the Arduino IDE to the latest software from arduino.cc .

The Get board info command shows that the computer can read the VID and the PID, but not the serial number or the board type. If I connect an Arduino Uno to the same socket, I can see the serial number and the board type, but I get the same error message (just with a different port ID). Neither boards show signs of degradation.
The Boards Manager shows that the Arduino AVR Boards, which include Arduino Uno and Arduino Nano, are installed.
When I click "Upload", the IDE compiles the program, then the Nano's L LED blinks, then the TX blinks, then a pause, then the L, then the RX, then the L, then the RX, and then the IDE shows the error. So I suspect that the error is not what the IDE says.
Furthermore, the connection between the Arduino and the IDE is working because the Serial Monitor shows the output of the previous program (at 9600 baud).
Some Arduinos can reset by connecting RX to GROUND and uploading code, but this one does not have an RX pin.
How can I debug this error?

then how did you solve the problem?

@Juraj: By chance, I was poking around the menus and found Tools > Board, just above Processor, as I wrote in the answer (which I wrote at the same time as you wrote your first comment).

so you say you didn't have the board selected at all?

It was showing Board: "Arduino Nano", left over from the last time I used it a few years ago. But when I dove into the sub-menus, Arduino Nano did not have a tick on it. Clicking it solved the issue. It may be a bug in the IDE...

I doubt it was the real problem, but ok

The structure of the boards changed from having multiple copies of the same board with different processors to one board with multiple processor options within it. The same goes for bootloader variants for some boards. If your preferences file contained the settings for the old style of boards from before you upgraded the IDE (at some point) then it won't necessarily map those settings across to the new way of doing it - hence you get an error because the settings don't match your board.

@Majenko That sounds plausible. Can you write an answer?

It seems that everything is working as it should and the computer and the board can see each other. The only thing left to do is to select the board type so the IDE knows how to send the code in a way that the board can interpret.
Select Tools > Board > Arduino AVR Boards > Arduino Nano.
If you have an old or non-Arduino board, try the old bootloader in the processor, as in  CH340 Nano avrdude: stk500_getsync() not in sync resp=0xa4 .


text:
Using 4-digit 7-segment display on Arduino Nano
I want to merge two projects: a "Don't touch your face" hat for Nano and a 7-segment 4-digit display for Uno. I tested both independently and they work. I added an RGB LED to the first, so I use 6 digital pins: 2 for the ultrasonic sensor, 1 for the buzzer, and 3 the RGB LED.
The Nano project takes 6 digital pins and no analog pins, leaving 4 digital pins and 8 analog pins. The Arduino Uno takes 12 digital pins. So I suppose that it's possible to replace the digital pins of the Uno with analog ones at the right voltage.
Even without the Nano project claiming 6 digital pins, the Nano only has 11 digital pins (D2-D12), not enough for a 7-segment 4-digit display. But I couldn't find a tutorial online on how to do so.
Is it possible to use a 7-segment 4-digit display on Arduino Nano?

The "Don't Touch your face hat"  uses only three I/O pins (D10-D12), and the 7-segment sketch appears to use 12 (D2-D13).  A0-A7 are the same exact pins as D14-D21, so you have plenty of digital I/O.  Change the hat sketch to use D14-D16 instead of D10-12, test again with the two separate sketches with all the hardware, then try to combine the code and post your code attempt.

Uno and Nano have nearly the same pinout. Both have D0-D13 and A0-A5 (all can work as digital pins as the analog function of A0-A5 is just additional functionality). Excluding the Serial pins we have D2-D13 and A0-A5, so 12+6=18 pins. I cannot see the hat project (since I don't have an account there), but if we take the 3 pins that DaveX mentioned and the 12 for the 7 segment display we get 15 pins. You have enough pins.

@chrisl I can't find D0, D1 and D13 on my nano, which are they? Yes, if A0-A5 can serve as digital pins, then it's simply a replacement of pin numbers. The Uno code compiles and uploads to Nano, so I'll try this simple replacement tomorrow.

D0 and D1 are marked as TX and RX since this is connected to hardware serial. D13 is on the same side with A0, right at one end of the header next to the 3.3V pin.

You can try to use a shift register.

@DaveX Your comment works perfectly. I shifted the previous pins to D2-D7 and moved the 4-digit 7-segment pins to D8-D12 and A0-A6. I still have two pins left: D13 and A7. I am unable to use A7 with #define D1 21, but the code works on pin D12 (with #define D1 12). Could you confirm that A7 should work just as well? And could you write an answer and I'll edit it with my code?

There are chips such as the MAX7219 designed to control 7 segment displays from devices such as an Arduino, there are also some well-established libraries such as LEDCONTROL to drive them. In fact the MAX7219 doesn't have to drive 7 seg displays, you can use it to drive any collection of up to 64 LEDs, I use one for a simple illuminated Christmas tree. You'll need some basic soldering skills to connect the chip to an Arduino but it's very simple.
E.g. see: https://www.maximintegrated.com/en/products/power/display-power-control/MAX7219.html


text:
I2C freeze on master
On my first big Arduino-project I made a game using the following Arduino's and the I2C-protocol:

1x Mega as master
4x Mega as slave
2x Uno as slave

The Arduino's controll a physical game where the players have to push 96 different buttons, according to how certain lights are controlled by relays. The two uno's are used for a MP3-shield and a timer.
My code might not be perfect at all, but I'm happy with how it works. The only problem is that sometimes my master freezes. This is on different moments, but always when the master processes multiple I2C-communications. Sometimes it completes the whole game without problem, but other times it freezes at different moments.
I used a 1ms delay at the end of the loop on all arduino's, because it looked like this might make the connection most stable. The I2C-cables are up to about 1m long, I can't make them shorter. I added 5K1-resesistors from the 5v-line of the master-Mega on the SDA and SCL line. Alle buttons and relays in the game are connected to seperate power sources and don't use the internal pullups.
The code is quite long, so I uploaded the code of the master and the code of 1 mega slave to Github: https://github.com/mrcbrgrs/Arduino-mega-buttons-game. Some comments might be in Dutch, sorry for that.
Who has an idea how I can stop the Mega from freezing?

Can you show us your code?

Things to try: 1) reduce the pullup resistors, see http://www.ti.com/lit/an/slva689/slva689.pdf, 2) reduce the i2c clock frequency, default is 100 khz, see Wire.setclock(), https://www.arduino.cc/en/Reference/WireSetClock

@MikaelPatel 1) I'll try. I already used without external pullup resistors, but was not a difference compared to the the 5K1 setup. 2) I tryed it on the master, but made it freeze very fast every time. Do i have to setclock on all slaves too?

@chrisl Link to code is in post now, was too long to add in post directly.

Use 1kΩ pullup resistors. 5k1 is too high even when using short PCB traces.

I2C is not designed to run over cables without proper "long distance" I2C drivers.

You askes the same question here: https://forum.arduino.cc/index.php?topic=628322.0 Is that 6 times 1 meter for a total of 6 meters? That is not possible, the i2c bus can be 50cm long, but that depends on the type of wires or cable. If you can not make them shorter, you might have to drop the i2c bus and think of something else.

@Majenko Thanks, I will use lower pullup resistors.

@Jot It's a bit less, think up to 4m in total. But even when I make all the cables shorter, the problems are about the same. So I'm not sure if the length is the problem.

Try a test with 50cm total length or shorter. If lowering the clock speed does not help, then there might be a ground problem. You need a GND signal that matches SDA and SCL and does not carry high currents of a motor. Only the Master sets the speed of the SCL clock, the Slaves just follow.

@Jot Thanks again for your help. A short total length had same problem, but also is not an option for the end product. The GND is directly from master-arduino (9v adapter). The master arduino does not power any elements. The clock speed change on the master only resulted on a crash almost every time the master needed to communicate, while without changes it only happens once in a while.

That is a serious problem. I have had multiple arduino slaves with a mega as a master without any problems. The pullup is 5 * 10k and 7 * 30k and 5k1, that is almost as low as 1k, that is too low. Without your 5k1 there is still too much pullup. At least remove the 5k1 resistors. On the arduino.cc forum they wrote about removing the Serial.println from the interrupt functions. Did you do that?

@Jot The setup is in a different workplace, so I'm collecting all info before driving there. Will try the tips soon and let know. Will also get some PCA9615 as I2C bus extenders to use as alternative.


text:
EEPROM page rotates while writing to it
The following code intends to read from serial port and write the data byte by byte to a 24LC01B EEPROM.
// 24LC01B PINS
// Pin 1, A0: float
// Pin 2, A1: float
// Pin 3, A2: float
// Pin 4, VSS: GND
// Pin 5, SDA: Arduino A4
// Pin 6, SCL: Arduino A5
// Pin 7, WP: Write/Protect = GND
// Pin 8, VCC: +5

#include <Arduino.h>
#include <Wire.h>

// I2C Bus address of 24LC256 EEPROM;
// if more than one eeprom, they will have different addresses (h/w configured);
#define EEPROM_ADDR 0x50
byte m_addr = 0;

#define MAX_ADDRESS 128

byte eeprom_write(byte address, byte *data, byte len)
{
    byte r = 0;
    for(byte i=0; i<len; )
    {
        Wire.beginTransmission(EEPROM_ADDR | m_addr);
        Wire.write(address + i);
        byte l = len > 8 ? 8 : l;
        Wire.write(data+i, l);
        r |= Wire.endTransmission();
        delay(3);
        i += l;
    }
    return r;
}

byte eeprom_read(byte address, byte *data, byte len)
{
    Wire.beginTransmission(EEPROM_ADDR | m_addr);
    Wire.write(address);
    byte tr = Wire.endTransmission();
    if(tr)
        return tr;

    Wire.requestFrom((uint8_t)(EEPROM_ADDR | m_addr), len);
    byte avail = Wire.available();
    if(avail < len)
        return 0xFF;

    for(int i=0; i < len; i++)
    {
        // store data in raw bcd format
        data[i] = Wire.read();
    }
    return 0;
}

void setup()
{
    Wire.begin();
    Serial.begin(9600);
    delay(500);
    Serial.println("Type something to store in EEPROM");
}

byte i = 0;

void loop()
{
    if(Serial.available())
    {
        byte data = Serial.read();
        int rc = eeprom_write(i, &data, 1);
        if(rc==0)
        {
            Serial.print("EEPROM[0x");
            Serial.print(i, HEX);
            Serial.print("] = 0x");
            Serial.print(data, HEX);
            Serial.print(" (");
            Serial.print((char)data);
            Serial.print(")");
            Serial.println();

            Serial.println("Reading from EEPROM:");
            for(byte j=0;j<MAX_ADDRESS;j++)
            {
                if(byte rc=eeprom_read(j, &data, 1))
                {
                    Serial.print("Error in reading from EEPROM (rc=0x");
                    Serial.print(rc, HEX);
                    Serial.println(")");
                }
                else
                {
                    Serial.print(data, HEX);
                    Serial.print(' ');
                    if((j + 1) % 8 == 0 && j != MAX_ADDRESS - 1)
                        Serial.print("| ");
                }
            }
            Serial.println("");
        }
        else
        {
            Serial.println("Write error.");
        }
        i++;
    }
}

Every time I write one byte to the EEPROM, I read back the data on it.
The result is a bit disappointing for me. I understand that 24LC01B has a page size of 8 bytes. But, it does not make sense to me why the bytes withing the page rotate right every time I write into it
Type something to store in EEPROM
EEPROM[0x0] = 0x61 (a)
Reading from EEPROM:
61 4 4F 0 80 0 80 4 | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0x1] = 0x62 (b)
Reading from EEPROM:
4 62 4 4F 0 80 0 80 | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0x2] = 0x63 (c)
Reading from EEPROM:
80 4 63 4 4F 0 80 0 | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0x3] = 0x64 (d)
Reading from EEPROM:
0 80 4 64 4 4F 0 80 | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0x4] = 0x65 (e)
Reading from EEPROM:
80 0 80 4 65 4 4F 0 | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0x5] = 0x66 (f)
Reading from EEPROM:
0 80 0 80 4 66 4 4F | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0x6] = 0x67 (g)
Reading from EEPROM:
4F 0 80 0 80 4 67 4 | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0x7] = 0x68 (h)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 4 45 0 80 4 3 0 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0x8] = 0x69 (i)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 69 4 4F 0 80 0 80 4 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0x9] = 0x6A (j)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 4 6A 4 4F 0 80 0 80 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0xA] = 0x6B (k)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 80 4 6B 4 4F 0 80 0 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0xB] = 0x6C (l)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 0 80 4 6C 4 4F 0 80 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0xC] = 0x6D (m)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 80 0 80 4 6D 4 4F 0 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0xD] = 0x6E (n)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 0 80 0 80 4 6E 4 4F | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0xE] = 0x6F (o)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 4F 0 80 0 80 4 6F 4 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0xF] = 0x70 (p)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 4 4F 0 80 0 80 4 70 | 3 F6 0 5B 4 38 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0x10] = 0x71 (q)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 4 4F 0 80 0 80 4 70 | 71 4 4F 0 80 0 80 4 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF
EEPROM[0x11] = 0x72 (r)
Reading from EEPROM:
4 4F 0 80 0 80 4 68 | 4 4F 0 80 0 80 4 70 | 4 72 4 4F 0 80 0 80 | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF | FF FF FF FF FF FF FF FF

Reading the code and serial EEPROM specifications takes a lot of time.  Try this and if it works I'll provide a more complete answer:  Write all 8 bytes in a page.

@st2000, I actually have tried 8 bytes data writing and it worked fine. No problem with that. The problem raises when you write less than a page (8 bytes). Is writing minimum as much as size of the page anything standard requirements for EEPROMs? I have not seen something like that in the datasheets.

It doesn't matter if you write 1 byte or a complete page. the only import thing is, you do not cross a page border while writing.

The global variable data is a byte variable. But in the read and write function you use it as an byte array (data[i] or 'data +i').
That's not OK, but also not an error in the case you use length 1 ;-).
In your read function you performed a so called random read action that must be terminated by a STOP signal on the I2C bus. This can be forced by:
// ...

for(int i=0; i < len; i++)
{
    // store data in raw bcd format
    data[i] = Wire.read();
}

Wire.endTransmission(true);

return 0;

// ...

It's just a guess.
Writing single bytes must also be ended by a STOP condition but you used
r |= Wire.endTransmission();

that does not send a STOP signal.
Again you can force it with:
r |= Wire.endTransmission( true );

I'm not a Wire lib wizard, so I had read the Arduino documentation. Hopefully I understood it correctly.

Your problem is
byte l = len > 8 ? 8 : l;
in the eeprom_write() function.
You wrote byte NumberOfBytes = len > 8 ? 8 : NumberOfBytes; and that will leads to an undefined behavior.
And for the future, if you want to write more than 1 Byte it is not important how many byte you write in a block but that the addresses are all located on the same eeprom page.
((address / pagesize) == ((address + length) / pagesize) must be true


text:
TFT Screen with Arduino UNO does not display as expected
I have a 3.5" TFT LCD communicating in parallel connected to Arduino UNO.
I expect it draws a white circle on a black background but all it does is to show a white screen.
How to fix this?
main.c
// sudo apt-get install avr-libc gcc-avr binutils-avr gdb-avr avrdude
// avr-gcc -mmcu=atmega328p -Wall -Os -o main.elf main.c
// avr-objcopy -O ihex main.elf main.hex
// avrdude -c arduino -p m328p -P /dev/ttyUSB0 -b 115200 -U flash:w:main.hex

#define DDRA (*(volatile uint8_t*)0x24)
#define DDRB (*(volatile uint8_t*)0x25)
#define DDRC (*(volatile uint8_t*)0x26)
#define DDRD (*(volatile uint8_t*)0x27)

#define PORTA *((volatile uint8_t*)0x3B)
#define PORTB *((volatile uint8_t*)0x38)
#define PORTC *((volatile uint8_t*)0x35)
#define PORTD *((volatile uint8_t*)0x32)

typedef unsigned char uint8_t;
typedef unsigned int uint16_t;
typedef unsigned long uint32_t;

typedef signed char int8_t;
typedef signed int int16_t;
typedef signed long int32_t;

#define F_CPU 16000000UL

#define LCD_RD A0
#define LCD_WR A1
#define LCD_RS A2
#define LCD_CS A3
#define LCD_RST A4

#define LCD_WIDTH 320
#define LCD_HEIGHT 480

#define LCD_DATA_PORT PORTD
#define LCD_DATA_DDR DDRD

#define LCD_RD_PORT PORTC
#define LCD_RD_DDR DDRC
#define LCD_RD_PIN 0

#define LCD_WR_PORT PORTC
#define LCD_WR_DDR DDRC
#define LCD_WR_PIN 1

#define LCD_RS_PORT PORTC
#define LCD_RS_DDR DDRC
#define LCD_RS_PIN 2

#define LCD_CS_PORT PORTC
#define LCD_CS_DDR DDRC
#define LCD_CS_PIN 3

#define LCD_RST_PORT PORTC
#define LCD_RST_DDR DDRC
#define LCD_RST_PIN 4

#define LCD_DATA_MASK 0b11111111

void delay_ms(uint16_t ms) {
    // calculate the number of cycles needed for the given number of milliseconds
    uint16_t cycles = F_CPU / 1000UL * ms / 4;
    // use a volatile variable to prevent the compiler from optimizing the loop away
    volatile uint16_t count = cycles;
    // loop until the counter reaches zero
    while (count > 0) {
        count--;
    }
}

void writeCommand(uint8_t command) {
    LCD_RS_PORT &= ~(1 << LCD_RS_PIN); // set RS pin to low for command
    LCD_CS_PORT &= ~(1 << LCD_CS_PIN); // enable chip select
    LCD_WR_PORT &= ~(1 << LCD_WR_PIN); // enable write
    LCD_DATA_PORT = command; // write the command to the data port
    asm volatile("nop"); // wait for stability
    LCD_WR_PORT |= (1 << LCD_WR_PIN); // disable write
    LCD_CS_PORT |= (1 << LCD_CS_PIN); // disable chip select
}

void writeData(uint8_t data) {
    LCD_RS_PORT |= (1 << LCD_RS_PIN); // set RS pin to high for data
    LCD_CS_PORT &= ~(1 << LCD_CS_PIN); // enable chip select
    LCD_WR_PORT &= ~(1 << LCD_WR_PIN); // enable write
    LCD_DATA_PORT = data; // write the data to the data port
    asm volatile("nop"); // wait for stability
    LCD_WR_PORT |= (1 << LCD_WR_PIN); // disable write
    LCD_CS_PORT |= (1 << LCD_CS_PIN); // disable chip select
}

void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
    writeCommand(0x2A);
    writeData(x0 >> 8);
    writeData(x0);
    writeData(x1 >> 8);
    writeData(x1);

    writeCommand(0x2B);
    writeData(y0 >> 8);
    writeData(y0);
    writeData(y1 >> 8);
    writeData(y1);

    writeCommand(0x2C);
}

void fillScreen(uint16_t color) {
    setAddrWindow(0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1);
    for (uint32_t i = 0; i < (uint32_t)LCD_WIDTH * LCD_HEIGHT; i++) {
        writeData(color >> 8);
        writeData(color);
    }
}

void initILI9488() {
    LCD_DATA_DDR = LCD_DATA_MASK;
    LCD_RD_DDR |= (1 << LCD_RD_PIN);
    LCD_WR_DDR |= (1 << LCD_WR_PIN);
    LCD_RS_DDR |= (1 << LCD_RS_PIN);
    LCD_CS_DDR |= (1 << LCD_CS_PIN);
    LCD_RST_DDR |= (1 << LCD_RST_PIN);

    LCD_RD_PORT |= (1 << LCD_RD_PIN);
    LCD_WR_PORT |= (1 << LCD_WR_PIN);
    LCD_RS_PORT |= (1 << LCD_RS_PIN);
    LCD_CS_PORT |= (1 << LCD_CS_PIN);
    LCD_RST_PORT |= (1 << LCD_RST_PIN);
    delay_ms(100);

    writeCommand(0x01); // Software reset
    delay_ms(100);

    writeCommand(0x11); // Sleep out
    delay_ms(100);

    writeCommand(0x3A); // Pixel format set
    writeData(0x55); // 16-bit color

    writeCommand(0x36); // Memory access control
    writeData(0x48); // BGR, horizontal flip

    writeCommand(0x2A); // Column address set
    writeData(0x00);
    writeData(0x00);
    writeData(0x01);
    writeData(0x3F);

    writeCommand(0x2B); // Page address set
    writeData(0x00);
    writeData(0x00);
    writeData(0x01);
    writeData(0xDF);

    writeCommand(0xB0); // Power control
    writeData(0x00);
    writeData(0x1B);
    writeData(0x14);

    writeCommand(0xB1); // Vcom control
    writeData(0x08);
    writeData(0x08);
    writeData(0x08);

    writeCommand(0xB4); // Display inversion control
    writeData(0x07);

    writeData(0x01);
    writeData(0xE0);

    writeCommand(0xC0); // Power control 1
    writeData(0x10);
    writeData(0x10);

    writeCommand(0xC1); // Power control 2
    writeData(0x41);

    writeCommand(0xC5); // VCOM control
    writeData(0x00);
    writeData(0x18);

    writeCommand(0xD0); // Power control 3
    writeData(0x07);
    writeData(0x07);

    writeCommand(0xD1); // Power control 4
    writeData(0x00);
    writeData(0x0E);

    writeCommand(0xD2); // Power control 5
    writeData(0x01);
    writeData(0x02);

    writeCommand(0xE9); // Set image function
    writeData(0x01);

    writeCommand(0x13); // Normal display mode on
    writeCommand(0x29); // Display on
}

#define PI 3.14159265

void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color) {
  int16_t x = 0, y = r;
  int16_t d = 3 - 2 * r;

  while (x <= y) {
    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    if (d < 0) {
        d += 4 * x + 6;
    } else {
        d += 4 * (x - y) + 10;
        y--;
    }
    x++;

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    setAddrWindow(x0 - x, y0 - y, x0 + x, y0 + y);

    if (x != y) {
        setAddrWindow(x0 - y, y0 - x, x0 + y, y0 + x);
    }
  }
}

int main() {
    initILI9488();
    while(1)
    {
        fillScreen(0x0000); // Clear screen with black color
        drawCircle(LCD_WIDTH / 2, LCD_HEIGHT / 2, 50, 0xFFFF); // Draw white circle at the center of the screen
        delay_ms(5000); // Wait for 5 seconds
    }
    return 0;
}

Connections:
ILI9488 VCC <----> 3.3V
ILI9488 GND <----> GND
ILI9488 SD_SS <----> Arduino pin 10
ILI9488 SD_DI <----> Arduino pin 11
ILI9488 SD_DO <----> Arduino pin 12
ILI9488 SD_SCK <----> Arduino pin 13
ILI9488 RESET <----> e.g., pin 5
ILI9488 D0 <----> Arduino pin 8
ILI9488 D1 <----> Arduino pin 9
ILI9488 D2 <----> Arduino pin 2
ILI9488 D3 <----> Arduino pin 3
ILI9488 D4 <----> Arduino pin 4
ILI9488 D5 <----> Arduino pin 5
ILI9488 D6 <----> Arduino pin 6
ILI9488 D7 <----> Arduino pin 7
ILI9488 LCD_RD <----> Arduino pin A0
ILI9488 LCD_WR <----> Arduino pin A1
ILI9488 LCD_RS <----> Arduino pin A2
ILI9488 LCD_CS <----> Arduino pin A3
ILI9488 LCD_RST <----> Arduino pin A4

Photos:

Which development environment are you using and did you get any compiler warnings, say duplicate definitions etc. ?

I use linux avr-gcc with no error/warning. The commands I used are the first few lines of the comment.

It may not help you much but for that board and screen I would have used the Arduino development environment and the MCUFRIEND_kbv library.

@6v6gt, is it serial or parallel?

This https://github.com/prenticedavid/MCUFRIEND_kbv appears to support screens based on the ILI9488 controller and some controllers with an 8bit parallel interface so you may be lucky.

@6v6gt, As far as I understand SPI means the communication is serial. Are you talking about any particular example?

Yes. SPI is serial and is used at least for the SD card reader on that board and possibly any touch screen controller (although your screen does not appear to support touch control). The display controller appears to have a parallel interface. Your screen picture appears similar to one appearing in this thread: https://forum.arduino.cc/t/3-5-tft-lcd-from-mcufriend-for-arduino-uno-320x480-ili9327/339132 . I assumed from your code that you had already identified the controller type as ILI9488. Did you get this information from the supplier?

@6v6gt, tried that library but it has issues. I have this problem. fatal error: ADA_GFX_kbv.h: No such file or directory.

It says this explicitly: ADA_GFX_kbv.h only gets used by non-Arduino projects. e.g. MBED or Keil. You are not using the Arduino development environment or are you now ? You can find that file here: https://github.com/prenticedavid/MCUFRIEND_kbv/tree/master/extras/unused. The author of that repository is very active in the display section of the Arduino.cc  forum so you may get more specific help there. I can't contribute much more here.


text:
LED strip brightness decreases when using multiple strips
Newbie question here.
I have bought a 5V, 40A power supply to externally power up some LED strips (WS2812B). The Arduino Nano is powered by a standard USB wall charger (5V).
So far I have tested with 4 LED strips (each of about 25 LED's). Each of the strips is connected to an individual data pin on the Arduino in addition to the power supply (5V and ground).
So, to the problem. For each LED strip that gets powered it seems that the brightness of the LED's decreases. Using for example "white color", all the LED's shows a "yellow"-ish color when all the LED strips are powered. If only one or two is powered it looks fine.
The Arduino by the way shares the same ground as the power supply.
What could the cause to this issue be? The power supple should be more than sufficient for the task. Is it the data pins that can't handle it?
Thanks for any help!
EDIT:
I more detail, each LED strip has 3 pins (1 for 5V, 1 for data input, and 1 for ground). Each for the LED strips 5V pin are connected to the + rail on a breadboard where the power supplies + is also connected. The same goes for the ground pin of the LED strips (they are connected to a ground rail on the same breadboard where also the ground of the power supply is connected).
The data pin on the LED strips are connected to 4 (when all are connected) different data pins on the Arduino Nano (A1,A2,A3 and A4).
The ground pin on the Arduino Nano is connected to the same breadboard ground rail as the rest. When I didn't do this the LED's had weird behaviour.
The wires going from the LED strips into the breadboard are standard 24 AWG stranded wires (each of about 50 - 80 cm in length).
Power supply used is "AC 110V-220V TO DC 5V 40A" from ebay.
https://www.ebay.com/itm/AC-110V-220V-TO-DC-5V-12V-24V-Switch-Power-Supply-Driver-Adapter-LED-Strip-Light/152134115704
LED strips that are used "5M WS2812B 5050 RGB, 150LEDS ip65 Waterproof"
https://www.ebay.com/itm/5M-WS2812B-Strip-LED-Lights-5050-RGB-30-60-LED-M-IC-Individual-Addressable-DC5V/113117301639?

have you done basic investigation of voltage levels?

@jsotola: I have checked the power supply and it provided 5.00 - 5.02V when I checked.
Measured in the circuit itself now, and it actually seems that it drops from 5V to everything between 4.44 - 2.3 based on how many strips that are activated.
I was expecting the power supply to hold based on the specification.

How is everything connected? And do you use cables/wires that are thick enough to conduct the needed current?

As chrisl says, you need to explain your setup in more detail. Are you connecting the LED strips' power through the Arduino? If so, don't do that. You should use a separate, heavy-gauge wire for the 5V lead for your LED strips (and another heavy gauge wire for the ground.) What's the max current draw from one of your LED strips? What's the total power from the full number of strips you are planning to use?

connect multiple wires in parallel to one of the strips .... is it brighter than the others?

I found a 144 WS2812B LED strip on Amazon that draws 20A just for 1 strip. Your 40A power supply would only be able to power 2 of those without getting overloaded.

@chrisl: Thank you for your reply. The question has been updated. Right when I updated the answer I started thinking that the power and ground of the power supply is in fact using the same wire type as everything else. Could that be the problem (24 AWG stranded wire)?

I don't think a breadboard can handle that much current. Also, try measuring the voltage at the power supply. If it can't handle that much current the voltage will drop a bit, which is easy to measure.

Still a circuit schema would come in handy.

When the voltage drops at the circuit, but not on the power supply, the voltage is lost on the way between them (for example in undersized wires and connections, like the breadboard)

As @Gerben said, definitely do not use breadboard for distributing power.

40 amps is a LOT of current.
24 AWG wire can't handle anywhere near 20A of current, nevermind 40A. (After a little googling, it looks like 24 AWG wire is limited to about 3.5A.)
Think about it. In the US, 15 amp branch circuits require 14 AWG wire. 20 amp circuits require 12 AWG wire. It looks like 40 amps requires 8 AWG, from the googling I did. (Voltage doesn't really matter when considering current carrying capacity.) So if you want to drive 40 amps, you need 8-gauge wire on both the +5 leg and the ground leg to your LED strip.
As I said in my comment, I found some 144 WS2812B LED strips on Amazon that draw 20A just for one strip. You say your strips have 150 WS2812B LEDs on them. Assuming it's 150 vs 144 of the same LEDS, you're going to need almost 21 amps per strip, so 2 strips will slightly exceed the 40A capacity of your power supply, and VASTLY exceed the current handling ability of your wiring. As a general rule you should have a power supply that offers a little MORE current that your max needs, never less.(When a power supply reaches its current limits its voltage may start to droop, or it may be slower to adjust to rapid changes in load.)
In addition, You're gonna need BIG, THICK 5V and ground wires to feed your LED strips, and you should wire the LED stips in parallel. (I suggest 8 AWG wires for 40A. Those are HUGE, but that's what you need for that much current.) You should not connect either the +5V supply or the ground wires through a breadboard.

Thanks for your answer. Removed the breadboarded and replaced it with wago instead. In addition switched the 24 AWG to some thicker wires from the power supply to the wago and LED strips. Now it seems to work perfect!

What is "wago"?

A type of wire connector:
https://www.ebay.com/itm/3-50pcs-Spring-Lever-Push-Fit-Reusable-Cable-2-3-5-Way-Wire-Connector-For-Wago/172570569841


text:
Different voltage sources across Vin and DC jack
So I understand that the USB VBUS circuitry turns off provided there is a high enough vin voltage using the PFET and comparator.
I can see that the DC jack is connected to the Vin pin via a diode.
However, what is to stop someone from plugging a voltage source across the Vin and at the same time putting across a voltage on the DC jack.
If I incorrectly plugged in a voltage source of a low voltage like a coin cell battery across the VIN pin and also powered the device using the 9 V DC jack, wouldn't that then send current through the VIN pin and back to the coin cell battery?
Is that what would happen in this instance? And if so then shouldn't there be a design feature to prevent users from damaging it like that? Fool/fail safe?

Vaguely related Does USB Host always supply power on VBUS?. Might be interesting.

wouldnt that then send current through the Vin pin and back to the coin cell battery? Is that what would happen in this instance?

Yep, that's right.

shouldn't there be a design feature to prevent users from damaging it like that? Fool/fail safe?

No. VIN can also be VOUT. You can use it to power other things that want a higher voltage.


text:
How to get PPM value from MQ-3?
I tried to build project to detect alcohol with Arduino Uno and an MQ-3 Alcohol sensor.
I already have the R0 value, but I faced problem here: I don't know how to convert it to PPM or BAC. I already tried some code from tutorial for convert it to BAC but when I gave the sensor alcohol the code gives me a value of 0.00, and I don't know why.
Here is the code to find R0 value:
void setup()
{
   Serial.begin(9600);
}

void loop()
{
    float sensor_volt;
    float RS; //  Get the value of RS via in a clear air
    float R0;  // Get the value of R0 via in Alcohol
    float sensorValue;

    for(int i = 0 ; i < 100 ; i++)
    {
        sensorValue = sensorValue + analogRead(A0);
    }

    sensorValue = sensorValue/100.0;     //get average of reading
    sensor_volt = sensorValue/1024*5.0;
    RS = (5.0-sensor_volt)/sensor_volt; //
    R0 = RS/60.0; // 60 is found using interpolation
    Serial.print("R0 = ");
    Serial.println(R0);
    delay(1000);
}

Here is the code to determine BAC:
float R0= 0.28;
void setup() {
  Serial.begin(9600);
}

void loop() {
  float sensor_volt;
    float RS_gas; // Get value of RS in a GAS
    float ratio; // Get ratio RS_GAS/RS_air
    float BAC;
    int sensorValue = analogRead(A0);
    sensor_volt=(float)sensorValue/1024*5.0;
    RS_gas = (5.0-sensor_volt)/sensor_volt; // omit *RL

   /*-Replace the name "R0" with the value of R0 in the demo of First Test -*/
    ratio = RS_gas/R0;  // ratio = RS/R0
    float a = pow(ratio, 2);
    float b = ratio/10;
    BAC = (0.1896*a) - (8.6178*b) + 1.0792 ;  //BAC in mg/L
    Serial.print("BAC = ");
    Serial.println(BAC*0.0001);  //convert to g/dL
    Serial.print("\n\n");
    delay(1000);
}

I would to know what's wrong with the code, and if you know how to convert the R0 values to PPM, please tell me.

figure 5 in the datasheet shows the relation between the output voltage and PPM value   .... https://cdn.sparkfun.com/datasheets/Sensors/Biometric/MQ-3%20ver1.3%20-%20Manual.pdf ........... you have to use a lookup table to convert the value

A series of if() statements and some simple division should be able to provide you with your PPM results.
From the datasheet, Alcohol Gas Sensor（Model：MQ-3), figure 5 shows the sensitivity curve:

It can be seen here

that there are three regions that the curve can be broken into:

The relationship is linearly proportional between 2.25 V and 3.25 V
Between 3.25 V and 3.8 V there is a curve
The relationship is linearly proportional between 3.8 V to 4.25 V

The slope of the straight line regions described in points 1 and 3 can be represented by the use of a constant and the PPM value by a simple division of the voltage by the constant.
The curve from the second part could be:

approximated by a straight line (thus, once again, using a constant), for simplicity, or;
more accurately, using a lookup table.

Using a straight line approximation for the curve (shown in lurid green), the graph becomes:

To determine the constant for the three lines simply take two points on each line and use:

(y2 - y1) / (x2 - x1)

So for region one, assuming (by approximation, 3 V corresponds to 100 ppm and 2.5 V corresponds to 85 ppm (my eye sight may be slightly off here), the slope is
(3 - 2.5)/(100-80) = 0.5/20 = 0.025

You can calculate the constants for regions two and three in a similar manner (if using a straight line approximation for region two).
Therefore the code would be alomg the lines of
const double kRegionOne = 0.025;   // region one constant
const double kRegionTwo = ???;     // region two constant
const double kRegionThree = ???;   // region three constant

int ppm;                           // ppm result

/*
 * your code here
 * ...
 */

if ((sensor_volt < 3.25) && (sensor_volt >= 2.25)) {
  ppm = sensor_volt/kRegionOne;    // we are in region 1
} else if ((sensor_volt < 3.8) && (sensor_volt >= 3.25)) {
  ppm = sensor_volt/kRegionTwo;    // we are in region 2
} else if (sensor_volt >= 3.8) {
  ppm = sensor_volt/kRegionThree;  // we are in region 3
}

If you wish to be more accurate then use a lookup table for region two, as jsotola states in their comment.


text:
How do I change the default LED pin for displaying uploading
I made a board for my project based on Arduino Pro Mini. The problem is, that I had to put the LED on pin 4 instead of pin 13.
What setting do I have to change to make pin 4 the default one? Or do I have to write my own Board Library?

The blinking while uploading makes the bootloader. Arduino Mini uses Optiboot. The source codes are on GitHub. You would need to change the pin in pin_defs.h and make the bootloader. Then flash it to the 328p with a programmer over ICSP.
Details what to change are in Greenonline's answer.

Following on from Juraj's answer:

The blinking while uploading makes the bootloader. Arduino Mini uses
  Optiboot. The source codes are on GitHub. You would need to
  change the pin in pin_defs.h and make the bootloader. Then flash it to
  the 328p with a programmer over ICSP.

The line that you need to change in pin_defs.h is line number 27:
#define LED B5

As you can see it is currently set to B5. This is the fifth bit in port B which corresponds to pin 13
Pin 4 corresponds to PORTD bit 4, so the line would become
#define LED D4

The Arduino digital pins are connected to three different banks of 8 bits, known as ports (PORTD, PORTB and PORTC`). To see their relation, refer to this table from Arduino Playground - Pins

I copied my answer as intro into this answer

Ok, thanks. I'm not sure it was necessary, unless you planned on deleting your answer. However, I've added a link back to yours to reference the quote, and it makes a bit more sense that way. Thanks again :-).


text:
Arduino network with minimum wiring
For a parking management system I am going to create an Arduino network.
An Arduino with an ultrasonic sensor will be placed above each parking space. If car is parked at specific location Arduino will inform master (PC) and also turn RED light ON.
I am not sure how I can make network with minimum wiring. I think RS485 will be suitable for this purpose.
There will be almost 200 Arduinos in a network. I have following questions in mind:

Should I go for RS485 protocol or something else?
Can RS485 support 200 devices as there will be only short communication (i.e device ID and parking status)?
I am planning to lay CAT6 cable. Two pairs will be used for power transmission and two pairs will be available for communication.

Where is the question in the third point?

Cabling detail is provided so that if someone have better communication method over 4 wires, I can go with it easily

This sounds, to me, like a job for CAN.  It's the current de-facto standard for industrial inter-MCU cabled connections. It's used, not only in automobiles, but also to control elevators and almost all other modern industrial distributed applications.
Note that CAN is designed to only support up to 30 nodes, so you would need to split your network into sections and have groups of nodes amalgamated together into a single sub-network.  For 200 nodes you may want 10 subnetworks - that is, 20 nodes connected together to one super-node, which is then connected to the "backbone" CAN bus.
However, CAN can be run at lower baud rates than normal, and that increases the number of nodes you can have on any one network segment. It potentially (bus capacitance permitting) support thousands of nodes.
Another option is to use CAN to connect multiple "master" nodes together into a backbone, and then those "master" nodes connect to a number of sub-nodes using LIN (which is cheaper to implement than CAN).

LIN can support a maximum of 15 nodes (plus one master node) per network, so you can get a theoretical maximum of 29*15 (assuming 1 CAN node is the connection to the PC), or 435 nodes.
You could also use RS-485, but that is also limited to around 30 "unit loads", and the number of nodes you could put on one segment is dependent on the "load" each node imposes. In practical terms it's rare to go over 30-40 nodes on a single segment, and grouping nodes together into sub-networks (as above with CAN/LIN) would be needed. So you may as well use the current standard for this kind of communication, and use CAN/LIN.

Note that whereas the limit on LIN nodes is a hard one, CAN will work fine with a ridiculously high number of nodes, if you pick an equally ridiculously low baudrate.

@DmitryGrigoryev I'm not familiar with the "standard" CAN protocol. Does that support more nodes, or would you have to use a non-standard protocol as well?

CAN has an 11-bit address field (and extended CAN bumps it to 29), which is plenty for 200 devices. Standard CAN baudrates start with 125kbps (supporting ~30 nodes along ~500m of distance) but most transceivers can be configured to much lower baudrates like 16kbps.

@DmitryGrigoryev Sounds even more ideal.

Hmmm it's sound great. I'm not much familiar with CAN network. I'll check on Google and come back soon. But looking briefly it looks like expense choice. As RS485 and CAN both can support almost same number of nodes depending upon load. Rs485 is much cheaper solution.  But by the way now I'm very clear I have to divide my network in small parts. Thanks a lot man

@Majenko Personally I would have said that in this application (one master and several receivers) the RS485 would have been better. CAN is more useful when you have an asynchronous network (is it called this way?), where nodes can communicate at will and there are some precedences to be respected. What are the advantages of CAN in this case, in your opinion? RS485 is much cheaper (you can use the UART peripheral, while CAN peripherals are not integrated in cheaper uC)

@frarugi87 CAN is the current standard for industrial applications. If you stick to a standard, then when someone else comes along after you to maintain it or upgrade it, etc, they can more easily know what it is all about.

Regarding your third point, a CAT6 cable may not work as well as you expect for power delivery depending on the topology you choose. The most common variety of CAT6 uses AWG24 wires with a resistance about 0,085 Ohm/m, so a 100 m chunk of such cable will have a resistance of about 17 Ohms. Assuming a current of 100mA, you will lose 1.7V in the cable, so if you supply it with 5V, the load will only see 3.3V.
This is one more reason to split your network into segments. If I were to implement this project, I would power the "backbone" cable with higher voltage (12 - 24V) and install DC-DC converters producing 5V locally in each upper-level node.
It seems from the comments that you're looking into solutions which would allow you to use standard UARTs for communication. You can of course use RS485 (you will still need several segments). Otherwise, I advice you to look at how LIN is implemented: essentially, a 19200 bps UART signal is made open-drain (to combine all TX/RX pairs into a single wire) and amplified to 12V for noise immunity. Software-wise, a master sends a frame including slave's address and waits for a reply, then talks to the next slave and so on. Slaves only respond when they receive a frame with their address in it.
If you don't want to spend extra effort and implement something standard, at least looking into an existing spec while implementing your own solution will save you a lot of trouble.

Yes you are absolutely right. And i was also planning to supply 12V supply with voltage regulator.  At different points.

@umair please note that Dmitry suggested using "DC-DC converters"; don't go for a generic "voltage regulator" (which usually are linear), use a switching converter

@frarugi87 Unless the OP wants to defrost the parking lot in winter :)

@DmitryGrigoryev "it's not a bug, it's a feature" ;)


text:
Class member variable would not update
Code would not update variable inside drive method. The variable is updated inside the drive method, but it doesn't change in the rest of the class. I wrote a simple similar method in normal C++ and the variable actually updated in the rest of the class.
engine.hpp
#pragma once
#include <Arduino.h>

namespace engine
{
class Engine
{
public:
    Engine(const unsigned char t_motor, const unsigned char t_forward, const unsigned char t_backward);
    void drive(unsigned int t_speed, bool t_isForward = true);
    bool isMovingForward() const;
    void stop();

private:
    const unsigned char m_motor;
    const unsigned char m_forward;
    const unsigned char m_backward;

    // Movements
    bool m_isActive;
    bool m_isForward;
    unsigned int m_speed;
};
} // namespace engine

engine.cpp init list
Engine::Engine(const unsigned char t_motor, const unsigned char t_forward, const unsigned char t_backward)
    : m_motor(t_motor),
      m_forward(t_forward),
      m_backward(t_backward),
      m_isActive(false),
      m_isForward(true),
      m_speed(0U)
{
}

drive method
void Engine::drive(unsigned int t_speed, bool t_isForward)
{

    if (!m_isActive || m_isForward != t_isForward)
    {
        stop();

        // Set direction
        if (t_isForward)
        {
            digitalWrite(m_forward, HIGH);
            digitalWrite(m_backward, LOW);
        }
        else
        {
            digitalWrite(m_forward, LOW);
            digitalWrite(m_backward, HIGH);
        }

        m_isActive = true;
        m_isForward = t_isForward;
    }

    if (m_speed != t_speed)
    {
        m_speed = t_speed; // Updated here
        analogWrite(m_motor, t_speed);
    }
}

how do you know it didn't update?

What code do you use to test this?

I know it didn't update because when I check the m_speed variable after calling the drive method, the m_speed variable is set back to zero.

Downvote just for the profane user name.  Have some class man

I figured it out.
I was passing the engine objects as references instead of pointers.
main.cpp
// Engines
engine::Engine
    engine1(motors::Constants::MOTOR_1, motors::Constants::MOTOR_1_FORWARD, motors::Constants::MOTOR_1_BACKWARD),
    engine2(motors::Constants::MOTOR_2, motors::Constants::MOTOR_2_FORWARD, motors::Constants::MOTOR_2_BACKWARD),
    engine3(motors::Constants::MOTOR_3, motors::Constants::MOTOR_3_FORWARD, motors::Constants::MOTOR_3_BACKWARD),
    engine4(motors::Constants::MOTOR_4, motors::Constants::MOTOR_4_FORWARD, motors::Constants::MOTOR_4_BACKWARD);

engine_controller.cpp init list
EngineController::EngineController(engine::Engine &t_e1, engine::Engine &t_e2, engine::Engine &t_e3, engine::Engine &t_e4)
    : m_engine1(t_e1),
      m_engine2(t_e2),
      m_engine3(t_e3),
      m_engine4(t_e4),
      m_currentSpeed(EngineControllerConsts::MAX_SPEED),

      // Directions
      m_rights(0),
      m_lefts(0),

      m_rightDistance(-1),
      m_leftDistance(-1),

      m_lastForward(true),
      m_counter(0),

      m_lastForward1(true),
      m_lastForward2(true),
      m_turnsCounter(0)

{
}

The solution would be to use dynamic memory allocation.
main.cpp
// Engines
engine::Engine
    *engine1 = new engine::Engine(motors::Constants::MOTOR_1, motors::Constants::MOTOR_1_FORWARD, motors::Constants::MOTOR_1_BACKWARD),
    *engine2 = new engine::Engine(motors::Constants::MOTOR_2, motors::Constants::MOTOR_2_FORWARD, motors::Constants::MOTOR_2_BACKWARD),
    *engine3 = new engine::Engine(motors::Constants::MOTOR_3, motors::Constants::MOTOR_3_FORWARD, motors::Constants::MOTOR_3_BACKWARD),
    *engine4 = new engine::Engine(motors::Constants::MOTOR_4, motors::Constants::MOTOR_4_FORWARD, motors::Constants::MOTOR_4_BACKWARD);

engine_controller.cpp init list
EngineController::EngineController(
    engine::Engine *t_e1, engine::Engine *t_e2,
    engine::Engine *t_e3, engine::Engine *t_e4)
    : m_engine1(t_e1),
      m_engine2(t_e2),
      m_engine3(t_e3),
      m_engine4(t_e4),
      m_currentSpeed(EngineControllerConsts::MAX_SPEED),

      // Directions
      m_rights(0),
      m_lefts(0),

      m_rightDistance(-1),
      m_leftDistance(-1),

      m_lastForward(true),
      m_counter(0),

      m_lastForward1(true),
      m_lastForward2(true),
      m_turnsCounter(0)

{
}


text:
Arduino Micro & Thin polymer lithium batteries
Is this battery:

Polymer Lithium-ion Battery
Model Number: PGEB014461
https://www.powerstream.com/p/PGEB014461.pdf

Producing enough energy to power the following Arduino-micro project:
Battery (thin, flexible) to be worn. It will be safely encased (See below)
I would also be using a micro heart pulse sensor module:

https://pulsesensor.com/
https://cdn-shop.adafruit.com/product-files/1093/Pulse+Sensor+Data+Sheet-2018.pdf

and a transmission module
(bluetooth, WiFi, IR, etc...  whichever is suggested or judged appropriate for an alpha project(Needs to be reliable for short range))
Edit: Clarifications about safety standards applied and "do not bend" comments...

They do not have to be kept flat. The 0.5 mm cells can be flexed or bent into a cylinder, into a hat band, belt, etc.

As previously mentioned, the battery will be safely encased and will not go against these warnings...

Do not immerse the battery in water or seawater, and keep the battery in a cool dry environment during stands by period.
Do not use or leave the battery near a heat source such as fire or heater.
When recharging, use the battery charger specifically for that purpose.
Do not reverse the position (+) and negative (-) terminals.
Do not connect the battery to an electrical outlet.
Do not dispose the battery in fire or heat.
Do not short-circuit the battery by directly connecting the positive (+) and negative (-) terminal with metal objects such as wire.
Do not transport or store the battery together with metal objects such as necklaces, hairpins etc.
Do not strike or throw the battery against hard surface.
Do not directly solder the battery and pierce the battery with a nail or other sharp object.

Comments are not for extended discussion; this conversation has been moved to chat.

The Arduino Micro requires 5V. It runs at 16MHz, and you can't run at 16MHz at voltages below about 4V.
To run off a 3.7V battery you need an Arduino board that runs at 8Mhz, such as the "3.3V Pro Micro" from Sparkfun.
To know if your battery is suitable for your project you need to work out the hourly average current draw. That is the proportion of "active" and "inactive" times for each of the devices (transmission duty cycle for your transmitter, sleep times for your MCU, etc).  Until you know that you can't know the capacity (mAh) you need for your project to run for the desired amount of time between charges.

You can also drop the idea of an Arduino and branch out. A board that is probably tailor made for your project is the Adafruit Feather M0 Bluefruit LE which is designed to run from a Lithium Polymer batter (and even includes the charger) and has bluetooth built in.

In a word, no. You need to provide an Arduino Micro with either > 6.5V unregulated into the barrel connector, or a regulated 5V supply directly to the 5V line.
You could use a buck/boost DC/DC converter to boost your 3.7V battery output to 5V and feed that directly into the 5V line on the Arduino (or better, feed it into the USB connector, since that will use the input switching on the Arduino.)
This one, for example:
https://www.banggood.com/DC-DC-3V-15V-to-5V-Fixed-Output-Automatic-Buck-Boost-Step-Up-Step-Down-Power-Supply-Module-p-1355829.html?gmcCountry=US&currency=USD&createTmp=1&utm_source=googleshopping&utm_medium=cpc_bgs&utm_content=frank&utm_campaign=pla-elc2-us-pc-0720&ad_id=368005069105&gclid=EAIaIQobChMI2pfb0Zj54wIVmeDICh2egQ_iEAQYAyABEgLVgvD_BwE&cur_warehouse=CN
Or this one: https://www.digikey.com/reference-designs/en/ac-dc-and-dc-dc-conversion/dc-dc-smps-single-output/1592?utm_adgroup=Converters&gclid=EAIaIQobChMIvM6-9pf54wIVxMDICh36XAxlEAAYASAAEgJsF_D_BwE
Or this one: https://www.adafruit.com/product/2190

To whoever down-voted my answer, can you explain what you found lacking?

to that person; I'm canceling all your down votes with a up-vote, gl. haha

If somebody thinks my answer was poor then a down-vote is fine. I'd like some feedback on what was wrong with my answer however.

he down-voted Majenko answer too...

"he?" I don't know of any way to tell who's doing the down-voting.


text:
Can I do parallel processing in Arduino?
I recently got to work with Arduino and I want to get parallel input from 5 LDRs and at the same instance I need to light a LED corresponding to that LDR if the resistance got high.
I read about a finite state machine, but I couldn't understand how it works.
Is it the only way for this type of problem or are there any other way?

See How to do multiple things at once

For info on state machines, take a look at What kind of problems are state machines good for?.

You do not need parallel processing or finite-state machines for that:
// Vector with digital pin numbers for LEDs (with resistor to ground)
const int LED_MAX = 5;
const int LED[LED_MAX] = { 2, 3, 4, 5, 6 };

// Vector with analog pin numbers for LDR (with pullup resistor)
const int LDR_MAX = 5;
const int LDR[LDR_MAX] = { A0, A1, A2, A3, A4 };

// Analog value or lower when to light the LED
const int THRESHOLD = 200;

void setup()
{
   // All LED pins should be digital output pins
   for (int i = 0; i < LED_MAX; i++)
     pinMode(LED[i], OUTPUT);
}

void loop()
{
   // Read all LDRs and set LED pins according to threshold
   for (int i = 0; i < LDR_MAX; i++)
     digitalWrite(LED[i], analogRead(LDR[i]) < THRESHOLD);
}

But if you really want to describe this as multiple tasks you could use the Simple Scheduler library:
#include <Scheduler.h>

const int THRESHOLD = 200;

template<int LED> void setup()
{
   pinMode(LED, OUTPUT);
}

template<int LED, int LDR> void loop()
{
   digitalWrite(LED, analogRead(LDR) < THRESHOLD);
   yield();
}

void setup()
{
   Scheduler.start(setup<2>, loop<2, A0>);
   Scheduler.start(setup<3>, loop<3, A1>);
   Scheduler.start(setup<4>, loop<4, A2>);
   Scheduler.start(setup<5>, loop<5, A3>);
   Scheduler.start(setup<6>, loop<6, A4>);
}

void loop()
{
   yield();
}


text:
Daikin Remote ARC
I started off attempting to use the  IRRemote    Library and a VS1838B Sensor to capture the Daikin air condition signal.  I’ve read about the timing and in all honesty, I don’t think I can do it on my own so I looked to find the code others had created and adapt it to my own, trying their remote controls first thinking Daikin may only have a few sets.
I can’t confirm that will work as yet because I’ve only been able to find the code below but I’m not quite sure what is the best practice for ripping (stripping out the parts I don’t need) it apart.
When I attempted to capture the IR codes, most of the time I get nothing at all.  My stereo remote is immediate displayed though.
Now the good news,  based on Harizanov’s work, he’s mapped the ARC533 Remote,  which is the same model that I have.

My Model : FTM18NV2S
Remote:  ARC533A55
Daikin - Smash

NV2S  (On the Inverter)

Remote:  Doesn’t say anything of use
15-Series Wall Mount

Code Here: Control Daikin air conditioner over the Internet
Code here: Github: mharizanov/Daikin-AC-remote-control-over-the-Internet
Can anyone provide a recommendation on how I could trim up this code to try it?

I'm not sure if I can just use the irsend.SendRAW options for this application but I figured since the ARC533 was already mapped out, why not use that.  This is my first attempt at anything like this so I'm a bit out of my realm of understand.
Appreciate any help.
Side note: I have been testing with a stereo remote and have copied the stereo remote On/Off as raw and can send it back, except the timing seems off because it flashes way too slow.

Anyone at all?    Got no idea how to proceed

I had a problem with my daikin A/C. After spending lot of time trying to fix this problem, i found out that is is using long ir codes which is hard to simulate using the IRSenderBitBang (38 kHz). After lot of fustation I used irdevkit.com. It has a ir decoder built in and I can control it using ESP8266. Works well


text:
text to 2D array on Arduino
I am trying to read a text file and send the info to 2D array, but after loading the array, it reads all zeroes. What can I do to stop the Arduino from doing this and get the array with my required data?
/* This program was created by ScottC on 8/5/2012 to receive serial signals from a computer to turn on/off 1-9 LEDs */

int** ptr;

void setup() {
  // initialize the digital pins as an output.
  pinMode(13, OUTPUT);
  // Turn the Serial Protocol ON
  Serial.begin(9600);
}

void loop() {
  byte byteRead;

  if (Serial.available()) {

    /* read the most recent byte */
    byteRead = Serial.read();
    //You have to subtract '0' from the read Byte to convert from text to a number.
    byteRead = byteRead - '0';
    ptr = new int* [byteRead];

    int i,j;
    for ( i = 0; i < byteRead; i++) {
      ptr[i] = new int[3];
      for ( j = 0; j < 3; j++) {
        if (Serial.available()) {

            /* read the most recent byte */
            byteRead = Serial.read();
            //You have to subtract '0' from the read Byte to convert from text to a number.
            byteRead = byteRead - '0';
            ptr[i][j] = byteRead;
            Serial.print(ptr[i][j]);
        }
      }
    }
  }
}

I see nothing there at all to do with text files, and the whole program looks somewhat daft. Please take a step back from the program and think about what you want to achieve before dumping someone else's code on us.

For reading serial data on the Arduino you should really read this to clear up some of your bad misconceptions: https://hackingmajenkoblog.wordpress.com/2016/02/01/reading-serial-on-the-arduino/

There are several issues with your code but instead of correcting I recommend that you start by checking that your assumptions about the format is correct. Send your data to this "reduced" variant of your sketch. Does it work? Did you receive what you expected?
void setup() {
  // initialize the digital pins as an output.
  pinMode(13, OUTPUT);
  // Turn the Serial Protocol ON
  Serial.begin(9600);
}

void loop() {
  byte byteRead;

  if (Serial.available()) {

    /* read the most recent byte */
    byteRead = Serial.read();
    //You have to subtract '0' from the read Byte to convert from text to a number.
    byteRead = byteRead - '0';
    Serial.print(F("byteRead = "));
    Serial.println(byteRead);

    int i,j;
    for ( i = 0; i < byteRead; i++) {
      for ( j = 0; j < 3; j++) {
        if (Serial.available()) {

            /* read the most recent byte */
            byteRead = Serial.read();
            //You have to subtract '0' from the read Byte to convert from text to a number.
            byteRead = byteRead - '0';
            Serial.print(i);
            Serial.print(':');
            Serial.print(j);
            Serial.print(F(":byteRead = "));
            Serial.println(byteRead);
        }
      }
    }
  }
}

Did you see the issue with:
    for ( i = 0; i < byteRead; i++) {
    ...
    }

Cheers!

The worst part of that code is the bit that reads `for ( j = 0; j < 3; j++) {
if (Serial.available()) {
        /* read the most recent byte */
        byteRead = Serial.read();`