text:
How to add calibration to a humidity contoller using UNO and DHT22 sensor?
I am using a setup that helps controlling humidity in an enclosure used to store a humidity sensitive product.   My original posting is here.
I'm using a NANO and a DHT22 temperature/humidity sensor to acquire information on the actual condition in the enclosure; I am also using a 75% RH calibration kit to check the accuracy oh the humidity reading by the UNO and I found the value 9 percentage points higher than the kit's calibration value.   Right now, until I find a solution to calibrate the unit, I have set my setpoint 9 points higher to compensate for the error.
Any ideas on how to tackle this issue would be highly appreciated.
At the moment I can read the DHT sensor and show the humidity value on the LCD like this:
[...]
  int chk = DHT.read22(DHT22_PIN);
  lastcheck = millis();

  lcd.setCursor(0, 0);
  lcd.print("Humidity: ");
  lcd.setCursor(13, 0);
  lcd.print(DHT.humidity);
[...]

@Thomas_Weller,
I'm running tests with your calibration routine and other code changes; I'm using your arbitrary values for testing purposes only; the compensation algorithm works, as sampled below, however the LCD output is the actual DHT22 reading, not compensated.
I am testing with a different sensor, whose output is 9% below the actual RH value.
Here's a sample of the serial output:
DHT value: 58
Compensated to: 55
DHT value: 59
Compensated to: 56
DHT value: 60
Compensated to: 57
DHT value: 61
Compensated to: 58
DHT value: 62
Compensated to: 59
DHT value: 63
Compensated to: 60
DHT value: 64
Compensated to: 60

setpoint = 72
DHT read = 66.80%
displ + backlights off
humidifier ON, fan OFF
setpoint = 72
displ + backlights off
humidifier ON, fan OFF
setpoint = 72
displ + backlights off
humidifier ON, fan OFF
setpoint = 72
DHT read = 66.80%
displ + backlights off
humidifier ON, fan OFF
setpoint = 72
displ + backlights off
humidifier ON, fan OFF
setpoint = 72
displ + backlights off
humidifier ON, fan OFF

You need more data points for an effective calibration. You currently have no idea if the error is linear, absolute or something else.

@StarCat, thanks, I am aware of that and I'm working on it.

To get better calibration, you need more calibration points. In the example below, I use 8 measurement points.
Given 8 humidity calibration bags for 20, 30, 40, 50, 60, 70, 75 and 80%.
int calvalues[] = {20, 30, 40, 50, 60, 70, 75, 80};

You would take several samples with the DHT sensor and build a table using the averages:
int dhtvalues[] = {15, 28, 39, 51, 63, 75, 84, 89};

As you can see, the DHT is below the real values in the lower range and above the real values in the upper range. But it could also be the opposite way.
You can then write this function:
#define COMPENSATION_POINTS 8

int compensate(int sensor_value)
{
  for(int index=1; index<COMPENSATION_POINTS; index++)
  {
    if (dhtvalues[index]>sensor_value)
    {
      int dhtLow = dhtvalues[index-1];
      int dhtHigh = dhtvalues[index];
      int calLow = calvalues[index-1];
      int calHigh = calvalues[index];

      return map(sensor_value, dhtLow, dhtHigh, calLow, calHigh);
    }
  }
}

which does linear interpolation for all the values that fall somewhere in between.
Here's some test code, which goes through the values in the expected range.
void setup() {
  Serial.begin(9600);
  for(int hum=15; hum<=89; hum++)
  {
    Serial.print("DHT value: ");
    Serial.println(hum);
    Serial.print("Compensated to: ");
    Serial.println(compensate(hum));
  }
}

void loop() {
  delay(1000);
}

Output:
DHT value: 15
Compensated to: 20
DHT value: 16
Compensated to: 20
DHT value: 17
Compensated to: 21
DHT value: 18
Compensated to: 22
...
DHT value: 87
Compensated to: 78
DHT value: 88
Compensated to: 79
DHT value: 89
Compensated to: 79

Applied to your case:
[...]
  int chk = DHT.read22(DHT22_PIN);
  lastcheck = millis();

  lcd.setCursor(0, 0);
  lcd.print("Humidity: ");
  lcd.setCursor(13, 0);
  int compensated = compensate(DHT.humidity);   // <- new line
  lcd.print(compensated);                       // <- changed line
[...]

Good answer (voted). How did you measure the sensor's response at 20, 30, 40, 50, 60, 70, 75, 80 RH? Do you have a setup with water containing various salts to create those humidity levels? And shouldn't you also measure the response at a range of different temps, since the error probably varies with temperature?

@DuncanC: you're probably right. That should be a 2D table.

@Thomas_Weller, I ran tests and my original question was edited with what I found; please comment, thanks.


text:
How to Read ADC value without Common GND ? (Possible or not !)
I want to Read external signal with the microcontroller.
But the problem is that ADC does not work because the signal GND and the microcontroller are not Common,
My question is, have you encountered such a problem? Is there a way to do it?

you are trying to measure the voltage difference between two nodes with only one node attached ....... try measuring the voltage of a battery with only one probe

How about You can explain more ? @jsotola

jsotola means: You need a common ground, no way around that. So connect both grounds together

So there is no solution. I tried to read one of the ECG electrode signals to the ADC until I had trouble. @chrisl

you could use an opto coupler if needed. i've DIY'd "analog" ones with an LED glued to a CDS then wrapped in tape, adjusting the LED resistor to "calibrate" the range. After tweaking, i was able to get a fairly linear response throughout 75% of the range.

The solution is to always use at least 2 electrodes. You need 1 electrode, that you connect to ground. You can put this electrode to somewhere neutral (this instructable suggest connecting it to your leg, but I don't know, if that position is really good).
An ADC measures voltage and voltage is the difference in potential between 2 points, so to measure voltage you by definition need 2 points/connections.

Note: The voltages from the EEG electrodes are normally very low, so that they completely vanish in the noise. To really get something useful, you need to amplify the signal. I think there are many tutorials out there, that explain how to do this.

This is true . But I want to send each 10 leads wirelessly. I need to read each of the leads with ADC.
Can the microcontroller ground be common with the shield lead ground to work the ADC? @chrisl

There are many things unclear in that question. What shield? (You didn't mention a shield before) And how do you plan to "send leads wirelessly"? An analog voltage cannot just simply send wirelessly. The normal way is to measure it wired (since you need it wired for measurement), and then send the measured value over a wireless transmit technology of your choice. Do you already have a complete project plan? If yes, you need to share it for me to answer. If no, then you first need to think about the overall plan. How everything should be working

OK . Let me explain the project to you. I first wanted to wire 10 leads of ECG each with #WiFI sended. But because the ECG device works differently, it didn't work !!!!So I wanted to put all the leads in a small control panel and send it with #WiFI.
I'm confused now and I don't know what to do.
What do you think should be done? @chrisl

"But because the ECG device works differently" Do you already have some kind of device, that does the actual measurement of the ECG? Or do you have to build one? It is unclear to me, what you already have. You seem to need general project guidance. Unfortunately this site is not good for guidance, since it's  a simple Q&A site. Maybe you get better results and help for your project when posting in the project guidance section of the Arduino forum (you can simply google it). A forum is a better fit for project guidance.

source: Stack Exchange

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

sort: votes


text:
NodeMCU hc05 Connection
I am using a NodeMCU from Amica. I tried interfacing the HC-05 module to the NodeMCU.
The following code works fine without any errors
#include<SoftwareSerial.h>
SoftwareSerial btport(D2, D3);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(38400);
  btport.begin(38400);
}

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

But when I change the code to the following the serial monitor displays garbage values.
#include<SoftwareSerial.h>
SoftwareSerial btport(D2, D3);

int count = 0;
char data[200];
char c;
int flag = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(74880);
  btport.begin(38400);
}

void clearData(){
  int i = 0;
  while(i < 200){
    data[i] = '\0';
    //yield();
  }
  count = 0;
}

void loop() {
  clearData();
  btport.write("AT+INQ\r\n");
  delay(200);
  if(btport.available()){
    while(btport.available()){
      c = btport.read();
      data[count++] = c;
      data[count] = '\0';
    }
  }
  Serial.println(data);
}

The output of the above code is

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1392, room 16
tail 0
chksum 0xd0
csum 0xd0
v3d128e5c
~ld

Soft WDT reset

>>>stack>>>

ctx: cont
sp: 3ffffe00 end: 3fffffc0 offset: 01b0
3fffffb0:  feefeffe feefeffe 3ffe84e4 40101289
<<<stack<<<
¢„*«P*V¡¡ET©«´¥T«ª«*¥u´U+UZªªUT¢üªTQT¥UQ©©jPªV©µuª¥…¢üZT¥(EŠª«ªQTEªj*QTE«ªUUªŠø/¥Å
Soft WDT reset

>>>stack>>>

ctx: cont
sp: 3ffffe00 end: 3fffffc0 offset: 01b0
3fffffb0:  feefeffe feefeffe 3ffe84e4 40101289
<<<stack<<<
¢„*«P*V¡¡ET©«´¥T«ª«*¥u´U+UZªªUT¢üªTQT¥UQ©©jPªV©µuª¥…¢üZT¥(EŠª«ªQTEªj*QTE«ªUUªŠø/¥Å

What should I do to solve this issue?

did you change the speed of the serial monitor as well?

@dandavis Yeah. I tried with different speeds. But didn't work.

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


text:
Why are the PWM variables in this RC code snippet handled this way? What are the magic numbers?
tcommand=(pwm_value-480.0)/8.22;
flapmag=(pwm_value-880)/41.0+10;

In this piece of code used in arduino radio control aircraft, I don't understand why PWM value is subtracted and divided like this. This is not my code, it came from here. Any explanation would be of great help. I have read about PWM but all have different explanations.
//Arduino servo flap system
//copyright Steve Morris 10-25-16
#include <Servo.h>
volatile int pwm_value = 0;
volatile int prev_time = 0;
static int servo_comm1 = 0;
static int servo_comm2 = 0;
volatile int flapangle1 = 0;
volatile int flapangle2 = 0;
volatile int millisold = 0;
int millinow = 0;
float dt = 0;
float flapmag = 0;
static float flapdeg = 0;
float tcommand = 0;
float floattime = 0;
float temp = 0;
float glide_deg = -10.0;
static int pwm_value_temp = 0;
float omegadot = 0.0;
float thetadot = 0.0;
static float omega = 0.0;
static float theta = 0.0;
static float k0 = 1.0;
static float k2 = 10.0;
static float servo_zero1 = -4;
static float servo_zero2 = 0;

Servo myservo1, myservo2; // create servo object to control a servo

void setup() {
  //Serial.begin(115200);
  // when pin D2 goes high, call the rising function
  attachInterrupt(0, rising, RISING);
  myservo1.attach(5); // attaches the servo on pin 5 to the servo object
  myservo2.attach(6); // attaches the servo on pin 6 to the servo object
}
void loop() {

  millinow = millis();
  floattime = millinow / 1000.0;
  dt = (millinow - millisold) / 1000.0;
  millisold = millinow;

  tcommand = (pwm_value - 480.0) / 8.22;
  omegadot = k0 * tcommand - k2 * omega;
  thetadot = omega;
  flapdeg = sin(theta);
  theta = theta + omega * dt;
  omega = omega + omegadot * dt;

  flapmag = (pwm_value - 880) / 41.0 + 10;
  flapdeg = flapmag * sin(theta); //variable amplitude+freq

  flapangle1 = (int)((30.0 - flapdeg + servo_zero1) * 2.0 + 25.0);
  flapangle2 = (int)((30.0 + flapdeg + servo_zero2) * 2.0 + 25 .0);

  if (pwm_value > 930) {
    servo_comm1 = flapangle1;
    servo_comm2 = flapangle2;
  }

  //Glide Lock
  if (pwm_value < 910) {

    servo_comm1 = (int)((30.0 - glide_deg + servo_zero1) * 2.0 + 25.0);
    servo_comm2 = (int)((30.0 + glide_deg + servo_zero2) * 2.0 + 25.0);

  }

  myservo1.write(servo_comm1); // tell servo to go to position in variable 'pos'
  myservo2.write(servo_comm2); // tell servo to go to position in variable 'pos'

  //Serial.println(servo_comm1);
  //Serial.println(floattime);
  //Serial.println(dt);
  //Serial.println(flapangle);
  //Serial.println(flapdeg);
  //Serial.println(temp);
  //Serial.println(tcommand);
  //Serial.println(pwm_value);

}

void rising() {
  attachInterrupt(0, falling, FALLING);
  prev_time = micros();
}

void falling() {
  attachInterrupt(0, rising, RISING);
  pwm_value = micros() - prev_time;
}

There is not enough context to be certain, but given the variable names I can assume that this is code from a sketch that receives information from an RC controller and is intended to control parts of some form of flying craft.
So with that in mind, let's take this line:
flapmag=(pwm_value-880)/41.0+10;

I assume that this is to calculate the amount the flaps should be extended or retracted.
RC controllers, or rather the receivers that pick up the signals, usually output a PWM signal (square wave with a variable duty cycle) where the duty cycle is directly related to the position of the joystick.
A joystick is usually zero in the center and goes plus or minus for up and down (or right and left). But you can't have a negative PWM value, since that makes no sense (how can you have a signal that is off for less that 0% of the time?!).  So the output is "offset" by a certain amount (that's not quite true - actually the joystick is 0 for fully down, and 100% for fully up, with "0" being somewhere in the middle, so the offset is applied by the joystick, not the receiver, but that really doesn't matter for us right now).
So we have a signal that is at any time somewhere between 0% and 100%, with "zero" being somewhere in the middle.  What actual value the "100%" is, or exactly where "zero" is, can vary depending on many many factors, so we'll just use "100" for the maximum, and "50" for the middle "zero" offset.
The first thing you want to do, then, is remove that "zero" offset. And that is as simple as subtracting it.  With our example numbers above, if you subtract the "zero" offset of "50" from the incoming signal it now goes between -50 and +50 instead of 0 and 100. That now relates much better to how a joystick appears - 0-50 in an upwards direction (+) and 0-50 in a downwards direction (-).
And that is exactly what is happening with pwm_value-880 in your code.  The middle "zero" value of 880 is being subtracted from the incoming joystick position to give you an "up" or "down" value that is positive or negative respectively.
Next comes the division.  This scales the incoming value to the right size for the device you are driving. In our example we have a ±50 signal. But what if our flaps require a ±10 signal to give the correct movement range. So simply dividing the value by 5 will change ±50 into ±10. That's exactly what the /41.0 is doing - scaling the result to fit the range of the target device.
Then there's one final +10 in there. This simply adds a small offset to the result. You can think of this as a "trim" value. It sets the actual "zero" point of the target device - in this case when the joystick is centered it means the flaps are set to a +10 position.
As to how the pwm_value itself is created, that is usually done through capturing the rising and falling edges of the incoming waveform from the receiver and timing how long the signal is in the HIGH or LOW state. That may be performed by some unspecified library.

Actually, this is what I was asking. Thanks for the information.


text:
How to create an inverted PWM on the Due via software
Hello I am i need of a piece of code that lets me invert a PWM signal of two PWM pins on the due. Example D1 will be 101010 and D2 will be 010101. Is it possible?
Im pretty limited in my options because, doing it externally is not an option because there will be a time where a change in mode is needed and both pins will be sending signal independently. Manually pulling the pins High and Low is also not an option for me because this will make the code blocking other codes.

inverted 75% is same as noninverted 25%

@jsotola i am having trouble visualizing that, although they would be opposing but the frequency would not match, the 25% would miss one cycle of the 75% . Am i missing something?

take a piece of paper and a pencil ... dreaw 10 cycles of 25% PWM waveform ... rotate the paper upside down ... maybe I'm missing something

Image. The above signal in the image is 75% and the one at the bottom is 25%. the 25% is missing one cycle of the 75%

this is PWM ... https://www.nightsea.com/wp-content/uploads/2017/12/PWM-diagram.jpg

Yeah i got a wrong understanding of pwm, im sorry. New Image although inverted but i have to phase out by a little bit. Now that would be a different approach, i guess which ever is easier to do, both i think would involve direct register manipulations

Let us continue this discussion in chat.

you could use an xor gate to invert the PWM signal. this allows you to   easily un-invert the signal with another GPIO pin feeding the gate's other input.

@dandavis well that is an approach i can go if i cant find a way to do in via software.  with everything i have read so far, I believe that it can be done via software, getting there is ust a little bit difficult

Not using the Arduino API, no. But you can by direct manipulation of the SAM3X8E registers.
You should study section 38 of the datasheet, where it mentions in the list of facilities:

Independent Complementary Outputs with 12-bit Dead-Time Generator (Also Called Dead-Band or Non-Overlapping Time) for Each Channel

Register manipulation is way over me, hopefully there is some examples.

@Jack There probably are, but probably not around here. The Atmel forums might be good though.


text:
Half-duplex for Atmel SAMD21
I'm using an Arduino MKR GSM 1400. I know this board uses the Atmel SAMD21 and the SAMD21 supports half-duplex (USART with full-duplex and single-wire half-duplex configuration). My question is, how can I configure one of the SERCOMs to use it as half-duplex (use one pin for rx and tx)?

what problem do you try to solve?

@Juraj So what is http://asf.atmel.com/docs/latest/sam0.applications.samba_bootloader.samc21_xplained_pro/html/asfdoc_sam0_sercom_usart_mux_settings.html ?

@Juraj "When TX and RX are connected to the same pin, the USART will operate in half-duplex mode if both one transmitter and several receivers are enabled."

so try it. the Arduino wrapper classes don't have clock pin configuration so you can't configure USART only UART.  so you must use registers or some other framework then Arduino

Up to six Serial Communication Interfaces (SERCOM), each configurable
to operate as either:

USART with full-duplex and single-wire half-duplex configuration
I2C up to 3.4 MHz
SPI
LIN slave

It is an error in the overview of the SAM D21 features in the datasheet. The SERCOM is half-duplex for I2C. USART can't be configured half-duplex.
see Application Note about SERCOM configuration

1 Introduction to Serial Communication Interfaces (USART, I2C, and
SPI)
... The exchange of data can be half-duplex or fullduplex depending on
the serial module specification. ...
1.1 USART
... It is full-duplex in operation. ...
1.2 I2C
... It is half-duplex in communication. ...

Is there anyway to configure USART as half-duplex?

Is there any library like https://github.com/nickstedman/SoftwareSerialWithHalfDuplex for SAMD21?

as I write in the answer. no

You can use USART in half duplex mode.
SERCOMx.PAD0 or SERCOMx.PAD2 are available for this. Refer to document "AT03256: SAM D/R/L/C Serial USART (SERCOM USART) Driver" section "10. SERCOM USART MUX Settings".
Below is a piece of code for ATXMEGA32E5, SERCOM0, PAD0. I am tested - it works:
Pull-up will help keep the line at 1 when the device’s transmitter is turned off and there is no other transmitter on the line, or it has not turned on yet. In the GPIO setup procedure:
// PA08 - SERCOM0/PAD[0]
PORT->Group[0].PINCFG[8].bit.PULLEN=1;    // Pull Enable
PORT->Group[0].PINCFG[8].bit.PMUXEN=1;    // Peripheral Multiplexer Enable
PORT->Group[0].PMUX  [4].bit.PMUXE=0x02;  // PMUX function C - SERCOM0/PAD[0]

In the SERCOM setup procedure, configure TX and RX on one pad:
while(SERCOM0->USART.SYNCBUSY.reg & 0x07) { ; }
SERCOM0->USART.CTRLA.bit.TXPO = 0x00;   // SERCOM PAD[0] Transmit Data Pinout
while(SERCOM0->USART.SYNCBUSY.reg & 0x07) { ; }
SERCOM0->USART.CTRLA.bit.RXPO = 0x00;   // SERCOM PAD[0] is used for data reception

If at the time of your transmission both the receiver and the transmitter are turned on at the same time, you will hear your echo.
When you get up for reception, do not forget to turn off your transmitter so that it does not interfere with reception:
SERCOM0->USART.CTRLB.bit.TXEN=0x00; while(SERCOM0->USART.SYNCBUSY.bit.CTRLB ) { ; }
SERCOM0->USART.CTRLB.bit.RXEN=0x01; while(SERCOM0->USART.SYNCBUSY.bit.CTRLB ) { ; }

Before transmitting, do not forget to turn on the transmitter:
SERCOM0->USART.CTRLB.bit.TXEN=0x01; while(SERCOM0->USART.SYNCBUSY.bit.CTRLB ) { ; }
SERCOM0->USART.CTRLB.bit.RXEN=0x00; while(SERCOM0->USART.SYNCBUSY.bit.CTRLB ) { ; } // If you don't want to receive your own transmission

Hope it helps.


text:
Level shifting 5V <-> 3.3V
My main goal is to use connect the HC-SR04 ultrasonic sensor with ESP8266.
Problem is, HC-SR04 works with 5V while the ESP8266 works with 3.3V
In order to solve this, idea would be to use a logical level converter.
I bought some of this 3.3V 5V TTL Bi-directional Logic Level Converter(s) a good while ago, and thought they would fit best for this project.
Here's my setup

5V from arduino
3.3V from digital power supply
GND connected together
Nothing connected to TX0 (HV side)
Voltmeter connected to TX1 (LV side), still getting a 3.3V

Here's a closer look at the breadboard connections

Am I doing something wrong ? Any suggestions would be appreciated !

Are you sure you connected it correctly? The description on the seller's site is not clear at all, and at least a bit ambiguous. I'm also not sure if these boards are really bidirectional as the markings seem to indicate Inputs (I) and Outputs (O). What do you see at RXO (Receive-Out?) on the low side if you connect, for example, the RXI (Receive-In?) on the high side to 0V or 5V? It would be very nice if these cheap boards were properly documented...

I'm not sure at all. I get 2.5V on RX0 if I connect RXI to 5V, and 0V if I connect RX1 to GND. I agree with the documentation, that's why I was hoping someone here might know more about them

Edit: Forget the post above if you just want to know how your board is working. Your board is a retired Spurkfun product - clone.
Here you can see the schematics and all info about your board:
https://learn.sparkfun.com/tutorials/retired---using-the-logic-level-converter
Original post:
The module you got, use the BSS138 MOSFET.
The circuit is easy, and how @Majenko said, it has just 2 pullups:
See https://electronics.stackexchange.com/questions/367052/replace-bss138-with-ao3400a-in-level-shifter-circuit

But this board is really strange: what means TX0, TX1, RX0, RX1 on the same MOSFET? It is better if you can measure it to be sure how to connect the sensor to the TX.
But there is a better way to solve it: Since you just have 1 input to your ESP, why not use 2 resistors?
5V--- 1k --- 2k --- GND
And connect the ESP input between the 2 resistors? It is even faster, because the MOSFET need up to 20ns to change state.

Thanks for making some "light". I tried all possible combinations with the module and still can't go from 3.3V -> 5V or the other way around. No wonder it's retired, also name starts with BS..
On the ESP I'll need two pins with the ultrasonic sensor. 1 as input and 1 as output. I'll try what you were saying above with the input pin but how should I go about the output ?

The board was made for a serial converter from 5V to 3.3V. This is the reason for RO and RI, or TO and TI. Since in the circuit, the Rx use just 2 resistors, you have to use the T0 and TI. So, put the Esp32 pin to TI, and your sensor input to TO. And invert VL with VH, if you have still 3V, since you want convert from 3V to 5V but the circuit was made to convert 5V to 3.3V. It should not be a problem if you do not use the middle part of this board.

I'm a bit worried that if I wire the ESP and sensor with the module and test it like that, it might damage them, if the module doesn't work as expected (eg. draws too much current). Would there be an "easy" way to check 3.3V to 5V, without being the possibility of damaging something ? The 5V to 3.3V works with the resistors

Yes, I know what you mean. An easy way to check is to apply a 3.3V to an XI (RI or TI) and see what you get on the output (RI goes to RO and TI goes to TO). How you connected the board is right (GND, LV to 3.3V and HV to 5V), I would just apply a 3.3V to both inputs: RI and TI, and check if you can measure 5V on RO or TO. If you measure still 3.3V, you have to set the 3.3V on RO and TO or invert LV and LH voltages. Just test it without the sensor or Arduino connected on this board.

No, you're not doing anything wrong.  Those simple MOSFET level shifters work by having both sides pulled up by resistors to their respective power supplies. When one side gets pulled low by a digital signal that LOW is mirrored to the other side of the MOSFET.
If you connect your TX0 pin to GND you will see the TX1 pin go to 0V.

Tried it, but it's not working. Also the current on the digital power supply increased to 0.7A - https://i.imgur.com/UG5dj6R.png

It might be only a one-way then.  I notice on closer inspection that it's not TX0 and TX1 bit TXI and TXO. That's Input and Output. For 5V->3.3v you should use RXI and RXO for 5V (I) and 3.3V (O), which just uses a simple voltage divider.

Check this out:
https://learn.sparkfun.com/tutorials/bi-directional-logic-level-converter-hookup-guide/all
This article gives a comprehensive explanation about the bi-directional logic level converter and it's connection in a circuit.


text:
Can't get actual output when, both input logic is high
I want
When,

light=0, ir=0 then output will pin 8 high & pin 12 low.
light=0, ir=1 then output will pin 8 high & pin 12 high.
light=1, ir=0 then output will pin 8 low & pin 12 low.
light=1, ir=1 then output will pin 8 low & pin 12 low (This statement
does not work).

Please find the code & suggest me, if any modification is needed.
void setup() {

    pinMode(8,OUTPUT); //logic output.
    pinMode(12,OUTPUT); //logic output.
    pinMode(2, INPUT); //value input.
    pinMode(4, INPUT); //value input.

    Serial.begin(9600);
}

void loop() {

    int light = digitalRead(2); //value input.
    int ir = digitalRead(4); //value input.

    if (light == LOW && ir == LOW)
    {

      digitalWrite(8, HIGH);
      digitalWrite(12, LOW);
      delay(2000);

    }

    if (light == LOW && ir == HIGH)
    {

      digitalWrite(8, HIGH);
      digitalWrite(12, HIGH);
      delay(2000);

    }

    if (light == HIGH && ir == LOW)
    {

      digitalWrite(8, LOW);
      digitalWrite(12, LOW);
      delay(2000);

    }

    if (light == HIGH && ir == HIGH) //This condition does not work.
    {

      digitalWrite(8, LOW);
      digitalWrite(12, LOW);
      delay(2000);

    }

    digitalWrite(8, LOW);
    digitalWrite(12, LOW);
    delay(2000);

}

Please format your code using a code block (see https://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks). I don't know why your code does not work like you intended, but the last two IF statements (including the one that does not work) are the same for ir being LOW or HIGH, so you can just as well combine them into one, for example: if (light == HIGH) { digitalWrite(8,LOW); digitalWrite(12,LOW); delay (2000); }. Or maybe that isn't what you intended and that's where the error in your code is.

Also, it would be helpful to explain what your code is supposed to do and what hardware it is connected to.

Here is two input & two output.
I want,
if light=0, ir=0 then output will pin 8 high & pin 12 low.
if light=0, ir=1 then output will pin 8 high & pin 12 high.
Otherwise output will,
pin 8 low & pin 12 low.

print some debug messages so you can see what‘s going on.

put the delay(2000); after all of the if statements

digitalWrite(8,LOW); digitalWrite(12,LOW);

You can simplify your requirements somewhat by splitting your inputs up.

light=0, ir=0 then output will pin 8 high & pin 12 low.
light=0, ir=1 then output will pin 8 high & pin 12 high.

If light is 0 then pin 8 is high. AND ir is echoed to pin 12.

light=1, ir=0 then output will pin 8 low & pin 12 low.
light=1, ir=1 then output will pin 8 low & pin 12 low

If light is 1 then both pins 8 and 12 are low, and you don't care what ir does, since it doesn't have any effect on the outputs.
So your structure could look more like:
if (light == 0) {
    digitalWrite(8, HIGH); // 8 will always be high with light == 0
    digitalWrite(12, ir); // echo the ir value to pin 12
} else {
    digitalWrite(8, LOW); // if light is 1 then everything
    digitalWrite(12, LOW);// is low regardless of ir.
}

Note this is not an answer to the question (I don't see any problem initially), but to clean the code it might help to debug it (using print statements as Sim Son suggests).
Instead of all the if statements, check when pin 8 and pin 12 needs to be HIGH:
 pin 8:  (light == LOW && ir == LOW)
 pin 12: (light == LOW && ir == LOW)  or (light == LOW && ir == HIGH)

For pin 12, the condition can be rewritten as
 pin 12: (light == LOW) || (ir == LOW or ir == HIGH)

which is equal to
 pin 12: light == LOW

So now you can change the code from the loop function to:
void loop()
{
   digitalWrite(8 , (light == LOW && ir == LOW) ? HIGH : LOW);
   digitalWrite(12, (light == LOW             ) ? HIGH : LOW);
   delay(2000);

   digitalWrite(8, LOW);
   digitalWrite(12, LOW);
   delay(2000);

}
the x ? : z statements means: if x is true, do y, else z.
The last three statements are fixed (copied from your code).
Now we can even further reduce it, by removing the duplicated code
void loop()
{
   processLeds((light == LOW && ir == LOW), (light == LOW));
   processLeds(False                      , False         );
}

void processLeds(int conditionLed8, int conditionLed12)
{
    digitalWrite( 8, conditionLed8  ? HIGH : LOW);
    digitalWrite(12, conditionLed12 ? HIGH : LOW);
    delay(2000);
}

You pass the condition when led 8 and 12 have to be high or log to a function, which sets the LEDs.
Now you can also use much less print statements for finding your problem.


text:
qsort is not really sorting
I'm working with Arduino and getting some strange errors. qsorting is not sorting correctly.
//using this libraries
#include <ESP8266WiFi.h>
#include <inttypes.h>

//the red struct is

typedef struct {
    int32_t rssi;
    int id;
} red;

//Here is my compare function
int compare (const void * a, const void * b)
{
  yield();
  red *redA = (red *)a;
  red *redB = (red *)b;
  //Serial.printf("redA->rssi: %d, redB->rssi: %d\n",redA->rssi,redB->rssi);
  //Serial.flush();

  return redA->rssi > redB->rssi ? 1 : (redB->rssi < redA->rssi ? -1 : 0);
  //return ( redB->rssi - redA->rssi );
}

void showNetworks(){
  int n = WiFi.scanNetworks(false,false);
  red listOfRedes[n];

  for (int i = 0; i < n; i++) // ...initialize it
  {
    yield();
    listOfRedes[i].rssi = WiFi.RSSI(i);
    listOfRedes[i].id = i;
    Serial.printf("%d: RSSI%d\n", i, listOfRedes[i].rssi);
    Serial.flush();
  }
  Serial.printf("salio\n");
  Serial.flush();
  qsort (listOfRedes, n, sizeof(red), compare);
  Serial.printf("ordeno\n");
  for (int i = 0; i < n; i++) // ...initialize it
  {
    yield();
    Serial.printf("%d: RSSI:%" PRId32 "\n", listOfRedes[i].id, listOfRedes[i].rssi);
  }
}

and this is the output i get
0: RSSI-69
1: RSSI-65
2: RSSI-72
3: RSSI-50
4: RSSI-60
5: RSSI-87
6: RSSI-87
7: RSSI-79
8: RSSI-80
9: RSSI-88
10: RSSI-74
11: RSSI-77
12: RSSI-78
13: RSSI-83
14: RSSI-79
15: RSSI-60
16: RSSI-85
17: RSSI-86
18: RSSI-66
19: RSSI-88
20: RSSI-80
21: RSSI-74
22: RSSI-81
23: RSSI-87
salio
ordeno
4: RSSI:-60
1: RSSI:-65
0: RSSI:-69
3: RSSI:-50
18: RSSI:-66
15: RSSI:-60
2: RSSI:-72
10: RSSI:-74
11: RSSI:-77
21: RSSI:-74
19: RSSI:-88
20: RSSI:-80
22: RSSI:-81
23: RSSI:-87
12: RSSI:-78
5: RSSI:-87
6: RSSI:-87
7: RSSI:-79
8: RSSI:-80
9: RSSI:-88
13: RSSI:-83
14: RSSI:-79
16: RSSI:-85
17: RSSI:-86

As you can see the sorting is not OK and I don't get why.
Thank you in advance and sorry for my poor English.

Thanks st2000 i did not know how to formatt it

Don't use qsort, use std::sort.

In your program there is this line of code:
  return redA->rssi > redB->rssi ? 1 : (redB->rssi < redA->rssi ? -1 : 0);

Which appears to return a 1 if A is greater then B other wise it will return a 0.  This code can not tell the difference between A < B and A == B.  Consider altering this line of code to allow returning 1 for A > B, 0 for A == B and -1 for A < B:
  return redA->rssi > redB->rssi ? 1 : (redA->rssi < redB->rssi ? -1 : 0);

can't belive i did that.... like.... for hours..... thank you men, i'm an idiot....

I didn't see it for a while either.  Glad I could help.


text:
Declaring and using array of structures in Arduino
Printing structure variables, I get default values. What is wrong with my code?
struct SCENARIO
{
  int Lamp_Pin = -1;
  int PB_Pin = -1;
} ;

SCENARIO  _red;
SCENARIO  _yellow;
SCENARIO  _white;
SCENARIO  _stop;
SCENARIO btns[4] = { _red,  _yellow, _white, _stop};

void setup()
{
  _stop.Lamp_Pin = 8;
  _stop.PB_Pin = 4;

 ///// initializing other 3 objects i.e. red & white & yellow
 ////
for (int i = 0; i < 4; i++)
  {
    Serial.print(i);Serial.print(":");
    Serial.print(btns[i].Lamp_Pin);Serial.print(":");
    Serial.println( btns[i].PB_Pin );
    //pinMode(  btns[i].Lamp_Pin, OUTPUT);
    //pinMode(  btns[i].PB_Pin, INPUT);
  }
}

The image below shows what I get. It seems I have not initialized the variables!

The problem is that a struct is handled as a value type, not as a reference type.
This means that a copy of _stop is made and put in btns (btns[3] actually).
So what you need to do is putting pointers into the btns array:
SCENARIO* btns[4] = { &_red, &_yellow, &_white, &_stop};

The symbol * denotes a pointer, and & means the address of a variable (so it points to the variable and is not a copy).
Now when you change _stop, also btns[3] which points to _stop will show the correct initialized value.
For printing you should use:
Serial.println( (*btns[i]).LampPin);Serial.print(":");
Serial.println( (*btns[i]).PB_Pin );

Because *btns[i] is a pointer, but because this is a very often used feature, a special notation can be used:
Serial.print(btns[i]->Lamp_Pin);Serial.print(":");
Serial.println( btns[i]->PB_Pin);

Thanks! Coming from managed world, I forgot the pointers behavior!

@BehzadSedighzadeh Luckily in C# they don't exist anymore, but with programming lower level devices, you don't want to rely mostly on automatic memory allocation and garbage collection and pointers are 'directly to the point(er)'.

If an answers helped you, upvote it (arrow next to the question), for the best answer, accept the answer (under the arrows next to a question).

In this line:
SCENARIO btns[4] = { _red,  _yellow, _white, _stop};

you are making 4 copies of the structures and placing them in an array.
Instead you should either create the array directly with the values:
SCENARIO btns[4] = {
    {-1, -1},
    {-1, -1},
    {-1, -1},
    {8, 4}
};

And only use the array, or use pointers in the array:
SCENARIO *btns[4] = { &_red,  &_yellow, &_white, &_stop };

and then access the entries as pointers:
Serial.print(btns[i]->Lamp_Pin);
Serial.print(":");
Serial.println( btns[i]->PB_Pin );

Thanks. I mostly code in C# and in this case I had forgotten Array of structures looks different than managed world!


text:
Behaviour of tone() not as expected within while loop
I have a smoke detector with a piezo buzzer. I want to operate the arduino in low power mode so that it will last on a 9V battery. I've attached an interrupt, and when the digital output of the MQ-2 sensor goes high, it switches to a monitor function.
In the while loop, I check to see if the analog sensor has reached the threshold value, and I output to serial to see if I am in the conditional. If I use:
digitalWrite(buzzer, HIGH);

then the piezo sounds, however if I use
tone(buzzer, 1000,200);
delay(200);

it does not. I'm confused as to why this would be the case.
Full code as follows:
#include "LowPower.h"

int redLed = 12;
int greenLed = 11;
int buzzer = 10;
int smokeA0 = A5;
// Your threshold value
int sensorThres = 50;
int smokeD0 = 2;

void setup() {
  pinMode(redLed, OUTPUT);
  digitalWrite(redLed, LOW);
  pinMode(greenLed, OUTPUT);
  digitalWrite(greenLed, HIGH);
  pinMode(buzzer, OUTPUT);
  pinMode(smokeA0, INPUT);
  pinMode(smokeD0, INPUT);

}
void switchToMonitor() {
  Serial.begin(9600);
  int digitalSensor = digitalRead(smokeD0);
  if (digitalRead(smokeD0) == HIGH)
  {
    digitalWrite(redLed, HIGH);
    digitalWrite(greenLed, LOW);
  }
  else {
    digitalWrite(redLed, LOW);
    digitalWrite(greenLed, HIGH);
  }
  //This will be updated later to use the analog input
  //Using digital to make debugging easier
  while (digitalSensor == HIGH) {
    int analogSensor = analogRead(smokeA0);
    Serial.print("Pin A0: ");
    Serial.println(analogSensor);
    Serial.print("Pin D0: ");
    Serial.println(digitalSensor);
    // Checks if it has reached the threshold value
    if (analogSensor > sensorThres) {
      digitalWrite(buzzer, HIGH);
      //tone(buzzer, 1000,200);
      Serial.println("here");
      delay(1000);
    }
    else {
//      digitalWrite(redLed, LOW);
//      digitalWrite(greenLed, HIGH);
      noTone(buzzer);
      Serial.println("also here?");
    }
    //delay(100);
    digitalSensor = digitalRead(smokeD0);
  }
  noTone(buzzer);
}

void loop() {
  //delay(100);
  //LowPower.standby();
  attachInterrupt(0, switchToMonitor, CHANGE);
  LowPower.powerDown(SLEEP_FOREVER, ADC_ON, BOD_ON);
  detachInterrupt(0);
}

@Juraj The tone function works when used within void loop() and not switching between low power and operational. It's only not working in the code example given

connect the buzzer to a battery ... does it make a sound?

You can't use delay() or timer based tone() function in interrupt handler. Set a flag in interrupt and run the code  in loop() conditionally based on the flag state. Do not forget to have the flag variable volatile.

Took it out of the interrupt handler and it worked. Thanks


text:
How to get the body of an HTTP request?
I want to read a binary body datas from an HTTP POST request.
The context is that I'm making a LED strip controller and I'm currently using this code :
#include <WebServer.h>
#include <Adafruit_NeoPixel.h>

Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, STRIP_PIN, NEO_GRB | NEO_KHZ800);
WebServer server(80);

void handleSimpleWrite()
{
    int r = 0, g = 0, b = 0;
    if (server.hasArg("red"))
        r = server.arg("red").toInt();
    if (server.hasArg("green"))
        g = server.arg("green").toInt();
    if (server.hasArg("blue"))
        b = server.arg("blue").toInt();
    strip.setPixelColor(id, r, g, b);
    strip.show()
    server.send(200,"Ok");
}

It works, but it's clearly innefficient. I want to make an API endpoint that get a binary buffer with RGB states along the request body and I can't figure out how to read this body.
Any ideas ?

this may help ... https://startingelectronics.org/tutorials/arduino/ethernet-shield-web-server-tutorial/SD-card-AJAX-XML-web-server/

esp8266 has arg("plain"). esp32 doesn't have it. can't you use plain WiFiServer?

@jsotola this library seem to be for AVR based Arduino, the header is unknow for my board
@Juraj I think that arg("plain") is stay working when looking in the source code.
I will edit libraries/WebServer/src/Parsing.cpp to fit my needs.

i send a long string of hex pairs, and it works well. use websockets instead of http to get more bandwidth.

What does efficiency mean here? -- Did you do any calculations about efficiency, if you mean speed? I mean, how fast will you change the RGB values? And how fast is the network connection? And how fast is the code you show? -- I'd leave it as is, because it is a clear and simple interface, and I assume that network and CPU are much faster than needed for this simple task.

@thebusybee you are right. I said that's not efficient because to set a different color on each LED, you need to perform an HTTP request for each LED, more than 500 in my case...

How about putting all 500 LED colors in a single POST? Even as string representation this is just a few KB, transferred in milliseconds.


text:
TX pin sends wrong data in Arduino Uno
I want to send some data to an IP Modem from Arduino Uno. That IP Modem has TTL levels TX and RX inputs.
I used this connection between Arduino to the IP Modem:

I am powering Arduino with 12 V plugged in the barrel.
This is the photo of the connections:

I connected the PC to the USB connector of Arduino and I uploaded the following sketch to send "AABB" to the Modem:
void setup(void) {
  Serial.begin(115200);
}

void loop(void) {
 Serial.print("AABB");

 delay(5000); // Envía la temperatura cada 5 segundos
}

When monitoring what is received by the modem, it is
0x5F 0x5F 0xAF 0x2F
If I send just "A", the character received each 5 seconds is 0x5F.
Of course, both ends are configured as 115,200bps, 8N1.
In order to discard Modem problem, I connected RX, TX and GND in Arduino to a DB9 female connector and then to a RS232 - USB converter and started monitoring with my PC.
My surprise was that the data received is exactly the same as the received by the modem when it was connected. As seen in the following picture:

As you see in the picture, "_" twice was shown (ASCII 0x5F), {\xaf} and finally "/" (ASCII 0x2F).
Above test confirms Arduino is sending wrong data.
Something to note. When I monitor using USB cable connected to Arduino and using Monitor Serie in the Arduino IDE, I  see correctly "AABB". The problem is when using TX and RX pins (the same happened if I used other pin along with SoftwareSerial library)
What may be going on?

pins 0 and 1 are used by the serial port to the PC ... choose some other pins and use software serial ...lots of examples can be found

Sorry, but It seems you did not read the whole question. I have connected pins 0 and 1 to the PC. Furthermore, I have done the same using SoftwareSerial library using other port. The same problem happens (as the final of the question tells)

i only read to the first picture ... it shows an interference between USB serial and the IP modem ... it is pointless to read any further

@jsotola as a teaching, don't read only the introduction to get the whole knowledge of a text

i understand what you are saying ... i simply made a comment about the first problem i saw .... please add your sketch that uses software serial

Please see the answer

Arduino and (all that Hardware like Arduino usb adapters) is sending Inverted (passiv is high) an the pc and all the "old" Hardware is sending NOT inverted. Only Software. Srial van send inverted - the hardware Serial can not. Same with ESP32 etc.

@Funkerman Yes.. I realized about that. I am electronical engineer so I understand electronical concepts however I am new to Arduino, but with this kind of problems I am facing, I can understand better how Arduino works. When I have more free time, I will take a look at Arduino cirtuit schematics. Also, if I develop more projects in Arduino, I will evaluate purchasing an oscilloscope to see the actual signals pins are sending.

Since you have already tried SoftwareSerial, also try inverting the serial protocol via SoftwareSerial.  Sometimes a device uses inverted serial protocol and you don't know it.
So initialize inverted add 1 to the end of the contructor like so :
SoftwareSerial mySerial(RXPIN, TXPIN,1); // RX, TX, inverted

you are a genius!! after 2 days of fight, that was the solution!

@jstuardo Additional note for faster research results the next time: Write down the bits as they are sent, and as they are received. Asynchronous serial communications uses LSB first here. 'A' = 0x41 = 0b01000001. Sent:0-1-0-0-0-0-0-1-0-1 Received: 0-1-1-1-1-1-0-1-0-1. I think it's quite obvious. ;-) Alternative way: Use an oscilloscope and watch TX and RX.

@thebusybee that is transparent for the systems. Sender always sends the data using LSB first, and receiver receives the data with LSB first. By the way, if 0x41 (0b01000001) is sent, it is actually sent 1-0-0-0-0-0-1-0 and received 0-1-1-1-1-1-0-1. I don't know why do you showed different bit pattern. And using oscilloscope is interesting, however, it is not really necessary for now. The key point here is that inverted bits are actually transmitted.

Yes, I know about the inverted bits. I added the start and stop bits to show that they are relevant for the analysis. -- And since I don't know your (and future readers') experiences I mentioned "LSB first." Not all serial communication protocols use this.


text:
Addressable LEDs vs Multiplexing for a Matrix
I would like to building a 8x64 RGB Matrix and connect it to my Arduino.
As this form factor does not really exist I would need to build one myself but now I am wondering if I should use addressable LEDs like WS2813 or APA107 and use FastLED or rather use 'dumb' LEDs and just multi-/charlieplex them using a MAX7221 or comparable chip.
What are some pros and cons I should consider with each one? I read that to many WS2813 can make problems but APA107 seem to fix that. But on the other hand most bigger matrices just use multiplexing........

the WS2813 would require way less hardware for interfacing

Cost would be one factor. Durability is another. When one of the addressable leds fail, all the leds after it would fail too (though the WS2813 has a BIN pin to "fix" that). I heard they aren't as reliable as dumb leds with separate drivers.

The smart RGB LEDs will be brighter. Each device has its own control chip that controls the 256 PWM level for each of the 3 LEDs. So for an 8x64 array, you send in 3 bytes/device, 8x64x3 = 1535 btyes, pause a few microseconds, and the array updates itself.
Going the multiplexing route, you would do something like have 64x3 = 192 anode drivers (or up to 192, if not all are LEDs are lit up) to enable the LEDs across the display, and then 8 common cathode drivers to turn on each row one at a time for 1/30 to 1/24 of a second for minimal flicker. So 192 LEDs, 20mA each, the common cathode needs to be able to sink 3.84A
On the otherhand, 8x64 LEDs, each needing up to 60mA at full on, = 30.72A.

You are assuming common cathode leds here. There are also common anode RGB leds. Secondly 643 x 8 isn't the only configuration possible. You could wire it as if it's a 323 x 16 matrix etc. The latter would require fewer chips, but would be less bright.

Any kind of multiplexing will be less bright. Common anode, common cathode, turned in rows, turned on as columns.


text:
How to calibrate MPU 6050 thermometer?
I'm using MPU 6050 and there's a thermometer onboard. However, I looked through the chip set data sheets but could not find the instruction for temperature sensing.
Could you tell me how to calibrate the data string from the two address started from 0x41?

The temperature sensor is likely included to keep the gyroscope and accelerometer better calibrated over the specified temperature range.  The temperature may not be the ambient temperature should the chip warm up.
The temperature sensor specifications are in section 6.3 on page 14 of the specification sheet indirectly pointed to in the question.
TEMPERATURE SENSOR
Range -40 to +85°C
Sensitivity Untrimmed 340 LSB/ºC
Temperature Offset 35ºC -521 LSB
Linearity Best fit straight line (-40°C to +85°C) ±1°C

So, when the chip is at 35C the chip temperature register is supposed to read about -521.  To convert that into C you need to make a calculation:

chip_temperature = ((value_read + 521) + (35 * 340)) / 340

Simplified:

chip_temperature = (value_read + 12421) / 340

This looks like the right conversion above, 35C, but I get some weirdness below, it becomes 229. Also of interesting note, the well known i2cdevlib library has code for the MPU6050, and example code exists for reading temperature using mpu.readTemperature(); however, no such method seems to exist in the library (anymore?). There is something called getTemperature(); but that gives out data raw, not converted. How very strange.

I would check the math and also pay attention if the code is performing integer arithmetic and causing rounding errors.  In which case add decimal points to your numbers in an effort to force floating point math.  I'm not familiar with i2cdevlib as I've been using the drivers from the OEM.  But if no one answers your question here, I would post an issue (ask your question) over in the i2cdevlib github web pages.

Yeah, I suspected it was something like that. Re-inspired, I took another crack at casting all the variables, and I got it to behave more or less as it should. Looks like it was because I wasn't casting the uint16 returned (what would be value_read above) up to float before adding and dividing. Incidentally, I'm using a Longan nano, not an Arduino. The inbuilt screen lib for displaying text doesn't like floats, so I was trying to avoid them. Looks like I was trying too hard. Either way, the math you provide is good. +1


text:
How to create real-time WASD control over an Arduino Uno?
I am trying to figure out how to use the WASD keys on my computer, to go through the USB cable and then spin the Arduino servos in real-time. So if I press the “a” key, it should start to move left with little time delay. How do I do this?

do it is steps ... first write code to get data from the PC to the arduino .... when you are successful, add code to move servos

why this way? you could start some serial terminal program which sends the character immediately, but much simpler is to put 4 buttons on breadboard or to use a small joystick

In any case you need some software on your PC to send the key events to the Arduino. The simplest solution can be the Serial Monitor of the IDE. Try this and if you have problems with the Arduino sketch, feel free to [edit] your questions. BTW, you might like to take the [tour] and learn [ask].


text:
How to determine minimum and maximum angle for cheap servos?
I have some cheap KY66 (seems to be SG90 clone) servos.
When I turn them to 0°, the servo tries moving and moving, without actually getting to 0°. I read that they are reaching the endpoint but the built-in potentiometer does give a reading of 0.
By changing the code and fiddling with the angle, I find that the minimum for one particular servo is 25°.
I'm now trying to figure out how the Arduino could determine this value automatically. I have tried
servo.write(0);
delay(3000);
int direction = servo.read();

and expected to get back a value near 25, but it was 0 instead. So the result of read() does not seem to be an actual reading, but more the "last known" setpoint.
I've also tried to relax the servo before reading:
servo.write(0);
delay(3000);
int direction = servo.read();

with no better result.
I like to figure out the minimum and maximum angle of the servo

because I don't like the servo to make much noise (it really doesn't sound healthy)
without having the user to figure out by himself and the need of re-programming the Arduino.

I know that these cheap servos only have 3 pins. 2 pins are for power supply only, so there's only 1 pin left.
My questions:

Is the data pin uni-directional (PWM output from Arduino to servo)?
Will it ever be possible to implement what I want without additional hardware?
How do people solve this issue? Do more expensive servos either have better calibration to actually go from 0° to 180° or do they provide a way to read the potentiometer with another pin?

Is the data pin uni-directional (PWM output from Arduino to servo)?

As you found out, standard servos have only three pins. And yes, two of them provide ground and power, and the third is a unidirectional signal.
This signal is commonly a pulse of 1 ms to 2 ms, repeated every 20 ms.
servo.read() can therefore only return the last value set by servo.write().

Will it ever be possible to implement what I want without additional hardware?

I don't think so.
You could insert a shunt into the power line and measure the current. If it stays high for extended periods, it means that the servo is still powering its motor. But this could be true also for other reasons than being at its own mechanical limit.

How do people solve this issue? Do more expensive servos either have better calibration to actually go from 0° to 180° or do they provide a way to read the potentiometer with another pin?

Since servos are used as a closed (sub-)system, I don't think that they are opened to read their potentiometer. And even if you do this, you might affect the internal working of the servo.
Eventhough I built several model aircrafts since the late 70s and used different servos, I have no feeling about the calibration of cheap or expensive servos. IIRC some data sheet documented ranges of only +/- 45°.
So the values 0 to 180 for servo.write() is just a mapping for 1 ms to 2 ms.
To make a long story short, I have no idea how people solve this.
You might like to limit your range to some "healthy" values, or ask the user to help in calibration. The calibration results can be stored in EEPROM, there is no need to reprogram the Arduino.
If you need the robot's head to turn from 0° to 180°, consider using some gear so that the servo just needs to move between, let's say, 30° to 150°. This is the way modellers go.

I think you have 2 choices: either measure and store for each one individually, or find the worst case for all of them and code around that.
Do you really need the full travel? If you're using the servo to push/pull, the servo-travel endpoints are pretty weak anyway.

I wanted a robot look left and look right, which is 0° or 180°.

Maybe you can make up the limited angular travel of the servo in the linkage between the it and the camera platform.

Indeed I wanted a robot look left and look right, which is 0° or 180°. 25° is quite a bit off. But well, it seems I need to consider that.


text:
Is the shiftOut code depending on the (low) speed of an Arduino?
In the (official) file wiring_shift.c I found the following code for shiftOut:
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        if (bitOrder == LSBFIRST)
            digitalWrite(dataPin, !!(val & (1 << i)));
        else
            digitalWrite(dataPin, !!(val & (1 << (7 - i))));

        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);
    }
}

However, the last two digitalWrite commands occur directly after each other. I wouldn't hope that digitalWrite depends on some time or delay, so how can it be assumed that the slave device sees the clockPin is HIGH if the Arduino immediately sets the clockPin to LOW again?
(My plan is to convert the shiftIn/shiftOut code to STM32 using HAL/CubeIDE).

Some time ago, I timed digitalWrite() and direct port write commands by looping over 10,000 executions of each and timing them with millis(). I made both tests on a 16MHz Atmega 328p at 16MHz.
For digitalWrite(13, LOW), I got 2.7usec / call.
For PORTB &= 0x20;, I got 0.15usec / statement. (The direct port access was executed 10 times within the loop to further pad it out for the millis() result to have any significance.)
[In my notes I wrote that I timed PORTB &= 0x20;, but the correct equivalent to the digitalWrite() version is PORTB &= ~0x20;. That is probably what I actually did, but note that the bit-mask would be generated at compile time, so either way should have produced the same result.]

how can it be assumed that the slave device sees the clockPin is HIGH

It would depend on the specifics of the slave, but it is quite likely triggered by a pulse, rather than polling its input until it finds a high-level.
Update:
To confirm my timing data, I redid my 2.5-years-ago experiment. I put 10 statements in each of 2 loops of 10,000 iterations, either:
digitalWrite(13, LOW);

or
PORTB &= ~0x20;

And got these total times in msec for the 100,000 executions:
digitalWrite(): 305     // digitalWrite(13, LOW);
PORTB (correct): 15     // PORTB &= ~0x20;
These translate to single execution times in 10s of nanoseconds:
3050 nsec == 3.05 usec for the function call,
150 nsec for direct port I/O, making port I/O about 20x faster.

Re “either way should have produced the same result”: Not really. The compiler can see that PORTB &= ~0x20; affects a single bit, and compiles that to a single cbi instruction that executes in 2 CPU cycles (0.125 µs @ 16 MHz). PORTB &= 0x20; is likely going to give you a 3-cycle read-modify-write sequence (0.1875 µs).

Back to the drawing board... :)

@JRobert thanks for the explanation, the first part I knew (kind of), but the second really answers my question exactly. I know that for timing mostly an IC checks the middle of a fixed state (either high or low), but if it triggers for an edge, yes, than it doesn't matter (as long as of course the IC has the time to get fully HIGH for a rising edge or fully DOWN for a falling edge, but I'm sure that's in the ns scale).


text:
If-statement matches but doesn't give a result
I just started two weeks ago with Arduino and I'm hooked!
I got off to a good start and went through some online tutorials quite easily. Then came the RGB LED, which I couldn't get to work all of a sudden (it required putting in a color through the serial monitor, which would then be given by the RGB).
And the strange thing is, I can't get anything to work anymore that requires input through the serial monitor, where I used to get it working immediately...
I presume it's something with the if-statement, because if I remove it and just say digitalwrite HIGH to a certain pin, it works fine....
Checks I did:

Full re-install of Arduino (didn't solve it).
Check the LEDs by hooking them up to 5V directly (they all work).
Reconnecting the Arduino (didn't solve it).
Use a multimeter to measure current (there isn't, although the if-statement matches...

Here's my code. Does anybody see it? Because I don't...
Regards,
nannev (using Mac and Arduino Uno)
int yellowPin=8;
int redPin=9;
int greenPin=10;
String myLED;

void setup() {
  Serial.begin(9600);
  pinMode(yellowPin,OUTPUT);
  pinMode(redPin,OUTPUT);
  pinMode(greenPin,OUTPUT);
}

void loop() {
  Serial.println("Your color?");
  while (Serial.available()==0) {
  }

  myLED=Serial.readString();
  Serial.print(myLED); //check if the input came through correctly, which it did
  delay(1000);
  if(myLED == "yellow"){ .    //nothing happens at yellow....
    digitalWrite(yellowPin, HIGH);
    digitalWrite(redPin, LOW);
    digitalWrite(greenPin, LOW);
  }

  if(myLED == "red"){             //nothing happens at red....
    digitalWrite(yellowPin, LOW);
    digitalWrite(redPin, HIGH);
    digitalWrite(greenPin, LOW);
  }

  if(myLED == "green"){       //nothing happens at green....
    digitalWrite(yellowPin, LOW);
    digitalWrite(redPin, LOW);
    digitalWrite(greenPin, HIGH);
  }
}

check the line ending setting in Serial Monitor. 'yellow\r\n" is not equal to "yellow". you can trim the line ends with myLED.trim();

you can add Serial.print(myLED.length()); so that you can see how many characters there are in the string

"  if(myLED == "yellow"){ .    //nothing happens at yellow...." Look at the period after {. That's a Mac quirk: sometimes when you press space twice it converts it to ". " – there's no way your code is compiling as is.

@Juraj Wow, this solved it! It appeared that the length of the String was 1 character greater than the actual word. Strange though, that I had it working several times before without the Trim function. Thanks, wouldn't have come up with this myself.

@jsotola Thanks too!

the line ending in Serial Monitor is configurable. it worked without the Serial Monitor sending line end characters

The Arduino IDE uses the C and C++ programming languages.
Some string comparison basics using C:
In the C programming language, a string can be thought of as an array of 8 bit values.  One way to compare two strings is to compare each 8 bit value and consider the strings different (not equal) upon finding the first not-matching 8 bit value.  Here is an example from programmingsimplified.com:
int compare_strings(char a[], char b[])
{
   int c = 0;

   while (a[c] == b[c]) {
      if (a[c] == '\0' || b[c] == '\0')
         break;
      c++;
   }

   if (a[c] == '\0' && b[c] == '\0')
      return 0;
   else
      return -1;
}

There is a common function called strcmp() which can be used instead.  Here is another example from the same web page which uses strcmp():
#include <stdio.h>
#include <string.h>

int main()
{
   char a[100], b[100];

   printf("Enter a string\n");
   gets(a);

   printf("Enter a string\n");
   gets(b);

   if (strcmp(a,b) == 0)
      printf("The strings are equal.\n");
   else
      printf("The strings are not equal.\n");

   return 0;
}

Note that in both cases the array of strings is assumed to end with a NULL or zero value byte.  If you do not wish to follow this format you can use an alternate version of the function called strncmp() where the number of characters to be compared is passed along with pointers to the 2 strings.
Some string comparison options using C++:
There are C++ ways to compare 2 strings which make coding Arduino Sketches easier.  But C++ string manipulation usually requires more RAM.  And RAM is usually in short supply on inexpensive embedded processors.
As the code in the question is written using type String we can explore that approach. And, as there is some concern the strings may have unexpected trailing characters, we will continue to check only the necessary number of characters. In this slightly modified code example from geeksforgeeks.org string s1 is compared with string s2.  But only the first 6 characters are compared:
void compareOperation(string s1, string s2)
{
    // Compares 5 characters from index number 3 of s2 with s1
    if((s2.compare(0, 6, s1)) == 0)
        cout << "Here, "<< s1 << " are " << s2;

    else
        cout << "Strings didn't match ";
}

The number 6 was chosen because "yellow" contains 6 printable characters.  In this way, we can avoid the uncertainty of what character(s) follow the characters that make up "yellow" as received from the serial port.

the Arduino String class has == operator overloaded to compare with char*. why this complicated off-topic answer?

The "compare()" was the 1st example found. So it was used. Also, there was talk in the comments about string length and problems with different unprintable characters after the desired printable word. So I offered a solution which mitigated problems associated with unprintable characters by counting the number of characters to compare. Lastly, this is an Arduino forum. Most Arduino platforms contain a very-low-cost embedded processor with very-limited resources. So it is almost always better to control string manipulation explicitly with clearly defined string lengths using C programming.

I've changed the answer making it clear that the 1st part is C and the 2nd part is C++.  I also added text explaining that character counting in both examples was used to mitigate any differences between the 2 strings which might occur after the desired word.

all true but not an answer. the compare failed only because the Serial Monitor input did contain line ends. this as a common mistake by beginners


text:
Cannot call function in call back for onRequest()
I am a NOOB!  Trying to use the ZS-042 RTC module to retrieve the current time and send it back to the RPi over I2C.  I can call the function and spool it to Serial but when I try to call the function to update the global variables from within the call back function for onRequest() the Ardiuno (Micro) crashes.
#include <Wire.h>

// LED on pin 13
const int TEMP_PIN1 = A0;
const int RELAY_PIN1 = 4;
const int SAMPLE_TIME = 100;
const byte RPI_I2C_ADDRESS = 0x08;
const int DS3231_I2C_ADDRESS = 0x68;

byte number = 0;
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

/*
 * RTC Setup
 */
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return( (val/16*10) + (val%16) );
}
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
      dayOfMonth, byte month, byte year)
{
  // sets time and date data to DS3231
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(second)); // set seconds
  Wire.write(decToBcd(minute)); // set minutes
  Wire.write(decToBcd(hour)); // set hours
  Wire.write(decToBcd(dayOfWeek)); // set day of week (0=Sunday, 6=Saturday)
  Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
  Wire.write(decToBcd(month)); // set month
  Wire.write(decToBcd(year)); // set year (0 to 99)
  Wire.endTransmission();
}

/*
void readDS3231time(byte *second,
    byte *minute,
    byte *hour,
    byte *dayOfWeek,
    byte *dayOfMonth,
    byte *month,
    byte *year)
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}
*/

void readDS3231time()
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  second = bcdToDec(Wire.read() & 0x7f);
  minute = bcdToDec(Wire.read());
  hour = bcdToDec(Wire.read() & 0x3f);
  dayOfWeek = bcdToDec(Wire.read());
  dayOfMonth = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read());
  year = bcdToDec(Wire.read());
}

void displayTime()
{
  //byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  //readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  readDS3231time();
  // send it to the serial monitor
  Serial.print(hour, DEC);
  // convert the byte variable to a decimal number when displayed
  Serial.print(":");
  if (minute<10)
  {
    Serial.print("0");
  }
  Serial.print(minute, DEC);
  Serial.print(":");
  if (second<10)
  {
    Serial.print("0");
  }
  Serial.print(second, DEC);
  Serial.print(" ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print(year, DEC);
  Serial.print(" Day of week: ");
  switch(dayOfWeek){
  case 0:
    Serial.println("Sunday");
    break;
  case 1:
    Serial.println("Monday");
    break;
  case 2:
    Serial.println("Tuesday");
    break;
  case 3:
    Serial.println("Wednesday");
    break;
  case 4:
    Serial.println("Thursday");
    break;
  case 5:
    Serial.println("Friday");
    break;
  case 6:
    Serial.println("Saturday");
    break;
  }
}

void flash_data(int loops)
{
   for (int i = 0; i < loops; i++)
   {
      digitalWrite(LED_BUILTIN, HIGH);
      Serial.println("LED Pin HIGH: "+String(digitalRead(LED_BUILTIN)));
      delay(50);
      digitalWrite(LED_BUILTIN, LOW);
      Serial.println("LED Pin LOW: "+String(digitalRead(LED_BUILTIN)));
      delay(50);
   }
}

// callback for received data
void receiveData(int byteCount)
{
  Serial.println("Receiving Data... ");
  if ( Wire.available() ) {
    number = Wire.read();
  }
  Serial.println("Data Received: "+String(number));
}

void sendData() {
  Serial.println("Sending Data on Request");
  //byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  //readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  readDS3231time();
  //char buf1[20];
  //sprintf(buf1, "%02d:%02d:%02d %02d/%02d/%02d",  hour, minute, second, dayOfMonth, month, year);
  //Serial.print(buf1);
  Wire.write("Hello");
}

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

  delay(500);
  Serial.println("Initializing Wire I2C on "+RPI_I2C_ADDRESS);
  // Join I@c bus as slave with RPI_I2C_ADDRESS 8
  Wire.begin(RPI_I2C_ADDRESS);

  Serial.println("Setting call back for Wire.onReceive");
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData);

  //Setup pin 13 as output and turn LED off
  Serial.println("Setting LED Pin up for Output");
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(RELAY_PIN1, OUTPUT);
  pinMode(TEMP_PIN1, INPUT);
  Serial.println("Turning LED off");
  digitalWrite(LED_BUILTIN, LOW);
}

float getVoltage(int pin)
{
  // This function has one input parameter, the analog pin number
  // to read. You might notice that this function does not have
  // "void" in front of it; this is because it returns a floating-
  // point value, which is the true voltage on that pin (0 to 5V).
  return (analogRead(pin) * 0.004882814);
  // This equation converts the 0 to 1023 value that analogRead()
  // returns, into a 0.0 to 5.0 value that is the true voltage
  // being read at that pin.
}

/*
 * MAIN LOOP
 */
void loop() {

  if ( number > 0 ) {
    //Serial.println("Flash Data: "+String(number));
    flash_data(number);
    float voltage, avgVoltage, degreesC, degreesF;
    if (number == 1) {
      digitalWrite(RELAY_PIN1, HIGH);
    } else if (number == 2) {
      digitalWrite(RELAY_PIN1, LOW);
    } else if ( number == 3 ) {
      voltage = getVoltage(TEMP_PIN1);
      //gets and prints the raw data from the lm35
      Serial.print("Voltage: ");
      Serial.print (voltage);
      Serial.println(" ");
      // Now we'll convert the voltage to degrees Celsius.
      // This formula comes from the temperature sensor datasheet:
      degreesC = (voltage - 0.48) * 100.0;
      Serial.print("CELSIUS: ");
      Serial.print(degreesC);
      Serial.println("*C ");
      //converts celsius into fahrenheit
      degreesF = degreesC * (9.0/5.0) + 32.0;
      Serial.print("FAHRENHEIT: ");
      Serial.print(degreesF);
      Serial.println("*F");
    } else if ( number == 4 ) {
       displayTime();
    }
    number = 0;
  } else {
    byte pinValue = bitRead(LED_BUILTIN, 3);
    if ( digitalRead(LED_BUILTIN) == HIGH ) {
      digitalWrite(LED_BUILTIN, LOW);
    }
  }
  delay(SAMPLE_TIME);
}

Any guidance would be appreciated!
THanks

Could you please show a schematic of your circuit? Do you really want your Arduino to be both a master and a slave on the I2C bus? Why not connect the Pi through Serial?

The onRequest and onReceive callback functions are called from inside an ISR. Thus you cannot use any code in there, that relies on interrupts to work. Serial writes or prints for example will only work, as longs as the buffer is not full (since the actual communication is handled by interrupts). If the buffer is full, the serial code will either block or loose data (depending on the version of the Arduino core. Not blocking in an ISR is a relatively new change). Such things also hapoen with other interrupt driven functions.
Let's take your codes logic particular in the onRequest callcack function. As written above, this is called from an ISR. The Wire library was contacted by the master to send data to it. With this callback the library uis asking you, what to answer the master. During that time, the current transmission (master read, slave send) is already active, but the slave is stalling the transaction, until the data is ready, meaning until you exit the onRequest callback. Now inside the callback you try to initiate another transaxtion on the same I2C bus, now as a master. The same I2C bus, where there is already a transaction going on. That cannot work. The former slave cannot take the control over the bus, since the first master haven't released it yet (as you tried this in the middle of it's transaction. So you are not only using interrupt driven functions in an ISR, you are also trying to reconfigure hardware, that you just got an interrupt from (which is a bad idea, unless you really know, what you are doing). The library has configured the hardware as slave and in the middle of the transaction you try to configure it as master.
I don't know, why you even try to do this. Since you already have the RTC on the same bus as the Pi, why not making the Pi the only master and let it directly poll the RTC? Why do you need the Arduino between them?
If you really really need the multi master setup for whatever reason (though I cannot think of one), you have to do the transactions independent of one another. The Arduino could poll the RTC regularly, when the bus is free, and buffer the results. Then it could send these results to the Pi, when it requests the Arduino to do that.

Note: I'm currently not up to date, how good the multi master support in the Wire library is these days. It incorporated the possibility for multi master since a long time, but when I checked last time, the bus arbitration was not implemented (meaning that if 2 masters try to send at the same time, the bus gets stalled). If it is still this way, you shouldn't use multi master with the Wire library.

Thanks chrisl! Sorry everyone. I realized moments after posting that I am conflicting between the 2 I2C devices in the way I am trying to do this which I think aligns with chrisl's post. DUH! I should be able to make a request to the RTC directly from the RPi via it's address given they are both on the same I2C bus. I will post this definitely once I've tested but I am pretty sure that's what is wrong. Total Bone Head Move.


text:
How to set a time out like Serial.setTimeout() for Serial.read()?
I read a comment form here:
"Serial.setTimeout() sets the maximum milliseconds to wait for serial data when using Serial.readBytesUntil(), Serial.readBytes(), Serial.parseInt() or Serial.parseFloat(). It defaults to 1000 milliseconds."
According to the latest webpage,
"Serial functions that use the timeout value set via Serial.setTimeout():
Serial.find()

Serial.findUntil()

Serial.parseInt()

Serial.parseFloat()

Serial.readBytes()

Serial.readBytesUntil()

Serial.readString()

Serial.readStringUntil()

"
So apparently, there's no direct indication to set a timeout option for Serial.read().
How to set a time out like Serial.setTimeout() for Serial.read()?

You can't set timeout for read(), but you can use readBytes() to read one byte.
byte b;
int count = Serial.readBytes(&b, 1); // read one byte with timeout
if (count) { // 0 or 1
  Serial.write(b); //echo
}

So Serial.read() and Serial.readBytes() were like two different class of objects?

no. read() is the basic function. readBytes() is a function too and implemented with use of read().


text:
If Arduino connected to computer and opened up Serial Monitor, will Tx and Rx pin still be working?
Suppose one connected two of the Arduino Uno boards through Rx and Tx pins. Then, if one or both of the Arduino boards were connected to computer, and possibly opened up Serial Monitors, will Tx and Rx pin still be working? i.e. will Arduino still communicate through Rx and Tx pin when it's communicating to computer? If not how to make them working while connect to computer?

The USB FTDI chip is connected to the TX/RX pins. So serial may not work the way you expect.

Suppose one connected two of the Arduino Uno boards through Rx and Tx
  pins.

I assume you will connect the TX of one Arduino to the RX of the other
one and vice versa, which is the right way to connect them. As
theSealion explained in his answer, you shouldn't connect two TX Pins
together.

if one or both of the Arduino boards were connected to computer, and
  possibly opened up Serial Monitors

If you do that, the Arduino won't even notice.
Well, to be more accurate... there is a small chip on the Uno, near the
USB connector, labeled “MEGA16U2”. This chip is used as a USB/serial
converter, and it will notice when you connect the USB link and when
you open the port. However, the main chip (the big PDIP28), which is the
microcontroller that runs your sketch, will neither know nor care.

will Tx and Rx pin still be working?

Absolutely.

will Arduino still communicate through Rx and Tx pin when it's
  communicating to computer?

The RX will not communicate with the computer. What will happen is:

Whatever your Arduino writes to its serial port will be received by
both the other Arduino and the serial monitor.
Whatever you send through the serial monitor will be lost.
When you Serial.read(), you will get whatever was set by the other
Arduino.

The reason of this behavior is a 1 kΩ resistor that sits between
the Mega16U2's TX and the main microcontroller's RX. When you connect
this RX to the other Arduino's TX, which is low impedance (≈ 25 Ω),
that TX will “win”: a low impedance output overwhelms a high impedance
one.

how to make [two Arduinos communicating with each other] working while connect to computer?

There are a variety of ways for 2 Arduinos to directly communicate with each other while one or both are communicating with the Serial Monitor of a laptop computer over USB.

Use a UART for the Arduinos to communicate that is independent of the USB connection. (See https://www.arduino.cc/reference/en/language/functions/communication/serial/ )

Several Arduino-compatible boards such as the Arduino Mega 2560, Arduino Due, Arduino Uno Wifi Rev.2, etc. have 4 hardware UARTs; the pins of Serial1 (note the "1") could be used to communicate with another Arduino without interfering with the Serial (without a "1") UART communication over USB to a laptop. (Alas, the Arduino Uno has only 1 hardware UART).
The ATmega32u4-based Arduino Micro and Arduino Leonardo and ATmega32u4-based Arduino derivatives such as FLORA and many of the ARM-based Arduino derivatives such as the Teensy series have a USB interface that doesn't use any of the UART pins; so the pins of Serial1 (note the "1") could be used to communicate with another Arduino without interfering with the Serial (without a "1") non-UART communication over USB to a laptop. (Alas, the Arduino Uno has a USB interface that does use its only hardware UART pins).
Even the Arduino Uno, which has only 1 hardware UART whose pins are hard-wired to the USB interface chip, can bit-bang a slow simulation of a UART on other pins. See What's the difference between all the Software Serial Libraries? Which one is Arduino Nano compatible? .

Rather than try to simulate a UART in software (the timing is kind of tricky), it may be easier/faster to use some other less time-sensitive ways of communicating between Arduino Unos or other Arduinos, such as

SPI between 2 Arduinos (a); (b)
I2C between 2 Arduinos (a) (b)
PJON between 2 Arduinos
a few asynchronous communication protocols have no timing dependencies at all
etc.

I got exactly the same problem! I was using the Arduino Uno board with an Jtag ICE mkii for debugging which was working nice. As I begann to use the UART it was a heavy mess. The transmitting from Arduino to an external TTL-USB adapter was working but not in the other direction. I played hours before I saw this thread and that gave me the idea for looking into the shematic -> Bang! I saw the two resistors.
Lesson learned: Do not use the Arduino hardware without the rest of the tools! Thought it was a good idea to use the hardware for rapid development. Now it costs me more time that I thought...

You should't connect two TX Pins together. The Arduino has some protection resistors but even it is not recommended to connect two output pins.
The only save way to use the RX / TX pins directly is to remove the protection resistors (RN4A and RN4B in the reference design) or at least the RN4A  and use only one connection at a time. It doesn't help if you do not use the PC connection or doesn't open the Serial Monitor since the pins is still an output.
(Multiple RX Pins are no problem since they are inputs)
(And of course I know it could work with multiple TX pins together most of the time, but I would recommend it)


text:
Unconsistent time in arduino loop
I have this code:

The output looks like this:

Why are there non-periodically some extremely large values?
Thanks

Serial.println waits if the TX buffer is full. And ATmega32u4 handles the USB port in the background

is there a way to make it faster?

No code as image please. Copy and paste the code as text and format it with the {} button

As explained by theSealion in his answer, this may be due to the
different background tasks performed by the microcontroller. However, I
personally find that 1 ms looks excessive. My guess is that the
main culprit is the USB stack pushing all those bytes down the wire.
In order to check this, I wrote the following program. It measures a
histogram of the loop execution times and then prints it through the
serial port. Since the data is only printed after the measurements are
done, the serial port does not do any work while the timings are being
measured.
const int HISTOGRAM_LENGTH = 512;

uint16_t histogram[HISTOGRAM_LENGTH];

void print_histogram() {
    Serial.println(F("t (us)  count"));
    Serial.println(F("-------------"));
    for (int i = 0; i < HISTOGRAM_LENGTH; i++) {
        if (histogram[i] == 0) continue;  // skip zeros
        Serial.print(i * 4);
        Serial.print('\t');
        Serial.println(histogram[i]);
    }
    Serial.println(F("-------------"));
    Serial.flush();
}

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

void loop() {
    static uint32_t last_time;
    uint32_t now = micros();
    uint32_t dt = now - last_time;
    uint32_t bin = dt / 4;  // resolution of micros() is 4 us
    if (bin >= HISTOGRAM_LENGTH)
        bin = HISTOGRAM_LENGTH - 1;
    if (++histogram[bin] == UINT16_MAX) {
        print_histogram();
        exit(0);
    }
    last_time = now;
}

These are the results when run on an Arduino Uno:
t (us)  count
-------------
8       21888
12      65535
16      632
20      323
56      1
-------------

This shows that most loop iterations take 8–12 µs. Those iterations
that were interrupted took 16–20 µs. The outlier at 56 µs is
most likely the time between the program starting and the very first
iteration of loop().
Here, the only interrupt source that affects the measurements is the
timer interrupt. It fired exactly 955 times during the measurement
period, which is consistent with the number of samples recorded at
16–20 µs. We can see from this data that the timer interrupt takes
roughly 8 µs to run, which is quite reasonable. Again, I would not
consider a 1 ms delay as reasonable.

There are be several "tasks" and interrupts that run in the background and they influence how often the loop() function is called.
For example timer, usart ...
They all need some attention from time to time. If the need some really fixed execution time you must use something like a hardware timer.
and by the way: a maximum of ~1.1ms is not bad for such a small controller. :-)
And as a addition to your question in your comments: I don't think there is a way to make the loop faster. As long as you need the other tasks, you have do give them some time.

Thanks theSealion! In addition, the original problem for this question was that I am driving a stepper motor and I need to communicate with Raspberry Pi using UART. The problem is that when I send some data about the motor to RPi and the motor is already spinning very fast, I often loose a step because there is just way too big delay. Do you have any idea how to solve this?

I don't know how the arduino stepper library is implemented and why you are loosing steps, but in general:
Make sure you don't use any busy waits. Especially when you are communication with the Rapsberry (do not wait for characters to be available).

Alright, I am still figuring out the source of loosing steps and I think I found it. I think it has nothing to do with Serial.print. I would like to run stepper at 3000 steps per second. That means one pulse each 333,3 microsecond. And obviously when there is a ~1.1ms delay, it is too long delay not to loose a step.
BTW I am using AccelStepper library. Is there some possibility to figure this out

I don't understand "a maximum of ~1.1ms is not bad"

In addition, the original problem for this question was that I am
  driving a stepper motor and I need to communicate with Raspberry Pi
  using UART. The problem is that when I send some data about the motor
  to RPi and the motor is already spinning very fast, I often loose a
  step

Your stepper code has to run very consistently to maintain 3000 steps/sec without jitter or dropping steps. It must not have to wait for communication or any other task but be able to issue the next step command on-time. Some possible techniques to accomplish this:

Don't post an entire message to the Pi but send only a few characters at a time, between steps.
Talk to the Pi in shorter, tightly coded messages, and let the Pi expand them if it needs to.
Use the highest baud rate the Uno & Pi can reliably use.
Issue step commands in a timer-driven interrupt routine, with any stepper housekeeping done in the background, between step-commands.
Use a faster processor.


text:
How to power Nodemcu using 12 volt AC to DC adapter?
I am trying to make a small project using Nodemcu. My project is WiFi controlled LED, 2 LED's will blink at the same time. I have successfully uploaded the code and it works fine using USB connection. But I want to power the Nodemcu using 12 volts 1.5 amps AC to DC adapter. I have checked it in web search but I have not found an understanding circuit. please help me out guys.

You connect the + side of the adapter to VIN pin and the - side to GND.
You have to check the maximum voltage when using the VIN pin. Probably it means you 'waste' some power (but it's from a wall wart, so it should be ok). See the remark of Flyingfenix below for heating consequences.
See this link: Power Related ESP-12E Development Board Pins, fragment 'Using a Wall Wart':

Examples: Wall-Mount-AC-Adapters
The current (1.5A) should be more than enough; the adapter's current should be higher than what is needed by the NodeMCU + circuit. So this is ok.

Thankyou Michel Keijzers. I will go ahead and try the connection today. cheers..!!

Please note that the regulator used (AMS1117 3.3V or equivalent) is a linear regulator, meaning that it "wastes" everything above 3.3V as heat. Using a 12V or above supply and loading the module's outputs/using wifi means it will run very hot - possibly even damaging it. Use, if possible, a 5V wall wart - temperatures will be much lower.

@Flyingfenix Thanks for the remark, I put a forward in my answer to your comment.

NodeMCU is not an Arduino and I've seen stories about them burning up when supplied with voltage too high.

@S.Imp Thanks for that remark, I removed the +20V as I cannot find it (anymore).

@MichelKeijzers your answer is pretty helpful. You might offer a link to 3.3V wall warts or to one of the voltage regulators mentioned here

You could just use a buck converter or linear regulator outside the NodeMCU, and power it with 5V, it will save your NodeMCU's tiny SMD components, If you look on the underside of most of these boards, the given maximum is 10V and recommended 5V


text:
esp8266 cant make more than one request at time
i am trying to make a get request, read that request and make another request with that read value. i havent shown it in this code but i want to make a request inside in a request. is it possible to make a request without ending one, if its, how do i do that?
here is the code :
#include <ESP8266WiFi.h>

#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>

#define WIFI_SSID "ssid"
#define WIFI_PASSWORD "pw"

void conn();
void getreq();
void anothergetreq();

void setup() {
  conn();
  getreq();
}

void loop() {
}

void getreq() {
  std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
  client->setInsecure();
  HTTPClient http;

  http.begin(*client, "https://jsonplaceholder.typicode.com/users/1");

  int httpCode = http.GET();
  String payaload = http.getString();
  Serial.print("HTTP CODE: "); Serial.println(httpCode);
  Serial.print("PAYLOAD: "); Serial.println(payaload);
  //here i presume got the value from payload, and making another request with it
  anothergetreq("posts/1");
  http.end();

}
void anothergetreq(String p) {

  std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
  client->setInsecure();
  HTTPClient http;

  http.begin(*client, "https://jsonplaceholder.typicode.com/"+p);

  int httpCode = http.GET();
  String payaload = http.getString();

  Serial.print("HTTP CODE: "); Serial.println(httpCode);
  Serial.print("PAYLOAD: "); Serial.println(payaload);
  http.end();
}

void conn() {
  Serial.begin(9600);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(300);
  }
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();
}

here is the output:
Connected with IP: 192.168.1.100

HTTP CODE: 200
PAYLOAD: {
  "id": 1,
  "name": "Leanne Graham",
  "username": "Bret",
  "email": "Sincere@april.biz",
  "address": {
    "street": "Kulas Light",
    "suite": "Apt. 556",
    "city": "Gwenborough",
    "zipcode": "92998-3874",
    "geo": {
      "lat": "-37.3159",
      "lng": "81.1496"
    }
  },
  "phone": "1-770-736-8031 x56442",
  "website": "hildegard.org",
  "company": {
    "name": "Romaguera-Crona",
    "catchPhrase": "Multi-layered client-server neural-net",
    "bs": "harness real-time e-markets"
  }
}
HTTP CODE: -1
PAYLOAD:

https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/readme.html#bearssl-client-secure-and-server-secure

Secure clients and servers require siginificant amounts of additional
  memory and processing to enable their cryptographic algorithms. In
  general, only a single secure client or server connection at a time
  can be processed given the little RAM present on the ESP8266

you have two BearSSL::WiFiClientSecure instances at time. it is simple to change your code to first free the first SSL client object.

i got the compile error "'client' was not declared in this scope" if i only use one ssl client object.

you can use two. only delete the first (from runtime memory, not from code) before using the second. it is possible that calling http.end() before making the second request will be enough

i dont know how to free that allocated memory, could you please show me. i managed to fully run and get the response by stopping client using  client->stop();. thank you.


text:
What are these stray resistors on the Arduino Mega schematic?
I am using the Arduino Mega schematic found here and it's mostly clear, but there are a few resistors floating in the middle and I'm not quite sure what they're for or where they go:

Does anyone know what these are and where they go?

Those are unused resistors in resistor arrays.  The arrays have 4 resistors side by side in a single package. Not all of the elements are always needed, but they have to be in the schematic anyway since they exist in real life.

Elements A and D of Resistor Network 1 (RN1)
Elements B and C of Resistor Network 2 (RN2)
Element C of Resistor Network 3 (RN3)

That's why many EDAs/ECADs have a "not connected" symbol (usually a "x" of some kind) to make clear that something is left unconnected on purpose (and not because the designer forgot to connect it). Also, when checking the nets, they'll raise an error for those "forgotten" pins.

@Flyingfenix Indeed. But eagle is either useless, or frequently abused by people without a clue.  Personally I never use it...

Isn't this a packaging detail? Not every resistor has to come in arrays of 4. Seems like a horrible decision to include it on the schematic.

@Tvde1 No, not every resistor has to come in arrays of 4. But it can be cheaper to use an array of 4 instead of 2 individual resistors. And since an array has 4 resistors you end up with 4 resistors in your schematic. I don't personally like the way it's done there either - I prefer to have a single component that has 4 resistors and 8 pins - that way you can more easily visualise which pins are going where to make routing of traces on the PCB simpler.

@Tvde1, it can also be less expansive and easier to manufacture to have fewer different components. A pick and place machine only has so many part cartridges, so to avoid having to run the boards through again, or having to place them manually, they reduce the types of parts. Also, this goes into the idea of cost scalability for parts. If you can get 10% off for using a part 10% more, then you've saved some money in manufacturing your board.


text:
Arduino UNO not showing up in USB devices on Ubuntu 18.04
I have an Arduino UNO (clone, not original) that was working fine until a couple of days ago. Now, it does not show up when I connect it to my laptop.
Things that I've troubleshouted:

USB cable is fine (tried with another Arduino).
USB ports are fine (tried with another Arduino).
Followed all the fixes and checks listed
here
and everything is successful.
I can upload sketches trough ICSP using a working Arduino.
I've tailed syslog while connecting and disconnecting the failing
Arduino and nothing shows up (it does when using the "good one").
I've tried on a Windows 10 machine and it doesn't show up.

What else can I try?

CH340 USB chip on it?

@Majenko Atmega16U2

Unusual. Maybe it's not a real one or its a factory reject. Probably dead. Continue using ICSP or use a USB UART dongle with it

Wondering if you bricked it similiar to my issue. @Majenko helped me as well :). Link to that answer located here: https://arduino.stackexchange.com/questions/66239/windows-10-does-not-recognize-arduino-leonardo

@static_cast I see that your problem was solved by reuploading the bootloader. I've already try that and it didn't work :(

I can't comment yet but have you updated your board manger for UNO on unbunto?
tools > Board > Board Manger > Search UNO
Kind of dumb to have to do that but it happen to me before and this was the solution I did.

It's already at the most recent version.


text:
Piezo buzzer not sounding well with ATmega328
I am using an ATmega328 to drive a 16x2 LCD, a LED, and a piezo buzzer. Piezo buzzer needs to buzz after every 5 seconds. But it doesn't make a nice sound it just gives out a faint buzz. Suspecting the buzzer to be faulty, I tested it separately from a 5V supply and it worked well. Then I put it back in the circuit and checked for the amount of current the whole circuit used. It was about 26mA when buzzer and LED were turned off, and 36mA with buzzer and LED ON. So no problem there. Additionally, the buzzer sometimes start sounding well too occasionally. This occurs after about half a minute the circuit is turned ON. This looks like that the buzzer is somewhat warming up before it can work properly. But this occurs occasionally.
I am using A0 Analog pin (or Pin no. 23 on ATmega328) for driving the Buzzer and giving 100Hz square wave to it.
What could possibly be the reason for this problem?

Re “I tested it separately from a 5V supply”: you mean with no square wave? Then you mus have a self-oscillating buzzer, right? You are trying to drive it with a software-generated square wave?

give the buzzer digitalWrite(HIGH)

even with a plain piezo 100 Hz is a very deep sound not played well on piezo

@Edgar Honey yes with no square wave...i used 5V using external supply... It worked well. But when 5V was supplied using microcontroller, it didn't work untill few seconds

why are you feeding 100 Hz signal? ... you said that it works with 5 V DC

@jsotola I want to play some notes

@jsotola then is there some name of this type of buzzer that I need

you need a speaker, not a buzzer

But i have seen notes being played on a piezo... How's that possible then?

piezo speaker versus piezo buzzer

if it doesn't work with digitalWrite(pin, HIGH) (and pinMode(pin, OUTPUT) in setup()) then show us your code

If it works well with direct 5v supply and not from an Arduino pin, you probably need a transistor to drive the buzzer.
Here is an example how to drive a buzzer using a transistor:
https://www.maxphi.com/piezo-buzzer-interfacing-arduino-tutorial

Some buzzers are active buzzers and will self oscillate when powered.
Other buzzers requires an oscillating signal on their pins in order to make a sound.  If the buzzer works on 5v then its an active buzzer and you only need to feed it a HIGH signal to make it work. Don't try to feed it a 100hz square wave.

It worked well with a constant 5V supply but not when this constant 5V was supplied using code(here I am not talking about the 100Hz wave, I modified the code to give a constant 5V)


text:
First Start Arduino Uno
When I started connecting my Arduino Uno for first project: LED to pin 13, resistor, breadboard, USB connected to Windows Laptop, the orange on-board LED flashes every second and the LED on the breadboard did the same.
What program is driving this?
I had NOT uploaded any program.
Please explain.

It is a preloaded sketch and will be overwritten when you upload your first sketch into the Arduino.
Typically it's the Arduino Blink sketch which can be found here:
https://www.arduino.cc/en/Tutorial/Blink
Which has the following (functional) content:
// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

Thanks all, Should have checked. I had Cura open!!!!! Lessons learned.

You're welcome, if it helped you, consider upvoting (the up arrow next to the answer), and if it is the correct answer for you, also accept it (pressing the check sign).