text:
Is there a way to get about a 10ns Timer resolution from an AVR CPU?
I have an 8Mhz ATM32u4 that is able to read external pulse inputs at 125ns ticks using InputCapture3 (PC7) on its 16-bit timer.  Is there a magical way (bitbanging?) to get around 10ns tick resolution to read pulses?  Edit:  like ADC conversions to allow 16-bit systems 24-bit accuracy via creative coding, etc.
If there is no magic, I should use a faster CPU?  I am limited in coding pretty much to AVR type CPUs in the Arduino IDE.  So wondering what AVR CPU would be fast enough for a 10ns tick that is incorporated already into like a Nano, UNO, etc?
Unless I am able to use Pin Interrupts that are able to read at 10ns intervals, then I could use ARM CPU types with Arduino IDE code which does not require me to dive deep into register level language.
Or, is there a stand-alone analog or digital IC that is able to read at 10ns intervals pulses that an Arduino can process?
Thank you.
Edit:  I would need to measure the length of a one-shot pulse only, not a continuous or changing signal. Down to 70us length with an accuracy of at least 18ns tick, but preferably 10ns to account for hardware, etc inaccuracies. This one-shot pulse could repeat not more frequently then 1 second apart, but likely several seconds apart. The signal is two positive square waves forming a pulse measuring not less than 70us from the positive rising edge to rising edge. The system measures the pulse length and sends it the user (serial, BLE, etc).
Edit 2: someone suggested a "one-shot pulse stretcher". Interesting concept...   The more I am looking into it, the more I think it's a very viable hardware solution to the AVR's processing speed limitation. One may say that this is hardware "bitbanging" by streching out the short pulse to a proportionally longer one that the MCU capture process can measure reliably/accurately. An example is this old IC from Linear Tech. See Fig 12 and Fig 13.    https://www.analog.com/media/en/technical-documentation/data-sheets/6752fc.pdf
http://www.anderswallin.net/2014/02/pulse-stretcher-v1/

The shortest expected pulse would be about 70us which needs to be measured at (around) a resolution of 18ns for the accuracy I need.  So I went with 10ns for design to allow for some accuracy "overhead".  That is between 4000-7000 counts/ticks  (18ns-10ns ticks) for the 70us signal.
If I stretch this same 70us signal to be measured with the pulse-stretcher to 700us and use the currently available 125ns tick interval of the ATM32u4, I should arrive in theory to about the same accuracy as using an 18ns tick for a 70us signal to be measured.
Here is a similar problem that was answered: https://electronics.stackexchange.com/questions/46922/lengthening-a-5-ns-pulse

You have a clock and it only ticks once per hour.  What bits are you going to bang that will let you measure seconds with that clock?  Same problem with the micro.  The smallest unit of time it knows is 125ns for an 8MHz clock.  There is nothing smaller than that.

What exactly is it that you think "bitbanging" means?  Or is it just a term you heard?

you are talking about a 100 MHz event ... how often does the event occur?

jsotola   It is a one shot pulse that can happen not less than in 1 second intervals, but can happen several seconds apart.

Delta_G   yes, I heard the term "bitbanging" (in general) when hardware does not cut the mustard and "creative" software methods are used to extrapolate the data to achieve accuracy/resolution that cannot be achieved with the given hardware. Could you describe it in a way that would correct my faulty understanding?

Delta_G could you address the other parts of my question which was not related to "bitbanging", which identify completely different potential solutions? Thank you for your constructive assistance!  What makes this forum great is to hear suggestions from folks like you who are willing spend time on a positive guidance focused on the correct portions of one's questions while also pointing out the incorrect ones..

Do you need to “capture” a 10ns event that occurs at most once per second? It’s unclear what you need to do with these events. Do you need to measure the amount of time between events? Do you need to react to such an event? With some external (TTL or dedicated I2C/SPI) timer components you could build an external timer that’s capable of doing this.

There are some Arduino-compatible boards based on the ATtiny85. This has a fast asynchronous timer that can be clocked off a PLL at 64 MHz. It's probably the fastest you can get on an AVR, but it doesn't have an input capture unit.

Do you need to measure the length or the pulse, or just it's existence? If you latter you'd need to stretch this 10ns pulse to something longer that 125ns. Something like an RC filter.

@ Edgar Bonet thank you for the excellent suggestion.  It's a great feature to get a 64Mhz timer from an 8 MHz internal RC clock by using an 8x scaled software solution!  That would get me to 15.625 ns, which could work if all theoretical cals are accurate in real life hardware.   I looked into it. It requires some pin mapping to Timer1 as the 64 Mhz clock after enabling the PLL,  but then would still need to setup a counter etc. and unfortunately due to my limited knowledge in coding at the registry level I rather not proceed that way.  .

@ StarCat and Gerben. I would need to measure the length of a one-shot pulse only, not a continuous or changing signal.  Down to 70us length with an accuracy of at least 18ns tick, but preferably 10ns to account for hardware, etc inaccuracies.  This one-shot pulse could repeat not more frequently then 1 second apart, but likely several seconds apart. The signal is two positive square waves forming a pulse measuring not less than 70us from the positive rising edge to rising edge. The system measures the pulse length and sends it the user (serial, BLE, etc).

Please [edit] your question to add information. I spent several minutes to find the relevant stuff down here, and I did this just for curiosity. Most others will not do it.

someone suggested a "pulse stretcher". Interesting concept...  http://www.anderswallin.net/2014/02/pulse-stretcher-v1/

@the busybee   At first I was a bit "annoyed" at your comment, but I did fix it immediately.  Now that I have gone back and edited, I want to thank you for pointing out that important changes/updates need to go up in the main post. It certainly made my review/progress easier and I am sure it also serves the same for other readers.  At the end it helps me by helping others better help me.  Thanks again!

There is nothing you can do on the AVR processors that I know of, which can run on from a quite slow clock, and I think up to 24 MHz. Since your Uno / Leonardo / Micro run at 16 MHz that would be only an incremental speed improvement (to clock them at 24 MHz).
Your idea of bit-banging is interesting, but in general bit-banging is a last resort when you need extra things the hardware doesn't provide (like an extra SPI port) and in general will be slower, not faster, because it involves code rather than inbuilt hardware.
Running at 16 MHz each clock pulse is 62.5 ns which means that is the absolute most resolution it could count. I don't see why you can't count at the rate of 62.5 ns (rather than 125 ns), however that isn't 10 ns resolution.

Or, is there a stand-alone analog or digital IC that is able to read at 10ns intervals pulses that an Arduino can process?

Very likely. There are probably dedicated counting chips that would do that for you. I haven't looked, but it is the sort of thing there would be a market for. Such a chip would probably use I2C or SPI to communicate, which is easy enough to interface to.

Mr. Gammon. Really appreciate your input. I've been studying your website's Microprocessor guides/examples & incorporated them into various projects.They are very clear & cover exhaustively the topic for people like me that are not that experienced. Thank you very much for that, sincerely. So based on your and the other comments above, including Edgar Bonet's, the closet one for an AVR is an Atiny85 with an internal oscillator scaled 8x to 64 MHz via PLL that theoretically can give 15.625 ns ticks for a timer that needs to be set up, etc but beyond my skills. Will look for faster non-AVR CPUs.

Mr. Gammon  If I may have the audacity to ask you two related questions? #1: reference the 328p and 32u4 using the InputCaptureCounter/Timer (16-bit) and implementing an external pulse-read (like in your #12 reply example under "Timers").  You used an ISR timer/counter and an ISR for overflow. Comparing that with using attachInterrupt based pulse-read on the INT0/1 pin(s) and accounting for the time it take to enter/leave the ISR (@5us), would both solutions have the same inherent accuracy?

Mr. Gammon   This is the #2 related question: I combined your InputCaptureCounter/Timer example and your CPU Deep Sleep example for the 328p (using the 32u4).  That is the code that I was hoping to "beef up" to read 70us pulses at 10ns resolution and is located here: https://arduino.stackexchange.com/questions/77978/input-capture-with-sleep-enabled-on-atm32u4-board-only-works-every-second-readin/77981#77981

Perhaps if you explain in more detail your project? Why do you need to measure such short pulses?

Mr. Gammon  Someone suggested a "one-shot pulse stretcher". Interesting concept...   The more I am looking into it, the more I think it's a very viable hardware solution to the AVR's processing speed limitation. One may say that this is hardware "bitbanging" by streching out the short pulse (via an RC "timer") to a proportionally longer one that the MCU capture process can measure reliably/accurately. Only requires three extra components. An example is this old LTC6752 from Linear Tech. See Fig 12 and Fig 13.    https://www.analog.com/media/en/technical-documentation/data-sheets/6752fc.pdf

If you make this work I suggest you post your own answer to your question, giving details about how you did it, for the benefit of future readers.

Mr. Gammon   I will do.  Thank you for your help.

1 ns is a billionth of a second. A 1 gHz clock has a cycle time of 1 ns. If you have a timer that's able to count single clock pulses you'd need a 1 gHz clock to get to 1 ns resolution. for 10 ns, you'd need a 100 mHz clock.
You won't get close to 10 ns resolution with an 8 mHz clocked device.

Duncan C, thank you for breaking it down to the numbers.  Yes, clearly would need an MCU with a faster input capture/timer, or a dedicated external IC that can do the same.  Wondering, if a fast ADC would do?  I suspect that Freq-to-Volt converter would be too inaccurate at these periods. And using a Freq dow-counter by 10 or 12 for example is would not work with a single-shot pulse that is only 70us in length/period,

10 ns is a very short duration. No way would you use something like frequency to voltage to measure durations that short.


text:
what is wrong with this code? It doesn't work
#include <DS1302.h>
#include <Servo.h>
Time t;
Servo myservo;
int Hour;
int Min;
int Sec;
// Init the DS1302
DS1302 rtc(2, 3, 4);

void setup()
{
myservo.attach(9);
myservo.write(45);
// Set the clock to run-mode, and disable the write protection
rtc.halt(false);
rtc.writeProtect(false);
Serial.begin(9200);
// The following lines can be commented out to use the values already stored in the DS1302
//rtc.setDOW(SUNDAY); // Set Day-of-Week to SUNDAY
//rtc.setTime(8, 59, 50); // Set the time to 12:00:00 (24hr format)
//rtc.setDate(8, 25, 2019); // Set the date to August 25th, 2019
}

void loop()
{
t = rtc.getTime();
Hour = t.hour;
Min = t.min;
Sec = t.sec;
 Serial.print(Hour);
 Serial.print(":");
 Serial.print(Min);
 Serial.print(":");
 Serial.println(Sec);

//set the time for fish feeding
if ((Hour== 2 && Min== 0 && Sec== 2)||(Hour== 21 && Min== 0 && Sec== 2)) {
myservo.write(0);
delay (300);
myservo.write(45);
delay (300);}
}

did the intermediate code work?

Nope, nothing seems to work hahaha

You need to define "doesn't work". What output are you expecting? What output do you get? What happens? It's like going to a doctor and saying you feel sick. S/he needs more details than that.

on your previous post, i suggested that you print a message when the seconds is 10 ... did that work?

Serial.begin(9200) ? and depending on the library, the rtc.get time may get stuck in a bad connection to the rtc chip.

It would be helpful if you could answer Nick Gammon's question. "Doesn't work" is not a useful description of a problem. Also Serial.begin(9200); will very likely not give any useful output on the serial console.

Nick, I was expecting the servo to rotate when the defined time. It doesn't do that. The servo doesn't move at all.

I've changed the serial.begin(9200) to (9600) but it doesn't seem to make a difference in the output.

I would break this down to individual problems by 1st commenting out the servo code and making sure the time code works AS EXPECTED. Then doing the same for the servo code.  If the clock does not work AS EXPECTED double check things such as using the correct pins to interface the RTC board to the ARDUINO UNO or if the RTC battery is still good.  If the servos do not work AS EXPECTED double check things such as using the correct pin to control the servo, the servo ground and power wires are correctly connected and if the poser supply is powerful enough to operate the servo.

@st2000 I think that the only thing I didn't cover so far is if the correct pins are being used. How do I check that?

Quit re-posting (3 times so far) your question!  People are going to start closing them down.  Instead - edit your original question.

In the line "DS1302 rtc(2, 3, 4);" you are tellng the program you will be connecting the Dallas Semiconductor clock chip to pins 2, 3 and 4.

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

Explanation about the multiple time execution
if ((Hour== 9 && Min== 14)||(Hour== 21 && Min== 0)) {
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
 }

Assume the time is 9:14:00 (9 hours, 14 minutes, 00 seconds).. the if condition passes.

The for loop will get executed. The duration needed to complete the loop is roughly 5 seconds.

Later, it will again go to the if condition. The time will be now 9:14:06.. it means, the condition will pass again.. the motor will again rotate.. this will repeat for about 11 times.. until the time changes to 9:15:00 or more.

So the solution is to give a delay, before exiting the if loop if you wait for a minute with
delay(60000);

then, the next 'if' condition will fail and works as per your expectation.

Part 2:
debugging:
        if ((Hour== 9 && Min== 14)||(Hour== 21 && Min== 0)) {
          for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
            // in steps of 1 degree
            myservo.write(pos);              // tell servo to go to position in variable 'pos'
            delay(15);
            Serial.println("moving");
    ....

Like this?
`void loop() {
t = rtc.getTime();
Hour = t.hour;
Min = t.min;
Sec = t.sec;
// Serial.print(Hour);
// Serial.print(":");
// Serial.print(Min);
// Serial.print(":");
Serial.println(Sec);
//set the time for fish feeding
if ((Hour== 11 && Min== 46 && Sec== 0)||(Hour== 21 && Min== 0 && Sec== 0)) {
for (pos = 0; pos <= 180; pos += 1) {
// in steps of 1 degree
myservo.write(pos);
delay(15);
}
for (pos = 180; pos >= 0; pos -= 1) {
myservo.write(pos);
delay(15);
}
delay(60000);
}
}`

But anyways, the issue here is that the servo doesn't even start either way!

you should check the Servo connections once. I doubt on that

It's all fine with the connections, I just tested the servo with the servo sweep exemple code

I just added the simulation snapshot. I created using the wokwi Arduino simulator.. it works just fine.. nevertheless, can you use some print statements to see whether the IF condition is passing ever?

I am a total noob in arduino and coding. I understant what you suggest by using some print statements to see if the IF condition is passing, but I have no idea on how to do it. I'm sorry for bothering you with so much. :\

@TiagoKotryk insert Serial.println("moving"); into the brackets of the if statements. Though at that point you should step back a bit and first do some basic Arduino tutorials to learn the basics. I don't think, that you really understand the code, that you wrote there, but that you just copy&pasted it together. It will get easier, when you understand the basics

@chrisl You are right about the point you made. Thank for your suggestion. I've inserted the code into the brackets and it shows here "Moving" on every second of the clock! Does it mean that the servo is trying to move every sec?

Yes. Though it is nor clear, what code you are currently using. Add the new code version to your question (leaving the old part intact)

@chrisl have updated this thread with the current code and results so you can take a look. Thanks for the huge help!

you have put the print statement outside the for loop. Please put it inside the for loop. you can put it after the line delay(15)

@goodarduinocode I have made the change:
 for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees     myservo.write(pos);              // tell servo to go to position in variable 'pos'     delay(15);                       // waits 15ms for the servo to reach the position     Serial.println("moving");   }  } }
But as result, the monitor serial displays nothing

The condition to drive the motor is never passing. Please take time and try to understand. Is the RTC running? Can you debug the time? Print the time and see

I think the problem is that you have given the baud rate as 9200 but the minimum baud rate is 9600(Serial.begin(9600)). And change the baud rate in the serial monitor.

4 hours before you posted your answer, Tiago Kotryk already replied in the comments that changing the baud rate to 9600 didn't make a difference. So why post this as an answer?

source: Stack Exchange

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

sort: votes


text:
Reliably using analogRead as a compact digitalRead
My goal is to reduce pins being used for micro-controllers with limited pins, or projects requiring a few different digital input values.
How I intend to do so is by using ADC pins to gather four specific different values through resistors with analogRead, which would otherwise need 2 pins (!A+!B, !A+B, A+!B, and A+B).
value = analogRead(adcPin1) >> 8;

This would give, if properly wired, 4 possible results like some sort of "Quartary bit", as analogRead yields a 10-bit response.
So my questions are the following:

Can analogRead be sufficiently reliable to tell the difference between four possible values?
What would the wiring/casing/etc. need to look like to prevent any errors?

Thanks!

I don't know how reliable it is, but it seems to be a quite commonly used technique.

Thank you Edgar that's exactly what I was looking for! Thank you I don't know why I missed on the research :/

There are 5-button-pads (https://www.sainsmart.com/products/lcd-keypad-shield-for-arduino-duemilanove-uno-mega2560-mega1280) available using this technique. It assumes you press only one of the buttons at a time. Just an info, no advertising, no recommendation :)

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


text:
Atmega328 and 4Digit 7 Segment ghost blinking!
I hooked up 4 7Seg leds (CC) with NPN transistors on the cathode of each digit. I am using 74HC595 shift register connected in the circuit in a pretty common fashion. The code I am running is the basic scanning code for the 7seg. The problem is that I see the scanned numbers on other LED digits too. Attached is the image. I call them "ghosts". The circuit I am using has an Atmega328 with an internal 8MHz Osc. The resistors on the segments are 220Ohm and 4 BC547's on the cathodes of the digits with 1kOhm resistors on their base.

below is the code:
void loop() {

      cathode_high(); // blank the screen

      break_number(number);

      display_number();
     delay(1);

}

void break_number(int num) { // seperate the input number into 4 single digits

  first_digit = num / 1000;
  digits[0] = first_digit;

  int first_left = num - (first_digit * 1000);
  second_digit = first_left / 100;
  digits[1] = second_digit;
  int second_left = first_left - (second_digit * 100);
  third_digit = second_left / 10;
  digits[2] = third_digit;
  fourth_digit = second_left - (third_digit * 10);
  digits[3] = fourth_digit;

}

void display_number() { //scanning

  cathode_high();
  digitalWrite(latch, LOW);
  shiftOut(data, clk, LSBFIRST, numbers[digits[count]]);
  digitalWrite(CAS[count], HIGH);
  digitalWrite(latch, HIGH);
  count++;
  if (count == 4) {
    count = 0;
  }
}

void cathode_high() { //turn off all 4 digit
  digitalWrite(CA_1, LOW);
  digitalWrite(CA_2, LOW);
  digitalWrite(CA_3, LOW);
  digitalWrite(CA_4, LOW);
}
Any help would be highly appreciated. Thanx in advance!

PNP on each cathode?! Surely you mean NPN...? You'd use PNP with a common anode, not a common cathode display.

Oh yes... I am sorry. 547 is an NPN.

If you only ever display one digit (never increment count) do you still see ghosting on that digit?

Could you measure the voltage on the Cathode pins when they're supposedly turned off? My guess is the BC547's do not completely turn off current through the display, or turn off very slowly, which explains the "ghost" when switching between digits. If you have an oscilloscope you could watch the voltage on the BC547's collector.

@Majenko Thanx for the effort. It is solved.

@StarCat It was a coding error. Its done now. Thanx anyway!!

@jsotola I have corrected it. Thanx

You change cathodes (digits) before latching in the new data. So for a spit second the data for the previous digits is shown on the current digit.
Swapping digitalWrite(CAS[count], HIGH); and digitalWrite(latch, HIGH); should fix that.

Bingo!! It worked. Thank You!

Glad it worked. digitalWrite is relatively slow. Thought I've had "ghosting" with direct port manipulation too.

Is there a way we can turn On/Off a full digit using the scanning method with 74hc595? As far as I understand, we cannot because the display_number() function is switching the digit pins already for scan.

I'd add one more element in the numbers array for the "no digit", with all segments off. To turn of a digit, you can then set the digit to the "number" 10.

Well, I understood the first part (adding a number to the array) and in my case the 7th element would render all digits blank, but unclear on the second part. And specially "number" 10

The numbers array is a lookup table for how to display a certain number (that is; which segments to turn on. Where index 0 gives you the segments that need to be on to show the character "0" on your 7-segment display. Index 1 for character "1" etc. I'd add an index 10 at the end for the empty character. The to set a digit to blank, use something like digits[1]=10;. Why did you numbers array only have 6 elements? I was expecting it to have 10 (indexes 0..9).

You could even add more indexes for the characters "AbCdEF-_" (which are about all the characters you can make on a 7-segment display).

Aahh I got you! Sorry I got confused in digit numbers. Earlier I had 4digits but now they are 6. So, had to add another element in the numbers array....great let me try it. I am making a reverse time counter for a machine. 6 digits mean, H M S . It is working good only I just wanted to blink the digit while setting the countdown time.

Ahh, now I get it. Note that you also have a decimal point. You could also use those to indicate a different mode (e.g. "time setting mode"). Just a thought.

Hey, Sorry I got stuck somewhere else. I have this on my mind too. Will try and get back. Thanx for all the support again.


text:
ESP32 send UDP packets from both cores
Im using AsyncUDP in an ESP32 project, where I initialize AsyncUDP udpSender and call udpSender.write(sendbuffer, sendbuffer_size) from both cores, with different buffers on each core.
One core is continually collecting GY-91 (accel/gyro/magnet) sensor data many times a second and sending it via UDP multiple times a second (after every collection), and the other one is collecting some other data like temperature once a second, as well as responding to commands a server sends.
So I'm basically using one sender on both cores and wondering if this is "thread-safe", if that terminology even applies to this scenario.
Can this cause problems? Is there a specific way this should be done? Like using semaphores?

I don't know if it's thread safe or not. However I would be inclined to play it sage and use a queue and notifications.

Create a queue
Create a "sender" thread that waits for notification then sends anything in the queue through UDP
Create any number of "sensor" threads that place items into the queue then notify the sender thread.


text:
Serial Communication, if statement not working
#include <SoftwareSerial.h>
SoftwareSerial my (D6,D7); //(Rx,Tx)
String msg;

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

void gas()
{

  Serial.println(msg);
  if (msg == "0")
  {
    Serial.println("Gas Leakage !!");
  }
  if(msg == "1") {
    delay(1);
  }
}

void loop() {

  msg = my.readStringUntil('\n');
  gas();
}

//I am using software serial to exchange data from Arduino UNO to NodeMCU, i am receiving the data correctly but the "if statement condition" is not working with it. how can i make the if statement work?

Maybe you also have an \r in your string. How exactly are you sending the message?

my problem solved by changing the if (msg == "0") with if (msg[0] == '0') ,, but I don't know why?

I would guess exactly the reason I stated above

what does that terminator \r \n means? in serial communication ?

Please answer the question, how exactly you are sending the message. Then I will write a proper answer to your question. Are you using Serial.println()? Or are you forwarding the data from the Serial Monitor set to both line endings?

yes I am using Serial.println()

https://www.arduino.cc/reference/en/language/functions/communication/serial/println/

You are using Serial.println() to send the message. That function will add the combination \r\n as line ending to your message, which are the ASCII codes for return carriage and newline.
In your receiving code, you read until \n, so your message now reads "0\r", which is of course not equal to "0". Thus the if condition will never trigger.
When using msg[0] == '0' you are taking the first character out of the string and compare that to the character '0' (especially note the difference between "0", which is a string, and '0', which is a single character). Since you are only using the first character of the string, the \r is out of the picture; you aren't using it.
What to do now?

You could send your message only with the \n character as line ending. For this only use Serial.print() instead of Serial.println() and add the line Serial.print("\n"); directly after you send your message.

You could write your own read-until code and just ditch every occurrence of the \r character.

You can use msg.trim() to remove any white space characters at the start or end of your string, including the \r at the end. Then you can use the code, that you already wrote.

Note, that using Strings on an Arduino is mostly considered evil. Especially if you want to use the code for a longer period or you are using String very often. The memory for a String is allocated dynamically, which can easily lead to heap fragmentation. For a better and longer explanation, look at The Evils of Arduino Strings, a blog entry from Majenko, who is one of our biggest contributors here.


text:
Grounding Arduino UNO with external voltage source
I was experimenting with external power supplies and noticed that the only way the Arduino can communicate with an externally powered sensor (through SPI) is when the GND pin under power AND the GND pin under AREF on the UNO is connected to the external ground?
From what I understand, both these pins are connected to the boards mutual ground (i.e. they are already internally connected)?
In the attached image both the orange and yellow wires were required and would not work individually.
I feel that either this shouldn't be the case or I am simply missing something and would appreciate an explanation.
Thanks!

Looks like orange is plugged into VIN to me...

you may be misunderstanding why a common ground is required when communicating with external devices

The circuit in the image shows the plan of the Arduino Uno, as you can see the GND pin under AREF and in the GND under the Power pin VCC are connected.
you can double-check this with a tester and figure it out.
so yes, they are internally connected.
now, in your breadboard you have connected GND to VIN, that's the problem, Vin is an input voltage that is regulated to supply 3.3V and 5V.

So remember to share grounds with external voltage supplies (DC-DC), that set the circuit to the same reference.

I would think connecting VIN to ground would cause the power supply to fail.

yes, sir,  it would.

...And it might even let out the "magic smoke" that makes electronics work.

haha almost! but the MOSFET down there doesn't let the "magic smoke" come out.


text:
How do I connect an MPU6050 sensor to an Arduino MKR WIFI 1010?
I've been trying to connect an MPU6050 to my MKR WIFI 1010 following these general instructions and using the I2CDev library, but I keep running into problems.
For a while the Arduino just didn't show up as connected in the IDE when all the pins were connected, which I think I've gathered was due to a lack of pull-up resistors for the SCL/SDA pins. Adding 10 kOhm pull-up resistors helped a little (in making the Arduino visible) but it would hang when trying to upload the example sketch. 2.2 kOhm resistors seemed to do the trick, where now the example sketches (MPU6050_DMP6 or MPU6050_raw) can be uploaded. They still fail to read any actual values, however. The raw sketch gives 0 for everything, and the DMP6 sketch prints
Initializing I2C devices...
Testing device connections...
MPU6050 connection failed

Send any character to begin DMP programming and demo:
Initializing DMP...
DMP Initialization failed (code 1)

Does anyone know why the sensor still fails to give any measurements? I connect VCC and GND from the sensor to VCC (3.3V) and GND from my Arduino. SCL and SDA from the sensor are connected to VCC via 2.2 kOhm resistors and to the SCL and SDA pins of the Arduino (12 and 11). And INT from the sensor is connected to digital pin 2. (I tried this on a couple other pins like 0 and 1 since it seems from the tech specs that 2 is not an External Interrupt pin, but that didn't change anything.)
The sensor and examples worked without any extra effort on my Arduino Uno, but unfortunately I fried that with a 12V power supply by accident. I'll probably just get another Uno, but I'm curious why this didn't work, if I'm missing something about I2C or the MKR WIFI.
I'll also note that I had to add
define #BUFFER_LENGTH 64

to wire.h in order to get sketches including I2Cdev to compile (following these instructions).

Yes, it was defined as 64, good catch. (Edited now.) I did not run any I2C scanner sketch, but I can try that. The wiring for SDA/SCL used a breadboard with both pins from the sensor connected to their own rows, a 2.2 kOhm resistor from each row to the +3.3V column (which itself connects to VCC on both the Arduino and sensor), and jumper cables from those rows to pins 11 and 12 on the Arduino for SDA/SCL respectively. The other wiring is GND (sensor) to negative column on breadboard to GND (Arduino) and INT (sensor) to digital pin 2 (which I wasn't sure about, so I also tried 0 and 1).

try the I2CScanner sketch without the pullups too

I'm seeing "I2C device found at address 0x60" and "I2C device found at address 0x6B", regardless of whether anything is plugged into my Arduino. When I tried to connect the sensor without the pull-up resistors, I got the error message "java.io.IOException: jssc.SerialPortException: Port name - COM3; Method name - setEventsMask(); Exception type - Can't set mask" and the orange CHRG light came on (with quick pulsing)

the MKR1010 has I2C devices on board

So it never detected the sensor then. Could different pull up resistors help? 4.7 kOhm seems to be a typical value used

what module with MPU6050 do you have?

This one from Aukru: https://www.amazon.com/Aukru-Arduino-Accelerometer-6050-Gyroscope/dp/B019SX74TE/

My hunch is the MPU 6050 is broken. I got a new Arduino Uno and the I2C scanner hangs when the MPU is connected, regardless of whether I have pull-up resistors. (And it worked perfectly fine with no extra pull-up resistors with my previous Arduino Uno before I fried it.) I'll order a new MPU-6050.

The sensor was indeed broken, and I had no problems after ordering a new one.


text:
For Loop function to iterate through outputs after interrupt
I would like help to continuously loop over my output pins after each sleep cycle.  I am trying to increment through each output pin during each successive interrupt.  Introducing this myIteration function causes immediate incrementing to final output pin and eliminates sleeping.
EDIT
To clarify a bit and clean up the code, I am having trouble getting the loop to increment over the output pins each time the interrupt is triggered.  It stays on the initialized pin value after each interrupt.
The reason I separate the if (state=HIGH) into two consecutive statements is because when I do not the debug LED remains on.
#include <LowPower.h>

const byte interrupt_pin = 2;                             // declare interrupt pin for PIR trigger
int musicPins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11};          // Initialize pins that play music in array, elements from 0 to 8
volatile byte state = LOW;                                // trigger threshold starts low
int pinCount = 9;
int previous = 0;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);                           // use builtin LED for debug
  pinMode(interrupt_pin, INPUT);                          // set interrupt pin as input

    for (int thisPin = 0; thisPin < pinCount; thisPin++) {      // set all music pins as High to start with no music during sensor initialization
    digitalWrite(musicPins[thisPin], HIGH);
    }
    for (int thisPin = 0; thisPin < pinCount; thisPin++) {      // set all music pins as outputs
    pinMode(musicPins[thisPin], OUTPUT);
    }

  delay(5000);                                            // wait so sensor can initialize
}

void loop() {

  attachInterrupt(digitalPinToInterrupt(interrupt_pin),interrupt_routine,RISING); // must attach each loop
  LowPower.powerDown(SLEEP_FOREVER,ADC_OFF,BOD_OFF);      // MCU sleep until interrupt
  detachInterrupt(digitalPinToInterrupt(interrupt_pin));  // remove interrupt

  if (previous==10){                                      // when variable gets to 10 reset to zero
    previous=0;
  }

  if (state==HIGH){                                       // PIR senses motion, sends high signal
    digitalWrite(LED_BUILTIN,HIGH);                       // debug LED turns on
    myOnIteration();                                      // musicPin number x turns on
    delay(100);                                           // wait to stabilize
    digitalWrite(LED_BUILTIN,LOW);                        // debug LED turns off
  }
  if (state==HIGH){                                       // separate statements to guarantee next steps happen
    myOffIteration();                                     // musicPin number x turns off
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);       // sleep for 8s after musicPin plays

  }

  previous++;                                             // increment before attaching next interrupt

}

////////Functions//////////
void interrupt_routine(){
  state = HIGH;
}

void myOnIteration() {                                    // cycle through output pins turning on once per interrupt
for (int count = previous; count < pinCount; count++) {
        digitalWrite(musicPins[count], LOW);
      }
}

void myOffIteration() {                                   // cycle through output pins turning off once per interrupt
for (int count = previous; count < pinCount; count++) {
        digitalWrite(musicPins[count], HIGH);
      }
}

Your problem description is a bit unclear. What did you expect the code to do and what did it actually do instead? Also: myIteration() is never called. Also it wouldn't change the global thisPin variable, since it uses it's own local variable with that name.

Why do you have two directly consecutive tests for if (state==HIGH)? Wouldn't one do? Plus what chrisl said.

I use two consecutive test for if (state==HIGH) because when I do not the debug LED remains on during sleep.  Thanks for the pointer about global variable.  I've edited the original post.  My iteration functions are still not iterating, the code runs only the initialized value at pin 4.

Why are you counting from 4 to 9, when your musicPins array has only has 8 elements? And did you intent to skip the first 4 elements with that? With that pin 4 will never change. Count from 0 to 7 instead

Thanks, the array was indeed incorrect. I've fixed it to be the number of elements in the array and not the pin numbers. I also needed to be incrementing inside the main loop before attaching the interrupt.  The original post is edited with final working version.

Original code is updated with final version. A motion sensing interrupt iterates over multiple voice playback output pins and sleeps at low power for rest of time.

I don't understand this "answer". Stack Exchange is not a forum. Are you saying the problem is fixed? If so, in what way? If not, please edit your question to elaborate, don't use an answer to clarify the question.


text:
Arduino code equivalent for python code binascii.unhexlify command
I want to convert a hexadecimal string or an array of bytes to binary data.
For example, if i have a string like
'424D368403'
my output should be like
b'BM6\x84\x03'
The python code binascii.unhexlify('424D368403') gives the correct output.
But, I want to do this in arduino code.
Can someone help me in creating an arduino code / command in getting desired output?

https://arduino.stackexchange.com/a/77974/4143

@Majenko, even if the answer is almost the same, the questions are different. but this question is better. maybe adapt the answer here?


text:
Knowing if ESP32 wakes up itself or manually
I have a project where I put an ESP32 to deep sleep for a certain amount of time, eg: 1h
To be able to self-awaken a cable must be connected from GPIO 16 to the reset pin, so basically the ESP pulls down pin 16 and causes itself to reset.
I also need the possibility to manually waken up the ESP, so in parallel to this cable I connect a button to GND, so I can manually reset the ESP and waken it up.
However I need to be able to tell if the ESP has awaken itself because one hour has passed or if it has been manually awaken.
I cannot connect the ESP to a internet time provider to check the time, so my first though wasto connect the button also to an input and read it when the ESP starts.
However the ESP won't start until the button forcing RST low is released and then it's too late to read it and see if it was pressed.
Is there a way that I can tell if the ESP was manually reset or if it woke up by itself?

I think you're getting confused between the ESP32 and the ESP8266. There is no need to connect GPIO16 to reset on the ESP32.
Instead the ESP32 has the "ULP" - Ultra Low-power Processor in it (essentially the RTC processor) which is what sends wakeup signals to the ESP32 cores. It is this which wakes the system up after an hour.
The ULP can also trigger a wakeup from other sources - most often used to wake up from an external signal, such as your button. But this only works if that signal is connected to one of the RTC input pins (GPIOs 34 to 39), or certain interrupt enabled pins (you can read more about what can wake the system up here).
Once a wakeup has happened you can then query the ULP to find out why it woke the ESP32 up using the esp_sleep_get_wakeup_cause() function.

the esp8266 has the RTC too, only there is some design bug and it can't wakeup internally. the io 16 connection to reset is a workaround

Another reason to not bother with the esp8266 and go straight for the ESP32...

Thanks. looks like that's what I needed.


text:
Understanding Debounce code
I don't understand the following Debounce code. (The complete code is at the bottom.) From what I understand, when the pin reads something, we wait at least 50 milliseconds before performing anything. But doesn't the reading variable get reset every loop iteration, so reading equals zero in the inner if-condition in every iteration.
What I think is the sequence of events: loop(), loop(), loop(), "loop(), button press, reading=1, set lastDebounceTime, first if condition fails because we have to wait, set lastButtonState=1", loop(), loop(),loop(),"loop() enough time has passed, but since no button press at in this iteration and the last few, reading and lastButtonState equal zero", loop(), ... .
However, this code works.
Why do we save reading in a local variable? Won't the code virtually always be this, then:
if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if 0 != buttonState) {
      buttonState = 0;

...

Entire code:
/*
  Debounce

  Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
  press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's a
  minimum delay between toggles to debounce the circuit (i.e. to ignore noise).

  The circuit:
  - LED attached from pin 13 to ground
  - pushbutton attached from pin 2 to +5V
  - 10 kilohm resistor attached from pin 2 to ground

  - Note: On most Arduino boards, there is already an LED on the board connected
    to pin 13, so you don't need any extra components for this example.

  created 21 Nov 2006
  by David A. Mellis
  modified 30 Aug 2011
  by Limor Fried
  modified 28 Dec 2012
  by Mike Walters
  modified 30 Aug 2016
  by Arturo Guadalupi

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/Debounce
*/

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;    // the number of the pushbutton pin
const int ledPin = 13;      // the number of the LED pin

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);

  // set initial LED state
  digitalWrite(ledPin, ledState);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
  }

  // set the LED:
  digitalWrite(ledPin, ledState);

  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
}

(Debounce code taken from: https://www.arduino.cc/en/tutorial/debounce.)

What's unclear with the comments?
BTW: The last code line is part of the debouncing algorithm.

Ah, sorry @jsotola. I seem to have copy/paste-d incorrectly

@DataFiddler, I edited the question. I don't understand part of the algorithm. Sorry about that.

think about this .... imagine that you have a stopwatch ... in front of you is an indicator light and a pushbutton ... the light turns on, and off, at random intervals ... your job is to press a button if the state of the lamp does not change for 10 seconds ... how would you accomplish your job? ... the algorithm does the same thing

I edited the question again. Why is reading local?

because reading needs to exist only for the duration of one iteration of loop()

@jsotola, don't we need it for the iteration when lastDebounceTime completes?

there is no lastDebounceTime completes

Let us continue this discussion in chat.

loop() does not need any time and repeats permanently.
lastButtonState is reading from previous loop run.
As long as the button bounces, lastDebounceTime is updated.
Only when the button has settled (either pressed or released), the condition
  ((millis() - lastDebounceTime) > debounceDelay)

becomes true and the code is executed -> if buttonState (the previous debounced state) and reading show a change to HIGH, the led state is toggled.
Not sure if this explanation makes anything clearer, as it is clear already as it stands, IMO.

Why isn't it that we check instead lastButtonState shows a change to high? Reading gets reset every loop() and will virtually always be zero (in my limited understanding).

Why would it always be 0?  It will be whatever the pin reads.  Every time loop repeats it reads the pin again and you get a new reading.  We could check lastButtonState or reading, they will be the same at that point in the code.  If they aren't the same then lastDebounceTime gets set to the current time and we don't enter that second if statement.

If loop takes a microsecond and bouncing takes two milliseconds, reading will be evaluated 2000 times in those 2 ms, and change a couple of times during this period. Only if is stable for 50 ms (you got nearly an infinite number of the same reading values) you accept that as a new debounced button state

What I think is the sequence of events: loop(), loop(), loop(), "loop(), button press, reading=1, set lastDebounceTime, first if condition fails because we have to wait, set lastButtonState=1", loop(), loop(),loop(),"loop() enough time has passed, but since no button press at in this iteration and the last few, reading and lastButtonState equal zero", loop(), ...

@thegoodhunter-9115 seriously think about what i said about the light and the stopwatch .... what would you do with the stopwatch if the light turned on or turned off?

@jsotola, I think I get it now. I (think) couldn't understand it due to my ignorance of how "long" a button press is and how many times loop() would run during a single press. Just to make sure: During the 50 ms (debounceDelay), the button would be remain in the pressed state by the user (even though it was just a click), and during that time, loop() would run multiple times (so, it would "remember" what reading was). I was thinking that the 50 ms would pass in one call of loop(). I could still be wrong in my understanding, but thank you kindly for your help, and sorry for the annoyance.

@DataFiddler Thank you kindly for your help and patience. I elaborated why (I think) I had this misunderstanding in my comment above to jsotola (in this thread). Thank you again.

@thegoodhunter-9115 thank you for the explanation of your misunderstanding ... i learned something from you today ... i now know that the loop() execution time can be the source of confusion

@thegoodhunter-9115 you can do a simple test ... write a sketch that, in setup(), prints the value of millis() and sets a counter to zero .... in loop() increments the counter ... when the counter reaches 1000, prints millis() again .... that will give you an idea of approximately how long 1000 iterations of loop() take

Alright. Thank you again, @jsotola.


text:
PT2257 only gives me heavy buzzing sound
I have this project where I control a bluetooth audio module with an arduino. In this case, I have used an arduino nano. But then, I have been meaning to add volume control to the project so I use a pt2257. But the sounds that it gives to me is my audio plus heavy buzzing sound and no matter how much attenuation that I set the volume doesnt seems to change. Can anyone help me?
Here is the schematics that I use for the PT2257:

I have tried giving Vdd 5V from arduino, and also 5V from a seperate power supply. But it seems there is no difference.
Here is the code that i use:
    void setup() {
      delay(1000);
      Wire.begin();
      Serial.begin(115200);
    }
    void loop() {
      Wire.beginTransmission(Volume_address);
      Wire.write(0b011100000);    // set low attenuation
      Serial.print("result 1: ");
      Serial.println(Wire.endTransmission());
      delay(2000);
      Wire.beginTransmission(Volume_address);
      Wire.write(0b11111111);  // set full attenuation
      Serial.print("result 2: ");
      Serial.println(Wire.endTransmission());
      delay(2000);
    }

Here is the link to PT2257 datasheet if you need it
EDIT:
Here is how I connect CSR8645 Output to my active speaker, before I add a attenuation IC. It works like a charm like this, but I need to add a volume control.

Did you connect the ground of the PT2257 and your audio to the ground of your Nano?

I have connected my pt2257 ground to arduino ground. But i didnt connect the audio ground to arduino ground. Since I have csr8645 as the audio source and it has Lp, Ln, Rp, and Rn, which one should i connect to the ground? I use Lp as left audio signal and Rp as right audio signal, Ln as audio ground. So does that mean I have to connect Ln to the ground?

Yes, I would connect the audio Ln, Rn to ground. Not having them connected to a (common) ground would explain the buzzing sound (50 or 60Hz interference from the power grid, depending on where you lvie).

Connecting any output direct to ground is very bad. Do not do it. You would normally connect the Ln and Rn inputs of a differential amplifier to ground through capacitors if you are using a single ended source. You would never connect the output to ground! Using Rp and GND will give you half the amplitude of using Rp and Rn. Leave Rn and Ln disconnected.

So how should I connect the audio attenuation ICs with CSR8645 output? I have single ended active speaker to connect it to. So, without the attenuation IC I connect it like the schematics I add in the edits

many amps and BT audio chips use differential input/outputs. none of the inputs nor outputs are considered grounds.
the Lp(left,postivie) Ln, Rp and Rn on your audio chip should be connected to loads directly. Ln or Rn are not audio grounds. so you can't use simple POT volume controls or any processor or amplifier chip that doesn't support differential IOs. so, you can't use PT2257 in this circuit.
for better understanding here are two audio signal types:

the simple, well known one, which consists of GND and an audio IN per channel. you can use many amplifiers, processors (e.h. PT2257) and POT volume controls. and one end of the output (e.g. speaker) is connected to GND.
the differntial audio signal which consists of a GND and a pair of IN+,IN- per channel. you can't use the soulutions mentioned above. for example, if you wanted to amplify the output signal of the bluetooth chip, you have to use something like PAM8302, 2.5W mono class D audio amp per channel. note the IOs:

Firstly, thanks for your kind explanation. Secondly, if i want to do volume attenuation which IC/Module do you suggest me to use? I have been searching for attenuation ICs  that uses differential input. But I can't seem to find any that suits my usage.


text:
Modbus TCP together with MQTT over same ethernet
I'm currently in a planning phase for a project.
I want to read some sensor data over Modbus TCP, do some simple calculations on the Arduino and publish the results over MQTT. Which means I have 2 RJ-45s and two different protocols.
Given a Arduino Mega with an Ethernet shield.
Does it work if I simply add a network switch and connect the sensor and an internet router to it, and use both protocols in parallel?
Or are there any problems running such a thing on only one Arduino?

don't underestimate Arduino. here are the ino files of Arduino sketch for my main project: https://github.com/jandrassy/Regulator#sketch it runs on ATmega1284p boaard. and a simpler Modbus TCP project with web server https://github.com/jandrassy/IsgModbusTcpSG which runs on Nano Every

Does it work if I simply add a network switch and connect the sensor and an internet router to it, and use both protocols in parallel?

Kind of, yes. You just connect both the MODBUS device and the Arduino to the network provided by the router. The Arduino is just a normal network device - the IP address for it allocated by the router, as is the MODBUS device.
Any device can communicate with any other device in a network.


text:
Get deceleration (negative acceleration when apply brake force)
I want to build a device to measure deceleration force when a car brakes. I am using a MPU6050 for get data and I read from it acceleration on X,Y,Z axes in m/s2 and also it gives me gyro in degrees/second.
My question is how can I use these gyro values to correct acceleration? Basically when apply brake the position of the axes are changing .
Also I guess I need to calculate the deviation as well if the car goes to the left or right during brake process.
Any ideas, hints will be very appreciated
Thank you very much

What exactly you want to calculate? Deceleration is indeed a negative number defined as deceleration = (velocity@begin - velocity@final)/time.

I accelerate to some speed for example. After that I will have a time without acceleration and when apply brake I start record values till the car is stopped. Then I want to get the speed that was when I started to brake and the distance till the car was stopped


text:
log STK500v2 commands while flashing a Mega
My final goal is to replicate the process with which the PC programs the arduino.
I have gone through the commands.h file and made a couple of attempts to get the logic right. But no success at flashing the arduino.
Is there any way to view the Hex commands that are written to the arduino from the PC? Something like verbose but list every hex command.
My idea is that I will just replicate the same commands and try uploading hex files from SD card.

have you examined the bootloader source code?

http://www.gammon.com.au/bootloader

Add the flag -vvvv to the avrdude command. That will show you the flow of data between the computer and the Arduino.
You can copy and paste the executed command from the IDE and run it in a terminal / command window adding the flag manually. Or you could modify the platform.txt file for the AVR core.


text:
Getting atsam3x8e (Arduino Due) to work
I decided to make a pcb based on the atsam3x8e (microcontroller used in Arduino Due). For the design I copied most of the layout that I found on this site and looked at the official Arduino Due schematic as well but decided that I didn't need everything. This is the schematic that I made and the pcb:

The problem is that my laptop doesn't see the "Arduino Due / atsam" when I connect the USB to my pc with a USB cable (with data lines). I understood that the chip chips with the SAMBA bootloader in ROM and that it should be programmable via native usb connection to the chip.
I supply 3V3 with a bench power supply.
Then I tried to follow the checklist for this microcontroller: checklist.
All voltages seem to arrive on the chip. VDDout makes a 1.7 voltage as it should.
I have a clocksignal on my 12Mhz crystal. I don't have a clock signal on my 32khz crystal but when measuring on an official arduino due I also didn't see a clock signal here so I guess this oscillator isn't always on.
I made some wire patches: decoupling cap were not ground referenced and one oscillator pin of 12 Mhz wasn't connected.
Any ideas on how I could further debug this?

check for unwanted solder bridges ... you have what looks like stray bits of solder on the board

did you solve this issue? I'm having a similar issue with my atsam3x8e design where windows show it up in device manager as an "Unknown USB Device (device descriptor request failed) and I can't work out why it won't show up as a com port. I verified that the chip is up and running fine by programming it over the TX and RX pins with a USB to serial converter. This might be a good place for you to start debugging your design, although you will have to add a 2 pin header connected to the TX&RX pin to your design.


text:
Arduino ESP32F-TFT-1.44 Driver
Datasheet https://github.com/espressif/esp-hosted/files/5190376/ESP-32F.pdf
The below code is not working.
I can see only White screen

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>

#define TFT_CS        26 // Hallowing display control pins: chip select
#define TFT_RST       16 // Display reset
#define TFT_DC        17 // Display data/command select
#define TFT_BACKLIGHT  13 // Display backlight pin

// OPTION 1 (recommended) is to use the HARDWARE SPI pins, which are unique
// to each board and not reassignable. For Arduino Uno: MOSI = pin 11 and
// SCLK = pin 13. This is the fastest mode of operation and is required if
// using the breakout board's microSD card.

// For 1.44" and 1.8" TFT with ST7735 (including HalloWing) use:
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

// For 1.54" TFT with ST7789:
//Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// OPTION 2 lets you interface the display using ANY TWO or THREE PINS,
// tradeoff being that performance is not as fast as hardware SPI above.
#define TFT_MOSI 19  // Data out
#define TFT_SCLK 18  // Clock out
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

float p = 3.1415926;

void setup(void) {
  Serial.begin(115200);
  Serial.print(F("Hello! ST77xx TFT Test"));

  //#ifdef ADAFRUIT_HALLOWING
  // HalloWing is a special case. It uses a ST7735R display just like the
  // breakout board, but the orientation and backlight control are different.
  tft.initR(INITR_HALLOWING);        // Initialize HalloWing-oriented screen
  pinMode(TFT_BACKLIGHT, OUTPUT);
  digitalWrite(TFT_BACKLIGHT, HIGH); // Backlight on
  //#else
  // Use this initializer if using a 1.8" TFT screen:
  //  tft.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab

  // OR use this initializer (uncomment) if using a 1.44" TFT:
  //  tft.initR(INITR_144GREENTAB); // Init ST7735R chip, green tab

  // OR use this initializer (uncomment) if using a 0.96" 180x60 TFT:
  //  tft.initR(INITR_MINI160x80);  // Init ST7735S mini display

  // OR use this initializer (uncomment) if using a 1.54" 240x240 TFT:
  //tft.init(240, 240);           // Init ST7789 240x240
  //#endif

  Serial.println(F("Initialized"));

  uint16_t time = millis();
  tft.fillScreen(ST77XX_BLACK);
  time = millis() - time;

  Serial.println(time, DEC);
  delay(500);

  // large block of text
  tft.fillScreen(ST77XX_BLACK);
  testdrawtext("Hello World asdf sdf adfsdf sdf sdf sdf sdf sdf ", ST77XX_BLACK);
  delay(1000);

  Serial.println("done");
  delay(1000);
}

void loop() {
  tft.invertDisplay(true);
  delay(500);
  tft.invertDisplay(false);
  delay(500);
}

void testdrawtext(char *text, uint16_t color) {
  tft.setCursor(0, 0);
  tft.setTextColor(color);
  tft.setTextWrap(true);
  tft.print(text);
}

are we supposed to guess what you expect the code to do, and what happens when you run the code, and what question you want to ask?

I can see only black screen.

then, what is the point of the lengthy program? ... reduce the code to minimum required to display a simple text message, such as "test" ... there should be an example sketch included with the library, try that first

from experience, I had the same problem with various displays with the example code above. using software SPI solved the problem many times. try it out. it's applicable in the code above with just some commenting.

What actual display do you have? Is it a ST7735 based one?

I checked my datasheet, but, there is no information, only TFT-1.44

According to the circuit diagram you provided, the TFT_MOSI is connected to pin 23, not pin 19. Pin 19 is for MISO, not MOSI.

@hcheung : thanks, that will be answer

#include <WiFi.h>

#include <time.h>
#include "AudioFileSourcePROGMEM.h"
#include "AudioGeneratorTalkie.h"
#include "AudioOutputI2S.h"

#ifndef STASSID
#define STASSID "WIFI_SSID"
#define STAPSK  "WIFI_PASSWORD"
#endif

const char *ssid = STASSID;
const char *pass = STAPSK;

long timezone = 7;
byte daysavetime = 1;

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>

#define TFT_CS        26 // Hallowing display control pins: chip select
#define TFT_RST       16 // Display reset
#define TFT_DC        17 // Display data/command select
#define TFT_BACKLIGHT  13 // Display backlight pin

// OPTION 1 (recommended) is to use the HARDWARE SPI pins, which are unique
// to each board and not reassignable. For Arduino Uno: MOSI = pin 11 and
// SCLK = pin 13. This is the fastest mode of operation and is required if
// using the breakout board's microSD card.

// For 1.44" and 1.8" TFT with ST7735 (including HalloWing) use:
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

// For 1.54" TFT with ST7789:
//Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// OPTION 2 lets you interface the display using ANY TWO or THREE PINS,
// tradeoff being that performance is not as fast as hardware SPI above.
#define TFT_MOSI 23  // Data out
#define TFT_SCLK 18  // Clock out
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

float p = 3.1415926;

AudioGeneratorTalkie *talkie;
AudioOutputI2S *out;

bool GetLocalTime(struct tm * info, uint32_t ms) {
  uint32_t count = ms / 10;
  time_t now;

  time(&now);
  localtime_r(&now, info);

  if (info->tm_year > (2016 - 1900)) {
    return true;
  }

  while (count--) {
    delay(10);
    time(&now);
    localtime_r(&now, info);
    if (info->tm_year > (2016 - 1900)) {
      return true;
    }
  }
  return false;
}

int threshold = 40;
bool touch1detected = false;
bool touch2detected = false;

void gotTouch1() {
  touch1detected = true;
}

void gotTouch2() {
  touch2detected = true;
}
void initLCD() {
  tft.initR(INITR_HALLOWING);        // Initialize HalloWing-oriented screen
  pinMode(TFT_BACKLIGHT, OUTPUT);
  digitalWrite(TFT_BACKLIGHT, HIGH); // Backlight on

  Serial.println(F("Initialized"));

  uint16_t time = millis();
  tft.fillScreen(ST77XX_BLACK);
  time = millis() - time;

  Serial.println(time, DEC);
  delay(500);

  // large block of text
  tft.fillScreen(ST77XX_BLACK);

}
void setup(void) {

  touchAttachInterrupt(T2, gotTouch1, threshold);
  touchAttachInterrupt(T0, gotTouch2, threshold);

  Serial.begin(115200);
  Serial.print(F("Hello! ST77xx TFT Test"));

  initLCD();

  /*
    delay(1000);

    // tft print function!
    tftPrintTest();
    delay(4000);

    // a single pixel
    tft.drawPixel(tft.width() / 2, tft.height() / 2, ST77XX_GREEN);
    delay(500);

    // line draw test
    testlines(ST77XX_YELLOW);
    delay(500);

    // optimized lines
    testfastlines(ST77XX_RED, ST77XX_BLUE);
    delay(500);

    testdrawrects(ST77XX_GREEN);
    delay(500);

    testfillrects(ST77XX_YELLOW, ST77XX_MAGENTA);
    delay(500);

    tft.fillScreen(ST77XX_BLACK);
    testfillcircles(10, ST77XX_BLUE);
    testdrawcircles(10, ST77XX_WHITE);
    delay(500);

    testroundrects();
    delay(500);

    testtriangles();
    delay(500);

    mediabuttons();
    delay(500);

    Serial.println("done");
    delay(1000);

    //*/

  Serial.print("Connecting to ");
  Serial.println(ssid);
  testdrawtext("Connecting to ", ST77XX_WHITE);

  WiFi.begin(ssid, pass);

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

  Serial.println("WiFi connected");

  tft.fillScreen(ST77XX_BLACK);
  testdrawtext(strcat("WiFi connected ", ""), ST77XX_WHITE);
  clearText();
  delay(1000);

  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println("Contacting Time Server");

  configTime(3600 * timezone, daysavetime * 3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
  struct tm tmstruct ;
  do {
    tmstruct.tm_year = 0;
    Serial.printf(".");
    GetLocalTime(&tmstruct, 5000);
    delay(100);
  } while (tmstruct.tm_year < 100);

  audioLogger = &Serial;
  out = new AudioOutputI2S(0, 1);
  talkie = new AudioGeneratorTalkie();
  talkie->begin(nullptr, out);
}

char temp[300];

int alarmHours = 5;
int alarmMinutes = 44;

void loop() {
  //  tft.invertDisplay(true);
  //  delay(500);
  //  tft.invertDisplay(false);
  //  delay(500);

  struct tm tmstruct ;
  tmstruct.tm_year = 0;
  GetLocalTime(&tmstruct, 5000);
//  Serial.printf("\nNow is : %d-%02d-%02d %02d:%02d:%02d Alarm %2d : %2d\n",
//                tmstruct.tm_year + 1900, tmstruct.tm_mon + 1,
//                tmstruct.tm_mday, tmstruct.tm_hour,
//                tmstruct.tm_min, tmstruct.tm_sec,
//                alarmHours, alarmMinutes);
  Serial.printf("\nNow is : %02d:%02d:%02d\n",
                tmstruct.tm_hour,
                tmstruct.tm_min, tmstruct.tm_sec);

  //  sprintf(temp, "%d-%02d-%02d% 02d:%02d:%02d Alarm %2d : %2d\n", tmstruct.tm_year + 1900, tmstruct.tm_mon + 1, tmstruct.tm_mday, tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec, alarmHours, alarmMinutes);
  sprintf(temp, "%02d:%02d:%02d", tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec);

  if (60 * alarmHours + alarmMinutes <= 60 * tmstruct.tm_hour + tmstruct.tm_min) {
    Serial.printf("-Alarm-");
    Serial.printf("\n** Now is : %d-%02d-%02d %02d:%02d:%02d Alarm %2d : %2d\n",
                  tmstruct.tm_year + 1900, tmstruct.tm_mon + 1,
                  tmstruct.tm_mday, tmstruct.tm_hour,
                  tmstruct.tm_min, tmstruct.tm_sec,
                  alarmHours, alarmMinutes);
    //    sayTime(tmstruct.tm_hour, tmstruct.tm_min, talkie);
    //    initLCD();
  }

  //  clearText();

  tft.fillRect(40, 30, 50, 10, ST77XX_BLACK );
  //  testdrawtext(temp, ST77XX_WHITE);
  tft.setCursor(40, 30);
  tft.setTextColor(ST77XX_WHITE);
  //  tft.setTextWrap(true);
  tft.print(temp);

  delay(1000);

  if (touch1detected) {
    touch1detected = false;
    Serial.println("Touch 1 detected");
    alarmMinutes = alarmMinutes + 10;
  }
  if (touch2detected) {
    touch2detected = false;
    Serial.println("Touch 2 detected");
    alarmMinutes = alarmMinutes + 10;
  }
}

void testlines(uint16_t color) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x = 0; x < tft.width(); x += 6) {
    tft.drawLine(0, 0, x, tft.height() - 1, color);
    delay(0);
  }
  for (int16_t y = 0; y < tft.height(); y += 6) {
    tft.drawLine(0, 0, tft.width() - 1, y, color);
    delay(0);
  }

  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x = 0; x < tft.width(); x += 6) {
    tft.drawLine(tft.width() - 1, 0, x, tft.height() - 1, color);
    delay(0);
  }
  for (int16_t y = 0; y < tft.height(); y += 6) {
    tft.drawLine(tft.width() - 1, 0, 0, y, color);
    delay(0);
  }

  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x = 0; x < tft.width(); x += 6) {
    tft.drawLine(0, tft.height() - 1, x, 0, color);
    delay(0);
  }
  for (int16_t y = 0; y < tft.height(); y += 6) {
    tft.drawLine(0, tft.height() - 1, tft.width() - 1, y, color);
    delay(0);
  }

  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x = 0; x < tft.width(); x += 6) {
    tft.drawLine(tft.width() - 1, tft.height() - 1, x, 0, color);
    delay(0);
  }
  for (int16_t y = 0; y < tft.height(); y += 6) {
    tft.drawLine(tft.width() - 1, tft.height() - 1, 0, y, color);
    delay(0);
  }
}

char prevText[300];

void clearText() {
  testdrawtext(prevText, ST77XX_BLACK);
}

void testdrawtext(char *text, uint16_t color) {
  strcpy(prevText, text);
  tft.setCursor(0, 0);
  tft.setTextColor(color);
  tft.setTextWrap(true);
  tft.print(text);
}

void testfastlines(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t y = 0; y < tft.height(); y += 5) {
    tft.drawFastHLine(0, y, tft.width(), color1);
  }
  for (int16_t x = 0; x < tft.width(); x += 5) {
    tft.drawFastVLine(x, 0, tft.height(), color2);
  }
}

void testdrawrects(uint16_t color) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x = 0; x < tft.width(); x += 6) {
    tft.drawRect(tft.width() / 2 - x / 2, tft.height() / 2 - x / 2 , x, x, color);
  }
}

void testfillrects(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x = tft.width() - 1; x > 6; x -= 6) {
    tft.fillRect(tft.width() / 2 - x / 2, tft.height() / 2 - x / 2 , x, x, color1);
    tft.drawRect(tft.width() / 2 - x / 2, tft.height() / 2 - x / 2 , x, x, color2);
  }
}

void testfillcircles(uint8_t radius, uint16_t color) {
  for (int16_t x = radius; x < tft.width(); x += radius * 2) {
    for (int16_t y = radius; y < tft.height(); y += radius * 2) {
      tft.fillCircle(x, y, radius, color);
    }
  }
}

void testdrawcircles(uint8_t radius, uint16_t color) {
  for (int16_t x = 0; x < tft.width() + radius; x += radius * 2) {
    for (int16_t y = 0; y < tft.height() + radius; y += radius * 2) {
      tft.drawCircle(x, y, radius, color);
    }
  }
}

void testtriangles() {
  tft.fillScreen(ST77XX_BLACK);
  int color = 0xF800;
  int t;
  int w = tft.width() / 2;
  int x = tft.height() - 1;
  int y = 0;
  int z = tft.width();
  for (t = 0 ; t <= 15; t++) {
    tft.drawTriangle(w, y, y, x, z, x, color);
    x -= 4;
    y += 4;
    z -= 4;
    color += 100;
  }
}

void testroundrects() {
  tft.fillScreen(ST77XX_BLACK);
  int color = 100;
  int i;
  int t;
  for (t = 0 ; t <= 4; t += 1) {
    int x = 0;
    int y = 0;
    int w = tft.width() - 2;
    int h = tft.height() - 2;
    for (i = 0 ; i <= 16; i += 1) {
      tft.drawRoundRect(x, y, w, h, 5, color);
      x += 2;
      y += 3;
      w -= 4;
      h -= 6;
      color += 1100;
    }
    color += 100;
  }
}

void tftPrintTest() {
  tft.setTextWrap(false);
  tft.fillScreen(ST77XX_BLACK);
  tft.setCursor(0, 30);
  tft.setTextColor(ST77XX_RED);
  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_YELLOW);
  tft.setTextSize(2);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_GREEN);
  tft.setTextSize(3);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_BLUE);
  tft.setTextSize(4);
  tft.print(1234.567);
  delay(1500);
  tft.setCursor(0, 0);
  tft.fillScreen(ST77XX_BLACK);
  tft.setTextColor(ST77XX_WHITE);
  tft.setTextSize(0);
  tft.println("Hello World!");
  tft.setTextSize(1);
  tft.setTextColor(ST77XX_GREEN);
  tft.print(p, 6);
  tft.println(" Want pi ? ");
  tft.println(" ");
  tft.print(8675309, HEX); // print 8,675,309 out in HEX!
  tft.println(" Print HEX!");
  tft.println(" ");
  tft.setTextColor(ST77XX_WHITE);
  tft.println("Sketch has been");
  tft.println("running for : ");
  tft.setTextColor(ST77XX_MAGENTA);
  tft.print(millis() / 1000);
  tft.setTextColor(ST77XX_WHITE);
  tft.print(" seconds.");
}

void mediabuttons() {
  // play
  tft.fillScreen(ST77XX_BLACK);
  tft.fillRoundRect(25, 10, 78, 60, 8, ST77XX_WHITE);
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_RED);
  delay(500);
  // pause
  tft.fillRoundRect(25, 90, 78, 60, 8, ST77XX_WHITE);
  tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_GREEN);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_GREEN);
  delay(500);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_BLUE);
  delay(50);
  // pause color
  tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_RED);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_RED);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_GREEN);
}

Please add an explanation for why this is an answer to the question. What does this code do and how does it solve the problem? What's with the audio stuff?


text:
Wiring Multiple MPU 6050 to Micro/Lenardo
disclaimer I am new at hardware/circuits
I am currently trying to connect two MPU-6050 to a single Micro board.
In addition, there are 5 additional buttons to be connected.
I am under the impression to connect multiple devices to the I2C bus, there must be unique addresses. I read there was a way to make unique addresses (https://playground.arduino.cc/Main/MPU-6050/#multiple).
However I am not sure of the wiring or if the voltage/resistors/anything is supposed to be located.
I have a sketch of what it may look like.

Can anyone help me verify that this is the proper configuration? Or what a proper configuration would look like?

Buttons are just buttons. You can have them "active high" with pulldown resistors as you have there (10K is fine. The actual value doesn't really matter, just don't have it too low or excess current will be drawn), or "active low" without resistors and connecting to ground when pushed instead of VCC and use INPUT_PULLUP. The choice is yours. There's no real benefit in this situation to either way of doing it.
The critical part is your AD0 connection. Whether you connect one to ground and leave the other unconnected, or connect one to VCC and leave the other unconnected, depends entirely on the design of the breakout board. It should have a resistor on the AD0 pin internally that either connects it to GND or to VCC. If it connects to GND then you need to link that pin to VCC to override it. If it connects it to VCC (or more likely 3.3V) internally then you need to connect it to GND to override it.
To find out which you will have to either consult the documentation or schematic for the board or measure the voltage at the AD0 pin. If it measures 0V (within a few mV) then it connects to ground and you will have to connect it to VCC to override it. If it measures more (probably nearer 3.3V) then connect it to ground to override it.
Because those chips are 3.3V and the board contains a 3.3V regulator (if your boards are the same as you picture in your wiring diagram) the chances are that the AD0 is pulled up to 3.3V so you just need to connect one to ground.
So it looks to me like your wiring diagram is most likely suitable and correct, pending confirmation of the pullup/pulldown in the AD0 pin.


text:
DS3231 rtc.begin() always returning false
I am using Arduino UNO with a RTC DS3231 module.
I have connected SDA & SCL pins of RTC DS3231 with Arduino SDA & SCL pins near AREF pin.
RTC module is having attached battery also.
My code is as below :
#include <RTClib.h>
#include <Wire.h>
RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {
  "Sunday", "Monday", "Tuesday",
  "Wednesday", "Thursday", "Friday", "Saturday"
};

void setup() {
  Serial.begin(9600);
  Wire.begin();
  delay(3000);
  //rtc.begin();
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
       // Following line sets the RTC with an explicit date & time
    // for example to set January 27 2017 at 12:56 you would call:
    // rtc.adjust(DateTime(2017, 1, 27, 12, 56, 0));
  }
}

void loop() {
  DateTime now = rtc.now();
  Serial.println("Current Date & Time: ");
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

    Serial.println("Unix Time: ");
    Serial.print("elapsed ");
    Serial.print(now.unixtime());
    Serial.print(" seconds/");
    Serial.print(now.unixtime() / 86400L);
    Serial.println(" days since 1/1/1970");

    // calculate a date which is 7 days & 30 seconds into the future
    DateTime future (now + TimeSpan(7,0,0,30));

    Serial.println("Future Date & Time (Now + 7days & 30s): ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();

    Serial.println();
    delay(1000);

}

While running the above command and opening the Serial Monitor, I always get following output:
Couldn't find RTC

Can anyone help me to correct this problem.

Did you connect the DS3231 to VCC and did you connect the DS3231 module's GND to your Arduino's GND? Does the DS3231 module already have pullups on the SDA and SCL lines?

Yes, I did connect DS3231 to VCC and GND with Arduino GND. How will I know if DS3231 module have pullups on SDA and SCL lines.

That should be in the datasheet or the schematics. Other question: did you run an I2C scan sketch or a different library to see if the DS3231 is visible to your Arduino?

Yes, it worked. Actually the problem was in faulty wire in SDA connection. While checking the I2C scan, it showed no I2C devices, then I checked the connections and found SDA connection faulty. After restoration, the RTC module is working fine. Thanks for the support. Though feeling very silly for such mistakes.

Feel free to post a self-answer, so that others don't need to read the whole comments dialog. Congratulations, btw. Simple problems sometimes are the hardest.

No fault is there in code. Rather, it was an faulty connection which prevented RTC module from working. Now, after restoration, the RTC module is working fine.

You can mark you own question as “answered”.


text:
Can FastLED be made faster?
I am using FastLED to drive 16 pixels on an addressable  WS2812B RGB LED strip. My application has extremely tight timing constraints. Specifically, I need to turn the LEDs on and off within less than 1 ms. I tried FastLED but it requires a minimum of 2.5 ms to execute the Show command, regardless of the number of LEDs attached. I analyzed another library and that one has the exact same limitation. In fact, I found a snippet of code that said roughly: "if this operation performs in less than 2500 us, then wait idly until the 2500 us have passed. Apparently this wait is necessary due to timing requirements of WS2812x strips. Does anyone have any advise about other addressable RGB LED strips or libraries that can be turned on and off within 1 ms?

What are you trying to achieve that needs such fast control of addressable LEDs? I suspect you are going about whatever it is the wrong way.

And why do you want to use the WS2812B LEDs for such tight timing. That doesn't seem to be a good choice, considering the 1ms time constraint and the fact, that you only have 16 pixels

I want to make a POV clock (Youtube it). In such clocks LEDs on a rotating arm are lit at precisely timed moments to create the illusion of an analog clock. For that to work, the arm must rotate at >10 revs per sec. For a clock with hands for minutes and seconds I need to divide a full rev into 60 visually distinct sectors. For that, I need to turn the LEDs on and off 60 times during one rev (100 ms).  Thus, I need the Show function to run 60 times in 100 ms. That is why the Show function's "hardwired" duration of exactly 2.5 ms is not fast enough.

I want to use the WS2812B LEDs because of the convenience of needing only one pin for data. If I used 16 individual 5mm RGB LEDs, then I would need 3x 16 = 48 PWM-enabled pins to control the LEDs. In my current attempt with a WS2812 strip I need only 3 wires between the stationary Arduino (or Teensy) and the continuously rotation LEDs, which allows me to use a slip ring to transfer power and data to the LEDs. Others who built POV clocks mounted their Arduino Nanos onto the rotor arm so they only need to transfer power through a slip ring but not a lot of PWM signals.

By default the fastLed is limiting the refresh rate to 400 fps (i.e. 2.5ms).
You can disable that with FastLED.setMaxRefreshRate(0);


text:
Where can I find SerialMonitor.java in installed Arduino IDE 1.8.13?
I have found the git source for SerialMonitor (Arduino/app/src/processing/app/*) but unable to find it in the installed Arduino IDE. I am using Ubuntu 20.04 64-bit.
I want to make changes to it, not so much a terminal emulator but just perform simple ASCII control characters like backspace (0x08). Some advice on replacing it would be appreciated too; I guess it involves jar files (I am not a java developer).
I have read elsewhere about (and used) various other terminal-type programs, but of course they stop the IDE from uploading sketches. So not much good for development.
Or if anyone knows of an already-improved Serial Monitor, and how to install it for the IDE, then that could be perfect.

IDE development is not an Arduino topic. Java is compiled so you will not find the source codes in distribution. only the built-in Serial Monitor knows when the IDE uploads

@Juraj please advise where https://github.com/arduino/Arduino topic discussions take place, if not in arduino.stackexchange.com

https://groups.google.com/a/arduino.cc/forum/#!forum/developers

After some searching, I found that Building Arduino - Steps for First Time Setup was good. It was tricky to find; most searches for 'Build Arduino' assume it's a project with an Arduino, rather than the IDE.
By building this way, I could change the source, then inside the build folder run ant run. So, no need to actually know where it goes.
I had a problem with it grumbling about
Incorrect IDE installation folder:  Your copy of the IDE is installed in a subfolder of your sketchbook. Please move the IDE to another folder.
which would have been more useful if it had said WHAT settings needed changing.
It turns out that preferences.txt had a conflict with settings sketchbook.path and runtime.ide.path. I changed sketchbook.path. All is now good.

Ah, yes. The anonymous down-voters. Some people just don't want this knowledge shared,

You can't just "find and replace" that file.
Java isn't distributed as source code. It's compiled "bytecode" that isn't modifiable by a human.
You would need to download all the source code, make your changes to it, and then recompile it.
Or, simpler: just use a more capable serial terminal program, such as "Putty" or "TeraTerm" in Windows, or "Minicom" or "Screen" on Linux. I have no idea what is available for OS X.

Screen works out of box in OS X too.

A) I did mention that jar files could be involved
B) Perhaps I'm not human, but I have successfully patched binary distribution images to fix bugs that annoyed me e.g. Copy-protected games to stop diskette wearing out, Ashton Tate/Borland DBase III & IV,
C) I HAVE downloaded all the Ardiuno git repository; I though that that was obvious. If I haven't got ALL the source, I'm still prepared to do so. Not only can I run compilers, I write & modify both compilers and decompilers.
D) As mentioned, I have and can run more capable terminal programs, BUT THEY STOP THE IDE FROM UPLOADING SKETCHES

The ide is crude and it only provides crude facilities. If you don't like it then write your own. You sound more than capable.


text:
RDM6300 library not working on ESP8266
I have a RDM6300 RFID module which I am trying to connect to an ESP8266 by using rdm6300.h library.
I had it all up an running all along with other components but we had connected to the ESP8266 but we had to move from the breadboard to an actual wired setup. Everything kept on working except for the RFID reader. The way I used to do it was by making a reference to this approach (more or less):
#include <rdm6300.h>

#define RDM6300_RX_PIN 4
#define READ_LED_PIN 13

Rdm6300 rdm6300;

void setup()
{
    Serial.begin(115200);

    pinMode(READ_LED_PIN, OUTPUT);
    digitalWrite(READ_LED_PIN, LOW);

    rdm6300.begin(RDM6300_RX_PIN);

    Serial.println("\nPlace RFID tag near the rdm6300...");
}

void loop()
{
    /* if non-zero tag_id, update() returns true- a new tag is near! */
    if (rdm6300.update())
        Serial.println(rdm6300.get_tag_id(), HEX);

    digitalWrite(READ_LED_PIN, rdm6300.is_tag_near());

    delay(10);
}

but now, after the re-arrangement it just stopped reading tags. What I did was to disconnect everything from the ESP and leave only the RDM6300 connected to it with the sample code. Unfortunately, it doesn't seem to detect any tags.
In order to test if the components are failing for some reason, I decided to test it by using SoftwareSerial.h library on it like this:
#include <SoftwareSerial.h>
SoftwareSerial RFID(2, 3); // RX and TX

int i;

void setup()
{
  RFID.begin(9600);    // start serial to RFID reader
  Serial.begin(9600);  // start serial to PC
}

void loop()
{
  if (RFID.available() > 0)
  {
     i = RFID.read();
     Serial.print(i, DEC);
     Serial.print(" ");
  }
}

and it worked perfectly fine. I was able to read the payload coming from the chip:

2 30 31 30 46 33 46 38 44 39 31 32 44 3

But, since I don't want to implement everything related to decoding this serial stream I decided to ask for your opinion what could be wrong here. It used to work without any problem but now it doesn't.
There is something interesting which I also noticed. When I run the first code snipped and change the ESP8266 pin used from 4 to 16(D0) and I upload it, once I move the tag close to the antenna the hardware light related to this pin starts flashing and when I bring the tag back (away from the antenna) it stops flashing.
This makes me thing that on a hardware level everything is fine but some software issues are happening.

a note to sw Serial sketch: pin 3 is hardware Serial RX

doesn't the rdm6300 library implement something like sw Serial? did you try sw Serial with pin 4 and rdm6300 with pin 2?

@Juraj this is the implementation: https://github.com/arduino12/rdm6300/blob/master/src/rdm6300.cpp

yes, it is a built-in sw Serial

@Juraj How does that help in my case?

did you try sw Serial with pin 4 and rdm6300 with pin 2?

I am using a single pin when making the connection between ESP8266 and RDM6300. It could be any digital pin.

yes but pin 2 works with SoftwareSerial. did you try it with RDM6300 library?

Yes, I did it that is the problem that it used to work now it doesn't. I have described it in my question.

in question you write about 4 and 16 with RDM6300 library.  and you write pin 2 works with SoftwareSerial. so did you try rdm6300.begin(2);?

I have tried that and GPIO2 led on board flashes when tag is near by, but rdm6300.update() never returns true. So, I can not detect the actual tag and read its ID. This is my problem.

What fixed the issue for me was to go to Boards manager on Arduino IDE and update to latest version:

Then I got the following error when compiling:

Board generic (platform esp8266, package esp8266) is unknown

In order to fix that, I followed these instructions.
And, I also removed rdm6300 library from C:\Program Files\Arduino\libraries and moved it in C:\Users\myusername\Documents\Arduino\libraries


text:
Fast PWM: Resolution in hertz
I am trying to get a nice sounding varying PWM to DAC, and intend to use a Sallen Key as part of an active low pass filter.
I set the Fast PWM at a max of 255 (WGM1[0-3] = 5) and set/clear OC1A upon comparing with OCR1A (1<< COM1A1)
I also update the value of OCR1A in 64 distinct steps, changing those steps around 15'000 times a second to create a specific sinusoidal shape.
As the chip works at 16 Mega Hertz, does this mean that one cycle of PWM is 16'000'000/256= 62.5 Kilo Hertz? If not, what is its resolution
Thank you!

As you are directly poking into the hardware I/O registers, you have to read the datasheet. Look for the prescaler, and the bits CS1[0-2].

Assuming you have no prescaler, you'd indeed get around 62.5kHz. The 15kHz update rate for the sinusoidal is a bit odd, as it's 1/4.167 of the PWM update frequency. I'd probably use the timers interrupt to call a function that updates OC1A every 4th call.

Thank you both for your answers! I read the datasheet but I guess without prescalers it's indeed 62.5kHz. The update will vary considerably as I'm trying to do the 12 tones of the scale. If I were to update OC1A every 4th PWM I'm not sure I'd be able to do a perfect period.

With the help of the comments, I decided to use variable PWM max values to match absolutely with the frequency. This resulted in a crispier sound that actually doesn't need the Sallen Key anymore.
For example, a low C natural, or 261.6Hz, updated 32 times for 8 full cycles of PWM give us, for a 16MHz chip, an period and amplitude of 238.
This means that having a prescaler of 8 (CS01), a period (OCR0A) AND a max potential duty cycle (ICR1) of 238, and going through 32 iterations of the sound sought for, I got the sound that I wanted and none of the wave groove that comes with a pulse duty cycle cut short.
Sure, it means less granularity when it comes to a Bb with a max duty cycle of 133, however it worked for me.


text:
Can Arduino UNO permanently store a code?
I'm really new to Arduino and wanted to know if I can make Arduino a permanent controller?
and could you help me with a cheaper alternative?
I also wanted to know about "fuse", i read it somewhere that i can protect the code from someone else who wishes to use, using a FUSE.
Thanks a lot for helping me out:)

hi thanks chris, appreciate your help, so basically i'm coding for an arduino to use it in a product commercially but since i'm really new to this idk if the arduino stores the code for ever. secondly i wish to protect the code from being copied, to a great extent.

The search keywords you are looking for are “AVR lock bits”.

idk if the arduino stores the code for ever

The code is saved in the flash memory, which is non-volatile. It does not lose its content during power cycles. Also, when looking at the time dimension, it holds the code over a very long time, though not for ever. The datasheet of the Atmega328p (the microcontroller in the Arduino Uno or Nano) states:

Reliability Qualification results show that the projected data retention failure rate is much less than 1 PPM over 20 years at 85°C or 100 years at 25°C.

So over 20 years at a temperature of 85°C you can get 0.0001% of data loss in the flash memory. At normal room temperature you can get that loss in 100 years. So significantly longer than the lifetime of most electronic products.

I also wanted to know about "fuse", i read it somewhere that i can protect the code from someone else who wishes to use, using a FUSE.

There are different ways and levels of protection. Though that is a more advanced topic, that you should tackle, when your product is finished otherwise. There are multiple resources on the web about this. The first place to look is always the datasheet of the used microcontroller. First part might be to not use the standard Arduino bootloader, but your own. And then you can set 2 fuses for getting different levels of protection (write protection, read protection), that will lock out 99% of the people. This question on Electrical SE might also be interresting for you. You can find many resources on the web by searching for something like "Arduino code protection" or "AVR code protection" (if you are using an AVR based microcontroller like with the Arduino Uno/Nano/Mega)

Apart from that I also would open the question to you, if your code is really that new and ingenious, that you need to protect it from being read that way? It might totally be, that this is the case for you. But from my perspective the probability is very low. I cannot say of my own codes, that they are worth the hassle of protection. And it also depends on what you really want to prevent that way.
For context: When you program the Arduino (or any microcontroller) with your C/C++ program, the text of the program is not saved on the Arduino. Instead the code is first converted to Assembler code and then compiled into binary machine code. On that level all the nice concepts of the higher level languages are not present, so they are done by multiple lower level functions (for example loops are jumps with conditions). An attacker might read the machine code back from the microcontroller. The biggest threat here is, that he would just copy it to a new microcontroller.
If he wants to get "code" from it, he would invoke a disassembler, which converts the machine code back to the assembler language. But at this point all symbols (names of variables, functions, ...) are lost, because they are not saved in the original machine code from the start. Reading and understanding such a code is very difficult, especially, if your code is rather big and complex. Most times it would be easier for an attacker to just reverse engineer your code based on the behavior of the original microcontroller.
So in the end, you cannot really prevent people from building counterfeit products. That's what a patent is for.
This does not mean, that you should not use the code protection. Just do a realistic security assessment and then decide, if it is worth the hassle.

Right.  Protecting your code with lock bits is not any way to prevent someone like me from copying your code.  I don’t need to see your code to copy it.  If you really think your idea is that unique then patent it.  Otherwise lock bits are like locking the doors to prevent a thief who just comes in through the window instead.  Long ago the way to make money on code was to keep it secret and prevent anyone from getting it without paying.  That’s not a very good business model anymore.  It guarantees that you won’t sell for long because those products are the first to get freeware versions.

I'm just knew to this environment, so I guess I was overexcited but the way you guys have explained(chrisl and Delta_G) I really appreciate it. Thank you!!!


text:
How to access bootloader recovery mode (like the Micro) or equivalent on the Due?
I would eventually like to use a Due as a custom USB device PC-side (through programming port) while using it as a USB Host on the native port.
Adding the programming port endpoints (perhaps willingly removing the CDC endpoints) means I may break USB descriptors, or USB to PC communication generally speaking during development.
On the Micro that's not a problem because a double reset input lets me access the bootloader for 8s and reprogram the board even though I've removed CDC endpoints altogether. But on the Due, which I am not familiar with, I can see that a double reset input does not seem to have the same effect as my script starts right away. So I am quite scared to begin messing with the USB communications if I might just break my Due permanently (or rather, until I can recover it directly accessing the MCU).
Hence the question: is there some equivalent to the bootloader recovery of the Micro (& other older boards) on the Due ?

There is an "Erase" button on the Due to wipe your sketch and access the bootloader.

I didn't know that, thanks @Majenko. This solves my problem. Feel free to post this as an answer if you want it accepted. I'll edit the question to add "recovery" [mode].

I'm not sure if you're asking the right question though. It sounds like you're going to want to reprogram the USB interface chip, in which case the main MCU has no role in this...

Ah yes I'm very new to the Due so that didn't occur to me, but the programming port uses an external Serial to USB adapter, right ? So it's not the MCU's problem and I'm in for a ride if I try to mess with it. Whereas the native USB port is directly handled by the MCU, correct ?

That is correct. Making the programming port anything other than UART will be the same as if you're doing it to the UNO.