text:
Perform Volume Control on arduino speaker
I am following this guide to produce tones with the arduino:
https://www.arduino.cc/en/Tutorial/BuiltInExamples/toneMelody
This uses the tone() builtin function. The connections is that one pin of the speaker got to one digital pin of the arduino, while the other goes to ground.
Is there a way to perform volume control (perhaps with a potentiometer) on this setup?
What worries me is that this is digital information (PWM) that goes to the speaker, and not an analog signal that can be adjusted.

one option: https://github.com/teckel12/arduino-toneac/blob/master/README.creole

@Juraj Thanks! I used this but unfortunately the sound quality is not as good as the original tone() function. In addition to that, when the sound was at the lowest, i could hear i clicking sound when every not was heard. However, i went back to the original tone() function and that clicking sound existed, however it was not as easily identified because the tone() is louder that the toneAC.

@Juraj I asked a new question about it here: https://arduino.stackexchange.com/questions/89993/clicking-sound-at-the-beggining-of-each-note

There is a library from LixieLabs that implements an audio-based PWM at super high frequencies that allows you to change the tone volume without additional hardware.

Thanks. I have tried this library, but i was not able to make it work in the past. See here: https://arduino.stackexchange.com/questions/90002/library-fails-to-compile

The tone() function generates a 50% duty cycle square wave using a timer and interrupts. 50% duty cycle is basically full volume.
It's possible to reduce the volume by reducing the duty cycle, but the tone() function does not support it. It is of course possible to change the software PWM generation to change the duty cycle (I wouldn't know how, so don't ask me), but I'll leave that as an academic exersize for you to experiment with should you wish.
An alternative is to do it in hardware. You can use an op-amp as buffer (or speaker driver) and a couple of resistors (or a potentiometer) as an "attenuator" before it to change the voltate of the signal going to the op-amp.
You need the op-amp as a buffer because the speaker will mess with the potentiometer otherwise.

Thank you! So is it possible to fix this with hardware alone? I will definately try this. I have another question that maybe you may know. At the beggining of each note, a clicking sound is heard and i don't know why, or if it is possible to mitigate it. Perhaps with an analog filter? I created a question here: https://arduino.stackexchange.com/questions/89993/clicking-sound-at-the-beggining-of-each-note. Thank you so much!

Is this how the connections to the system should be? https://imgur.com/a/tgK0hZ2 Did i understand your advice correctly?


text:
External Interrupt not working on 3.3V atmega168
I made a 3.3V board and I've put both atmega328p (that I pulled off of a 3.3V pro mini), and an atmega168 that I bootloaded (using USBtinyISP whilst selecting board "Arduino Pro or Pro Mini" and "atmega168 (3.3V, 8MHz") .
Everything works perfectly with the atmega328 - code works and interrupts do as well - which function to pull the Arduino out of sleep when INT0 rises.
However on the Atmega168, the interrupt doesn't seem to work. All the normal code works as expected (communications, instructions etc), just not the interrupt. After the Arduino goes to sleep, I can't wake it since the interrupt isn't working.
Basic code below:
#include <avr/sleep.h>//this AVR library contains the methods that controls the sleep modes

byte interruptPin = 2; //Turn board on/off
unsigned long shutDownTimer = 0; // Timer for shutdown

void setup() {
  Serial.begin(57600);
  pinMode(interruptPin, INPUT); //Set pin d2 to input using the buildin pullup resistor
  Serial.println("Starting");

}

void loop() {
  Serial.println("Awake");
  delay(1000);

  // Shutdown control
  if (digitalRead(interruptPin) == LOW ) {
    Serial.println("Shutdown detected");
    shutDownTimer = millis();
    while (digitalRead(interruptPin) == LOW ) {
      if (millis() - shutDownTimer > 1000) {
        Serial.println("sleep mode triggered");
        Going_To_Sleep();
      }
    }
  }
}

void Going_To_Sleep() {
  sleep_enable();//Enabling sleep mode
  delay(1000);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);//Setting the sleep mode, in our case full sleep
  delay(1000); //wait a second to allow the led to be turned off before going to sleep
  attachInterrupt(0, wakeUp, RISING);//attaching a interrupt to pin d2

  Serial.println("Interrrupt attached");//Print message to serial monitor
  sleep_cpu();//activating sleep mode
  Serial.println("just woke up!");//next line of code executed after the interrupt

}

void wakeUp() {
  sleep_disable();//Disable sleep mode
  detachInterrupt(0); //Removes the interrupt from pin 2;
  Serial.println("Interrrupt Fired - wakeup");//Print message to serial monitor

}

Instead of using "attachInterrupt(0, wakeUp, RISING);" Ive also tried the following which also don't work:
attachInterrupt(INT0, wakeUp, RISING);
attachInterrupt(digitalPinToInterrupt(interruptPin), wakeUp, RISING);
attachInterrupt(32, wakeUp, RISING);  //since its the pin of the chip? Hail Mary
attachInterrupt(2, wakeUp, RISING);  //obviously this won't work, Hail Mary 2

I have no idea why the interrupts aren't working. I have an inkling it might be due to something fuse related within the boot loader, but I don't really understand things at that level (Though I'm happy to dive in with some guidance). Any guidance will be appreciated!

Your Serial.println inside the ISR is putting you in danger of locking up there. Test using an LED or something instead.

According to the datasheet for the Atmega168:

Note that recognition of falling or rising
edge interrupts on INT0 or INT1 requires the presence of an I/O clock, described in
Section 6.1 “Clock Systems and their Distribution” on page 23. Low level interrupt on INT0 and INT1 is detected
asynchronously. This implies that this interrupt can be used for waking the part also from sleep modes other than idle mode.
The I/O clock is halted in all sleep modes except idle mode

In other words, only the LOW interrupt wakes it from sleep.
Having said that, the Atmega328P does wake from sleep with a rising or falling interrupt, as I have previously had confirmed by Atmel, however I can't say for sure that this enhancement (over what is stated in the datasheet) applies to the 168.
You could try doing a bit of testing to confirm that. Maybe rejig so that the interrupt occurs when the signal goes low rather than high, and then use a LOW interrupt and not a RISING one.
Also, don't do serial prints inside an ISR. The modern versions of the library handles that better than in the past, but this may still be an issue. As suggested in a comment, try flashing an LED rather than printing something. Or don't print anything, after all you print something when it wakes up. Why print something extra inside the ISR? That is just asking for trouble.

I didn't see the information in the Atmega328P data sheet stating that it works with rising, and that the Atmega168 does not work with rising. However it is indeed functioning consistently with what you say. I'll just have to use Atmega328's for this application. Thanks.

Depending on what signal you are using to wake the Arduino, you may also find pin change interrupts an alternative to the edge triggered interrupts you are currently using.
These are usually more predictable in behaviour and less subject to nuanced interpretations of the data sheets.
See https://playground.arduino.cc/Main/PinChangeInterrupt/ for examples of how to use these.

source: Stack Exchange

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

sort: votes


text:
PubSub'a - KeepAlive function not as expected
I'm using PubSubClient to pub/sub MQTT messages using ESP8266.
As far as I know "Keep-alive" detects when a client went off-line after a period of time.
I'm using library's example mqtt_ESP8266 with 2 minor adjusments (noted "<----- 1/2"), to use keepAlive.

Timeout was set to 45 sec (client.setKeepAlive(45);), in order to be "far enough" from reboot.
Pressing on-board Reset button.
Although Wifi+MQTT connection establish after 10 sec, and mqtt sends messages as shown loop, a "DEAD" publish is sent to designated topic after roughly 45 seconds from (2) , whuch makes no sense since MQTT was reconnected 35 seconds before.

Appreciate assistance,
Guy
/*
  Basic ESP8266 MQTT example
  This sketch demonstrates the capabilities of the pubsub library in combination
  with the ESP8266 board/library.
  It connects to an MQTT server then:
  - publishes "hello world" to the topic "outTopic" every two seconds
  - subscribes to the topic "inTopic", printing out any messages
    it receives. NB - it assumes the received payloads are strings not binary
  - If the first character of the topic "inTopic" is an 1, switch ON the ESP Led,
    else switch it off
  It will reconnect to the server if the connection is lost using a blocking
  reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
  achieve the same result without blocking the main loop.
  To install the ESP8266 board, (using Arduino 1.6.4+):
  - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":
       http://arduino.esp8266.com/stable/package_esp8266com_index.json
  - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
  - Select your ESP8266 in "Tools -> Board"
*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "Wifi";
const char* password = "Password";
const char* mqtt_server = "192.168.2.100";

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

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

  randomSeed(micros());

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

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is active low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }

}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    client.setKeepAlive(45);  \\ <--------- Line 1
    if (client.connect(clientId.c_str(), "guy", "kupelu9e", "myHome/log", 0, true, \\ < "DEAD")) { \\ <---- Line 2
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  unsigned long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("myHome/debug", msg);
  }
}

This is the correct behavior.
The “last will” message is sent by the broker when it detects that the client has gone away.
When you reset the ESP8266, the original connection to the broker is destroyed. When it restarts, it creates a new, second connection, it does not resume the original connection. So the broker correctly transmits the last will message when the original connection times out.

even it connects in same client ID ? so what's the point?

The point is to notify other clients when a client terminates without disconnecting. The client ID is irrelevant unless you use a session with MQTT 5. Both the client and broker must support MQTT 5 for that to work; in that case, if the client reconnects before the “last will delay”, the will won’t be sent. pubsubclient does not support MQTT 5.

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


text:
passive buzzer is drawing 500mA
I am having a ridiculously hard time trying to make a passive buzzer work correctly on my Seeeduino XIAO.
Here is the buzzer module :

Here is how I believe it works, assuming the SOT23 smd is a PNP transistor? :

I plugged VCC to a +5V rail, GND to the ground rail, and I/O pin to my Seeeduino XIAO's pin 2 (aka "A2 / D2" :

When I write DigitalWrite(2, LOW), I can mesure about 0.4V on pin 2, while DigitalWrite(2, HIGH) reads about 3.3V (I assume the 5V rail feeding my Seeeduino XIAO's VCC gets converted to 3v3 through an internal regulator)
I understand I have to oscillate the signal to make this module buzz (remember it is a passive buzzer, or a transducer, whatever it is called), or simply use the tone() method, and I eventually managed to make this beep on and off every 1 second successfully during 10 seconds, but what bothers me is that I can NOT turn this module OFF after 10 seconds as a test in my sketch. It stops beeping after 10 sec as expected (ìf (millis() < 10000) { doBeep(); } , but it still draws massive current and gets hot after that delay. It's like the PNP transistor never turns off? I tried both digitalWrite HIGH and LOW but no success.
This is driving me crazy. What am I doing wrong?

You're right that it's a PNP transistor - the SS8550 to be precise.
And therein lies the problem.
When running at 5V to "make no current flow" through the base the voltage at the base has to be higher than 4.4V (5v - 0.6v), and since you're controlling it from a 3.3V microcontroller that can never happen. So you are right in thinking it never turns off - it never does.
Even when you're "beeping" it it's not turning fully off, so the beep sounds you make will be reduced accordingly.
You should power the board from 3.3V instead of 5V so the PNP can turn off fully. If that is not possible then switching the GPIO pin to INPUT mode will prevent it from driving the PNP thus allowing it to turn itself off.

Thank you for the explanation. Adding an AMS1117 3.3v did solve the issue. The buzzer was shy indeed. Knowing all this, I will probably prefer a logic level converter.


text:
Where should unit tests go in the Arduino IDE
I have an Arduino project where the file structure looks like this
myProject/
    myProject.ino
    ImportantClass1.hpp
    ImportantClass1.cpp
    ImportantClass2.hpp
    ImportantClass2.cpp
    Etc….

It compiles and runs fine. No problem pulling the cpp and hpp files into the ino program. However to really make sure of reliability I want to make additional ino files for unit testing of importantClass1 & etc. I have made files importantClass1UnitTest.ino & importantClass2UnitTest.ino however these can’t be in the same dir as the respective source files as the arduino compiler requires the ino file and the dir to have the same name.
The tests run when I move the files around. But I am not happy with that, I want to be able to run the tests at any time with the standard arduino compiler without having to script filecopy commands.
If I put the unit test in its own dir separate to the class source and #include using the full path it also works. However this solutions is not portable, when I (or any collaborator) pull the project from git hub on any other computer the paths are wrong and it doesn’t work.
Where am I going wrong? How can I do this so as to avoid moving/copying files and also avoid using full paths?

I do not think there is a standard “Arduino way” of storing unit tests, and this is a great question that may, hopefully, help reveal best practices. I would suggest to #include a relative (rather than absolute) path.

Thanks @EdgarBonet I have tried relative paths and can’t get them to work. If the path is relative to the location of unitTest.ino file then the relative path has to start with ../../location of source. But this doesn’t work for me. Where would the relative path be relative to?

Without a working environment, I would use "../myProject", if "myProject" is on the same level as "importantClass1UnitTest".

@EdgarBonet, Arduino IDE/CLI compiles and builds in a temporary folder. relative paths don't work.

Confirmed. Relative paths don't work.

Can you use symbolic links?

OK. Thank you @EdgarBonet. Have found a way to do it based on sym-links. Will write an answer below...

One way to do it is to use preprocessor conditionals. Name your project file and unit-test files with .cpp extensions and put them in a subfolder (called "sources" in my example). Then your .ino file would only be used to instruct the preprocessor which of the several "main" file to start compiling with:
myProject.ino:
/*
 * myProject.ino
 * define which "main" CPP file to compile:
 */

#define PRODUCTION
// #define UNITTEST1
// #define UNITTEST2
// #define UNITTEST3

// The compilation starts here with the requested "main" file:
#if defined PRODUCTION
#include "sources/myProject.cpp"

#elif defined UNITTEST1
#include "sources/unitTest1.cpp"

#elif defined UNITTEST2
#include "sources/unitTest2.cpp"

#elif defined UNITTEST3
#include "sources/unitTest3.cpp"

#else
// If nothing defined, compile for production
#include "sources/myProject.cpp"
#endif

/* END */

Only the .ino file would need to be edited to compile one of the unit tests, and only one project file would be needed.
Update:
"did you try it? "
Yes, and it does work. The only caveat I'd add is: don't name your subfolder "src" - that seems to be a magic-name to the IDE, and you'll get complaints of compilation errors (multiple definitions) if you use it. And further, if you try it, you can't get back simply by changing the folder's name (on disk and in the code); you'll have to restart the IDE as well.
I tested it with v1.8.19 of the IDE.

Given that the two files I placed in the folder were a complete Arduino 'blink' sketch and a complete 'Hello, World' sketch, but with .cpp extensions,, and that selecting one or the other as I showed in the my answer and compiling and downloading produced the expected results, than, yeah, I can definitely say they were compiled. But don't take my word for it; try it yourself.

sorry. yes. the cpp was not a cpp. it was just an included file. it could have txt or ino as filename extension.

Thanks for the answer. I am not going to do it this way though. Looks like I will have to make test runner scripts that overcome the lack of support for relative paths by copying files from the project dir to the unit test dir and maybe running the unit tests with the Arduino CLI.

@HubertB, it would be great if you can share an example when you can of your intended alternative solution as another answer here.

OK. Update, better late than never. I used soft links to overcome this problem.
The final directory structure is like this:
myProject/
    .git/
    myProject.ino
    Class1.hpp
    Class1.cpp
    Class2.hpp
    Class2.cpp
    ...
    UnitTests/TestClass1/TestClass1.ino
    UnitTests/TestClass1/Class1.cpp -> ../../Class1.cpp
    UnitTests/TestClass1/Class1.h   -> ../../Class1.h
    ...

Both the main program and all the unit tests run fine when compiled in the Arduino compiler and there is only one copy of the class files that I want to test.


text:
Help with reading data from ADXL373 Accelerometer (I2C)
I am using ADXL373Z accelerometer with Arduino Uno for a project.
When I run the code, I am getting incorrect values which are probably not even acceleration data. I am thinking it might be a wiring problem, I attached circuit diagram below. This is my first Arduino project, and I couldn't find any other applications with the sensor I am using so any help would be much appreciated. Thanks in advance.
Datasheet for sensor : https://www.analog.com/media/en/technical-documentation/data-sheets/adxl373.pdf
Code ( for x-axis data only) :
// ADXL373 Accelerometer Test

#include <Wire.h>

/* -------- REGISTERS -------- */
#define ADDRESS_ADXL373 0x53 // sensor adress (assumes MISO pin high)
#define ADDRESS_POWER_CTL 0x3F // power control
#define ADDRESS_MEASURE 0x0E // measurement control
#define ADDRESS_TIMING 0x3D // output data rate and extarnal timing triggers
#define ADDRESS_XDATA_H 0x08 // x-axis acceleration data [11:4]
#define ADDRESS_XDATA_L 0x09 // x-axis acceleration data [3:0]
#define ADDRESS_YDATA_H 0x0A // y-axis acceleration data [11:4]
#define ADDRESS_YDATA_L 0x0B // y-axis acceleration data [3:0]
#define ADDRESS_ZDATA_H 0x0C // z-axis acceleration data [11:4]
#define ADDRESS_ZDATA_L 0x0D // z-axis acceleration data [3:0]
/* -------- REGISTERS -------- */

#define SCALE_FACTOR 0.2f // 200 mg per LSB scaling factor
#define GRAVITY_EARTH 9.80665f // gravity of earth in m/s^2

void setup() {
  Serial.begin(115200);
  while(!Serial);
  Serial.println("ADXL373 Accelerometer Test");
  Wire.begin();
  Wire.beginTransmission(ADDRESS_ADXL373);
  Wire.write(ADDRESS_POWER_CTL);
  Wire.write(0x03); // activate full bandwith measurement mode
  Wire.endTransmission(true);
  delay(50);
  Wire.beginTransmission(ADDRESS_ADXL373);
  Wire.write(ADDRESS_MEASURE);
  Wire.write(0x04); // set output signal bandwith to 2560 Hz
  Wire.endTransmission(true);
  delay(50);
  Wire.beginTransmission(ADDRESS_ADXL373);
  Wire.write(ADDRESS_TIMING);
  Wire.write(0x80); // set output data rate to 5120 Hz
  Wire.endTransmission(true);
  delay(50);
}

void loop() {
  byte xAxisH, xAxisL;
  Wire.beginTransmission(ADDRESS_ADXL373);
  Wire.write(ADDRESS_XDATA_H);
  Wire.endTransmission(false);
  Wire.requestFrom(ADDRESS_ADXL373, 1, true);
  xAxisH = Wire.read();
  Wire.beginTransmission(ADDRESS_ADXL373);
  Wire.write(ADDRESS_XDATA_L);
  Wire.endTransmission(false);
  Wire.requestFrom(ADDRESS_ADXL373, 1, true);
  xAxisL = Wire.read();
  int16_t xAxisFinal;
  xAxisFinal = (uint16_t) xAxisH << 8 | xAxisL; // bit shift and combine two components
  xAxisFinal = xAxisFinal >> 4; // 12-bit resolution
  float xAccel;
  xAccel = xAxisFinal * SCALE_FACTOR * GRAVITY_EARTH;
  Serial.print("Xa = "); Serial.println(xAccel);
  delay(200);
}

Circuit Diagram :

Results from Serial Monitor (in m/s^2) :

xAxisFinal = xAxisH << 4 | xAxisL; I think you mean << 8.

According to the datasheet, the 12 bits of the X acceleration are stored
into the registers XDATA_H and XDATA_L as follows:
XDATA_H:   b₁₁b₁₀b₉ b₈ b₇ b₆ b₅ b₄
XDATA_L:   b₃ b₂ b₁ b₀ x  x  x  x

where x means “reserved”.
Now, there are two issues with this code:
xAxisFinal = xAxisH << 4 | xAxisL; // bit shift 12-bit output data

The first issue is that, by shifting xAxisH by four places, the bits
b₇–b₄ end up in the same positions as the bits b₃–b₀ in xAxisL. Then,
when those values are combined with |, the bit b₇ gets mixed with b₃,
b₆ with b₂, etc. If you really want to shift xAxisH left by four
places, you should also shift xAxisL right by four places.
The second issue is that the x data is a signed number represented as
two's complement, and the sign bit (b₁₁) ends up in the wrong place. For
example, if the measured value is −16 (XDATA_H:XDATA_L = 0xff:0x00),
you end up reading 4980 (0x0ff0). In order to avoid this issue you could
sign extend the 12-bit number to 16 bits.
I would suggest, though, a completely different approach. The number is
left justified in the sensor registers, so just keep it like this:
xAxisFinal = (uint16_t) xAxisH << 8 | xAxisL;

The intermediate cast to uint16_t is here to avoid an undefined
behavior, the final result is signed. If there is some risk that the
reserved bits are non-zero (the datasheet is not very clear in this
respect), you could
xAxisFinal &= 0xfff0;  // clear last 4 bits

Note that now the unit of the acceleration is 1/16 of the resolution of
the sensor, and all values you get are multiples of 16. I don't expect
this to be an issue. If you really want to use the sensor resolution as
your unit, you could now shift xAxisFinal four places to the right,
which would automatically perform the sign extension.

Edit: Addressing the edited code from the OP:

I modified the code according to your suggestions. But I am still
getting incorrect values from serial monitor.

What I see in your post is very small values, around ±3 LSBs of the
sensor. This could very well be sensor noise. But then, there is the
occasional larger value. Interestingly, those larger values seem to be
very close to ±16 LSBs, hinting at some kind of communication
problem.
I guess the answer is in this warning from the sensor's datasheet:

Always read acceleration data using multibyte transfers to ensure that
a concurrent and complete set of x, y, and z acceleration data is
read.

Imagine the sensor is outputting only noise, and the noise fluctuates
between −1 and +1 LSB. What you expect then is:
value  XDATA_H   XDATA_L
  −1   11111111  11110000
  +1   00000000  00010000

If you read XDATA_H and XDATA_L in two different transactions, you
may well read 0b11111111 for XDATA_H (as the sensor is reading  −1),
then read 00010000 for XDATA_L (as it is getting +1). When you
combine these two readings together, you get
value  XDATA_H   XDATA_L
 −15   11111111  00010000

I suggest you follow the recommendation from the datasheet and read both
registers in one go:
Wire.beginTransmission(ADDRESS_ADXL373);
Wire.write(ADDRESS_XDATA_H);
Wire.endTransmission(false);
Wire.requestFrom(ADDRESS_ADXL373, 2, true);
xAxisH = Wire.read();
xAxisL = Wire.read();

Heh. Your answer came in about when my comment did.

Thanks, I modified the code according to your suggestions. But I am still getting incorrect values from serial monitor. I edited the code and results in my post. If you have any other suggestions I would appreciate it.

@Maxxie: See expanded answer.


text:
Measured voltage higher than AREF
What happen when a  voltage measured by analogRead() is higher than AREF voltage?
Example: AREF = 2.5V AO = 3.2V
What is the maximum voltage ?

About which microcontroller are you asking? Normally AREF must be within a rather small range around Vcc.

AREF is basically top value of ADC, AVCC must be around Vcc.  If your AO will be bigger than Vcc, then internal protection diodes takes place (so Vcc might be pulled to AO level, eventually protection diode might get destroyed by over current, or MCU by overvoltage)

You will be reading the maximum ADC value. If you were sampling a waveform the top of it would be clipped off at 2.5v.


text:
PWM on Wemos D1 Mini (esp8266 chip) does not work
I am working on a hobby project: creating an rc-(radio controlled)-toy car.
I'm working with a Wemos D1 Mini (esp8266) microcontroller, L298N H-bridge (for controlling the motor) and I'm using the Arduino IDE to program it all.
The project is quite simple: make the car drive around via an virtual joystick on an app. The project is quite fun and a nice learning experience for me. The project is going pretty well until this point.
I can move the car forwards and backwards with a constant speed, but I'm not able to change the speed via a PWM signal. Actually, I'm not even sure if it is even possible to create a PWM signal on the Wemos D1 Mini, I have never done it before on this specific controller. I'm not an electrical engineer, so I'm not really familiar with very specific details about the controller itself.
Can somebody help me create a PWM signal to control the speed of the car?
This is what I have got now, very basic stuff:
void setup() {
  pinMode(D2, OUTPUT);
  pinMode(D5, OUTPUT);
  pinMode(D6, OUTPUT);
  pinMode(D7, OUTPUT);
  pinMode(D8, OUTPUT);
}

void forward() {
  digitalWrite(D5, LOW);
  digitalWrite(D6, HIGH);
}

void backward() {
  digitalWrite(D5, HIGH);
  digitalWrite(D6, LOW);
}

void setVelocity(int value){
  analogWrite(D2, value);
}

void loop() {
  setVelocity(1023);
  forward();
}

Thanks in advance!
Sincerly,
Stefan

how did you try to change the speed?

@jsotola presumably analogWrite to the enable pin on D2.

@timemage that is unknown

Yes, D2 is the enable pin! @timemage

I think I'm going to switch to a different microcontroller

See here regarding about the change in default for range in analogWrite calls. Your code is producing a 50% duty cycle waveform at 1KHz if told to setVelocity to 128.

You don't have to switch to a different microcontroller. As @timemage's link pointed out, if you're using an ESP8266 core >= 3.0.0, you could either reduce the range of analogWrite from 0..255 or put analogWriteRange(1023); in your setup().

At one point analogWrite as it was implemented in the esp8266-core had defaulted to a 10-bit range. This is no longer the case. It defaults to 8-bit range now.
In any case analogWrite is implemented to clamp the given value to be within the range.
If you were not experimenting in the bottom quarter of the velocity range with your code as written then you would have seen full velocity.
You can change to working with the 8-bit range or use analogWriteRange(new_range) or analogWriteResolution(bits) as this mentions.
Your code as is will produce a 50% duty cycle 1Khz signal on D2 if setVelocity is given 128 with the current core.

Thanks for your swift response! It turns out... my ESP8266 board core was very outdated :( I think that was the problem. And you are right it is 8 bit now! I'm very happy it works now! Thanks for your help, very much appreciated!


text:
ISR for very fast processes, strange code found. Has ISR effect on timer behaviour?
I found the following code within an example for performing very fast changes on a PWM-output. It works, however I'm wondering about some details.
TIMER2 was set up in setup() as follows:
TCCR2A = 0;               // We need no options in control register A
TCCR2B = (1 << CS21);     // Set prescaller to divide by 8
TIMSK2 = (1 << OCIE2A);   // Set timer to call ISR when TCNT2 = OCRA2
OCR2A = 32;               // sets the frequency of the generated wave
sei();                    // Enable interrupts to generate waveform!

If I understand that correctly, the timer will run until overflow and generate interrupts any time in between as defined by OCR2A.
ISR(TIMER2_COMPA_vect) {  // Called each time TCNT2 == OCR2A
  static byte index=0;    // Points to successive entries in the wavetable
  OCR1AL = wave[index++]; // Update the PWM output
  asm("NOP;NOP");         // Fine tuning
  TCNT2 = 6;              // Timing to compensate for time spent in ISR
}

TIMER2 is used to call this routine in equidistant points in time.
To adapt the timespan between two calls of the ISR the author sets OCR2A and within the ISR resets TCNT2. As the timer is reset at the end of the ISR there's some time "already gone" written into the start value of the timer. However there are two things I don't understand.

Why isn't CTC mode used by setting WGM21 in TCCR2A? This should call the ISR in precise intervals.

If not using CTC mode the counter has to be reset by the ISR. But why isn't that done directly at the beginning of the ISR? Everytime the ISR gets some minor changes the correction value written into TCNT2 has to be changed.

Am I missing some vital detail? Or is my idea of using CTC better?
For sake of completeness, the only other things done in setup() are configurations on timer1:
pinMode(9, OUTPUT);       // Make timer's PWM pin an output
TCCR1B  = (1 << CS10);    // Set prescaler to full 16MHz
TCCR1A |= (1 << COM1A1);  // PWM pin to go low when TCNT1=OCR1A
TCCR1A |= (1 << WGM10);   // Put timer into 8-bit fast PWM mode
TCCR1B |= (1 << WGM12);

loop() is empty.

Mhh, not using CTC in such a case doesn't make much sense to me either. Especially since the timer does not stop when the compare ISR is called. It will keep running just fine while the ISR is working (since the Timer works in hardware). I would guess that this is just a bad code

Why isn't CTC mode used by setting WGM21 in TCCR2A?

As we cannot read the author's mind, we cannot say for sure. That being
said, to me, the most likely reason is that either the author was not
aware of CTC mode, or they just didn't think about it.
You are right that CTC is the most straightforward way to get precise
intervals. You are also right that the resetting the timer at the end of
the ISR makes the code somewhat fragile. If, for some reason, I needed
to avoid CTC in a code like this, I would
OCR2A += 32;

rather than resetting TCNT2.

I tend to think, the author did not know the CTC mode well enough. Otherwise I cannot explain the solution proposed. I was just stunned because it was published in a magazine. https://makezine.com/projects/advanced-arduino-sound-synthesis/  Not that I think this is a guarantee for quality but who knows...


text:
Determining ArduinoJSON document size based on file size
I'm trying to effectively allocate a doc's size, based on the size of the file saved in flash of ESP8266. Is there a way?
For example: file.size() X 1.5

I would think it very much depends on what the content is. If you have a lot of string data then it can correlate quite well. If you have a lot of numeric data then I would imagine the internal representation could be a lot smaller than the textual file representation of the same data.

@Majenko Since some parameter files are stored on flash (which also can be change in future), one size's can be 256, and other is 1250. My goal is not to allocate max of all

There is unfortunately no way to predict the size of the JsonDocument from the file size alone.
As a workaround, I suggest that you allocate a very large memory pool and shrink  it after deserialization; like so:
DynamicJsonDocument doc(ESP.getMaxAllocHeap());
deserializeJson(doc, file);
doc.shrinkToFit();

Indeed, this program consumes more memory than strictly required, but only for a fraction of a second.
See also:

How to determine the capacity of the JsonDocument?
BasicJsonDocument::shrinkToFit()

Is only for DynamicJsonDocument?

@guyd shrinkToFit is available in BasicJsonDocument, too. But not in JsonDocument or StaticJsonDocument. See the docs to determine which one to use in your use case.

Depending on what is actually being done, the filtering feature may also be helpful.

@guyd, you asked how to determine the document size at run time, so StaticJsonDocument is not an option.


text:
Funduino USB Host Shield problems
I'm currently working on connecting a Funduino version of usb host shield onto an arduino mega board. But the serial output shows "osc did not start", which means the board can't find the shield. However the reset button works, so I estimate insufficient power being supplied.

I'm aware of the bridging solution for the regular arduino module for the 3.3v and 5v (example). But how can this solution be applied to the Funduino model.
Update: I've changed the SPI lines on the shield to the 6 ISCP pins on the Mega, but still no change in results.
I performed a second test using board_qc, which returned:
Circuits At Home 2011
USB Host Shield Quality Control Routine
Reading REVISION register... Die revision invalid. Value returned: 00
Unrecoverable error - test halted!!
0x55 pattern is transmitted via SPI
Press RESET to restart test

Please provide a link to the product page of that shield.

https://www.altronics.com.au/p/z6342-funduino-usb-host-shield/#/

https://fluxworkshop.com/products/ccaa100015-uno-usb-host-shield-keyes-red?variant=32458615783484

And can you please provide a link to the used library (and include either your sketch or point to the example code that you might be using)

https://www.arduino.cc/reference/en/libraries/usb-host-shield-library-2.0/ I used version 1.5 as shield requires.

That shield communicates over SPI. However the SPI pins it uses are the "old" style (10-13) for the Arduino UNO.
The Mega doesn't use those pins, which is why the "new" style 6-pin SPI/ICSP header was added to boards.
You will have to manually jumper the right pins to the SPI pins of the Mega using wires.

Can you provide a pinout, so that I know where to make connections.

You would need to refer to the schematic or manual for the shield (which I don't have). The pinout for the mega is well documented.

I have tried connecting the SPI to the 6 pins in the center, but am still getting the same results.

I have also tried the SPI pins at the bottom of the Mega.

If the shield was designed for the Arduino Uno, then it would have a similar pinout to interface with it. So I used the Uno pinout as reference.

You should look for the actual pinout of the shield. You may have an interrupt signal to cope with, and there's no telling where any other logic signals may be...


text:
Can't pair two HC-05 (Master - Slave)
I want to connect two HC-05 modules, one master and one slave. So to that I need to access 'AT Commands'.
Theoretically, I just needed to upload an empty code, and then connect the module to the arduino in command mode (I use a Nano) TX and RX pins and then go to the Serial Monitor at 38400 baudrate and sent the AT commands. In the past this worked for me, but now this ain't working anymore.
So I went for some code online and aparently AT commands started working. I configured master and slave, and binded the address of the slave to the master.
I connected the modules to an input voltage and I was expecting a connection between them but they are not pairing. On youtube videos they say to connect with two different arduinos, but doesnt make any sense to me because they should connect by themselves just for being ON.
I don't know what to do, I need these working for a project and I'm just wasting time searching on the internet, because nothing works for me. I just didnt tried using them with 2 arduinos with code on them, but I dont think thats the issue AND IF IT IS, please tell me what's the correlation.

Are you sure about that the modules should connect automatically on startup? Honestly I wouldn't think that to be the case. Also: What exactly are you trying to do if you don't use 2 Arduinos with your two HC-05 modules?

@chrisl I saw man videos on youtube and after they configure the modules they just put them both in data mode and they pair by themselves, I dont really know why they put them alingside 2 arduinos. I'm using an arduino and an STM32, but as I said, they should connect by themselves

Are you sure you've binded master to slave? Try writing AT+BIND? for master and AT+ADDR? for slave, they should match.


text:
Can we use more than one timer when programming an Atmega32/16?
I tried to do a simple program using the ATmega16 microcontroller, the program is to toggle two LEDs the first one by using timer0 interrupt and the other using timer2 interrupt.

If you put them on correct pins, you can setup timers to toggle them without any software handling. Also yes, you can have more than one ISR and even all the timers running at the same time

Yes, you can. However there is one thing to note:
Only one ISR can run at once.
That means that if one LED wants to toggle while the other one is in the process of toggling it will have to wait until that first ISR is finished before it can toggle.
For simple LED toggling that won't be noticeable, but it's something you need to bear in mind if you are doing multiple things that require precise timing.

Yes, we can.
(stackexchange wants the body of the answer to be at least 30 characters, so I have to add some filler. Truth is, for answering the question as asked, there is nothing more to say.)


text:
ESP8266 Wemos D1 min pro - how to change TCP_SND_BUF?
Is there any way to change the TCP send buffer size (TCP_SND_BUF) on this module ?
Now it is equal to TCP_SND_BUF = 2 * TCP_MSS = 2 * 1460 = 2920.
Editing lwipopts.h doesn't make any difference.
The same question applies to ΤCP_MSS, TCP_WND etc.
I am using v2 Higher Bandwidth variant. Platform is Microchip Studio with vMicro Arduino addon.

I finally figured it out the hard way :
https://github.com/esp8266/Arduino/discussions/8616

Install Git for windows (https://git-scm.com/download/win)
Install MinGW for windows (https://sourceforge.net/projects/mingw)
In MinGW installation manager, enable:

mingw-developer-toolkit
mingw32-base
mingw32-gcc-g++
msys-base

(not sure if all are necessary but just in case)
put C:\MinGW\bin in Windows PATH (check this https://www.rapidee.com)
reboot PC
rename C:\MinGW\bin\mingw32-make.exe to C:\MinGW\bin\make.exe
open bash terminal (just type bash in run)
(from now on assume that hardware files are in \Documents\Arduino\hardware\esp8266com\esp8266)
go to \tools\sdk\lwip2
optional: change lwip options in \tools\sdk\lwip2\builder\glue-lwip\arduino\lwipopts.h
(caution : NOT \tools\sdk\lwip2\include\lwipopts.h, this will be overwritten !)
type in bash: make install to build libraries in \esp8266com\esp8266\tools\sdk\lwip2\builder
type in bash: make clean to clean \esp8266com\esp8266\tools\sdk\lwip2\builder
finally copy new libraries to \esp8266com\esp8266\tools\sdk\lib

May all richnesses of the world reach you, my friend, for I have been going crazy the entire day yesterday trying to figure this out!

No, you can't.
The macro you are trying to tweak is for reference only and does not control the size of the buffer.
On the ESP8266 the IP stack (and much of the rest of the system) is precompiled as .a libraries. Changing things like the TCP_SND_BUF macro will never change what has been compiled into those libraries. Instead all it will do is cause problems of buffer overruns and corrupted data as other code is then given incorrect information about the size of the buffer.


text:
Create member object using constructor arguments, or pass reference to object via constructor
I'm not entirely sure about the proper C++ terminology, so I'll just illustrate what I'm trying to achieve by giving a Java example since it should be pretty obvious:
public class LcdDecorator {
    private HD44780Lcd lcd;

    public LcdDecorator(int rows, int cols, int i2cAddress) {
        this.lcd = new HD44780Lcd(rows, cols, i2cAddress);
    }
}

or... alternatively...
public class LcdDecorator {
    private HD44780Lcd lcd;

    public LcdDecorator(HD44780Lcd lcd) {
        this.lcd = lcd;
    }
}

For what it's worth, there's no real concern about scope... LcdDecorator is a Singleton that gets created in setup(), then lives forever and gets used by loop() until the power gets shut off.
Here's what I've attempted so far:
LcdFacade.h:
#ifndef CORECONTROLLER_LCDFACADE_H
#define CORECONTROLLER_LCDACADE_H

#include <stdint.h>
#include "../.pio/libdeps/megaatmega2560/HD44780_LCD_PCF8574/src/HD44780_LCD_PCF8574.h"

class LcdFacade {

public:
    LcdFacade(uint8_t rows, uint8_t cols, uint8_t i2cAddress) ;
};

#endif //CORECONTROLLER_LCDFACADE_H

LcdFacade.cpp:
#include "LcdFacade.h"
#include "../.pio/libdeps/megaatmega2560/HD44780_LCD_PCF8574/src/HD44780_LCD_PCF8574.h"

HD44780LCD lcd;

LcdFacade::LcdFacade (uint8_t rows, uint8_t cols, uint8_t i2cAddress) : lcd{rows, cols, i2cAddress} {
    // ... the rest of the constructor goes here ...
}

note: I also tried using parentheses instead of braces for lcd's constructor:
LcdFacade::LcdFacade(uint8_t rows, uint8_t cols, uint8_t i2cAddress) : lcd(rows, cols, i2cAddress) {

In CLion, the 'lcd{rows, cols, i2caddress}' portion of the constructor in LcdFacade.cpp is red-underlined, and reports member initializer 'lcd' does not name a non-static data member or base class
Meanwhile, gcc(?) reports error: no matching function for call to 'HD44780LCD::HD44780LCD() on line 4 of LcdFacade.cpp.
Any ideas?

When you define
HD44780LCD lcd;

at global scope, you are creating a global variable that is initialized
before main() is called. In this case, it is initialized with the
default constructor HD44780LCD::HD44780LCD(), which does not exist,
hence the error. You could avoid this error by calling a suitable
constructor in the initialization, e.g.
HD44780LCD lcd(4, 20, 0x23);

but this may be inconvenient to you.
If you want to initialize lcd in the constructor of LcdFacade, then
it must be a non-static member of the class:
// In LcdFacade.h:
class LcdFacade {
public:
    LcdFacade(uint8_t rows, uint8_t cols, uint8_t i2cAddress);
private:
    HD44780LCD lcd;  // <- non-static member
};

// In LcdFacade.cpp:
LcdFacade::LcdFacade(uint8_t rows, uint8_t cols, uint8_t i2cAddress)
: lcd(rows, cols, i2cAddress) {
    ...
}


text:
Why does the data I send to the server get rounded off and how do I send the entire float instead?
#include <Arduino.h>
#include <WiFi.h>
#include "WiFiManager.H"
#include <HTTPClient.H>
#include "ESPAsyncWebServer.h"
#include <AsyncTCP.h>

float version = 1.9;

uint32_t chipId = 0;
String chipId2 = "";
int i;

String serverName = "http://d";

// WiFiManager
// Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wifiManager;

// Create AsyncWebServer object on port 80
AsyncWebServer server2(80);
WiFiServer server(80);

// variables to count the pulses of the meters.
int count1=0;
float prior_count1=0;
int count2=0;
float prior_count2=0;
int count3=0;
float prior_count3=0;
int count4=0;
float prior_count4=0;
int countgas=0;
float prior_countgas=0;
int countwater=0;
float prior_countwater=0;

String payloadpulse = "0";

unsigned long lastTime = 0;
unsigned long timerDelay = 6000;

String guifactor1 = "1000";
String guifactor2 = "1000";
String guifactor3 = "1000";
String guifactor4 = "1000";
String guifactorgas = "1000";
String guifactorwater = "1000";

String counter1 = "1";
String counter2 = "1";
String counter3 = "1";
String counter4 = "1";
String counter5 = "1";
String counter6 = "1";

// function to increment the meters value by 1.
void pulse1() {
  if (counter1.toInt() == 1) {
    count1 = count1 + 1;
  }

  if (counter1.toInt() == 2) {
    count1 = count1 - 1;
  }
}

void pulse2() {
  if (counter2.toInt() == 1) {
    count2 = count2 + 1;
  }

  if (counter2.toInt() == 2) {
    count2 = count2 - 1;
  }
}

void pulse3() {
  if (counter3.toInt() == 1) {
    count3 = count3 + 1;
  }

  if (counter3.toInt() == 2) {
    count3 = count3 - 1;
  }
}

void pulse4() {
  if (counter4.toInt() == 1) {
    count4 = count4 + 1;
  }

  if (counter4.toInt() == 2) {
    count4 = count4 - 1;
  }
}

void pulsegas() {
  if (counter5.toInt() == 1) {
    countgas = countgas + 1;
  }

  if (counter5.toInt() == 2) {
    countgas = countgas - 1;
  }
}

void pulsewater() {
  if (counter6.toInt() == 1) {
    countwater = countwater + 1;
  }

  if (counter6.toInt() == 2) {
    countwater = countwater - 1;
  }
}

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

  wifiManager.autoConnect("ss", "ss");

  pinMode(25, INPUT_PULLDOWN); // Set GPIO25 as digital output pin
  attachInterrupt(digitalPinToInterrupt(25), pulse1, RISING);

  pinMode(19, INPUT_PULLDOWN); // Set GPIO19 as digital output pin
  attachInterrupt(digitalPinToInterrupt(19), pulse2, RISING);

  pinMode(23, INPUT_PULLDOWN); // Set GPIO22 as digital output pin
  attachInterrupt(digitalPinToInterrupt(23), pulse3, RISING);

  pinMode(18, INPUT_PULLDOWN);// Set GPIO18 as digital output pin
  attachInterrupt(digitalPinToInterrupt(18), pulse4, RISING);

  pinMode(21, INPUT_PULLDOWN); // Set GPIO22 as digital output pin
  attachInterrupt(digitalPinToInterrupt(21), pulsegas, RISING);

  pinMode(5, INPUT_PULLDOWN); // Set GPIO5 as digital output pin
  attachInterrupt(digitalPinToInterrupt(5), pulsewater, RISING);
}

//--------------------------------------------------------------------
void loop() {
  float new_count1  = static_cast<float> (count1) / guifactor1.toInt();
  float new_count2 = static_cast<float> (count2) / guifactor2.toInt();
  float new_count3 = static_cast<float> (count3) / guifactor3.toInt();
  float new_count4 = static_cast<float> (count4) / guifactor4.toInt();
  float new_countgas = static_cast<float> (countgas) / guifactorgas.toInt();
  float new_countwater = static_cast<float> (countwater) / guifactorwater.toInt();

  // keeps track of the amount of pulses of pulse meters
  if (new_count1 != prior_count1 ||
   new_count2 != prior_count2 ||
    new_count3 != prior_count3 ||
     new_count4 != prior_count4 ||
      new_countgas != prior_countgas ||
       new_countwater != prior_countwater) {
     Serial.println(new_count1, 4);
     Serial.println(new_count2, 4);
     Serial.println(new_count3, 4);
     Serial.println(new_count4, 4);
     Serial.println(new_countgas, 4);
     Serial.println(new_countwater, 4);
     prior_count1 = new_count1;
     prior_count2 = new_count2;
     prior_count3 = new_count3;
     prior_count4 = new_count4;
     prior_countgas = new_countgas;
     prior_countwater = new_countwater;
  }
  // sends an update to the web
  if ((new_count1 > 0 && ((millis() - lastTime) > timerDelay)) ||
   (new_count2 > 0 && ((millis() - lastTime) > timerDelay)) ||
    (new_count3 > 0 && ((millis() - lastTime) > timerDelay)) ||
     (new_count4 > 0 && ((millis() - lastTime) > timerDelay)) ||
      (new_countgas > 0 && ((millis() - lastTime) > timerDelay)) ||
       (new_countwater > 0 && ((millis() - lastTime) > timerDelay))) {
  {
      // checks if wifi is connected.
      if (WiFi.status()== WL_CONNECTED) {
        HTTPClient http;
        // preparation HTTP GET request.
         String serverPath = serverName + "?chip_id=" + chipId + "&count1=" + new_count1 + "&count2=" + new_count2 + "&count3=" +
         new_count3 + "&count4=" + new_count4 + "&countgas=" + new_countgas + "&countwater=" + new_countwater;
        // Your Domain name with URL path or IP address  with path.
        http.begin(serverPath.c_str());
        // Send HTTP GET request.
        int httpResponseCode = http.GET();
        // confirms the arrival of a response from the server or sends an error.
        if (httpResponseCode>0) {
          count1 = 0;
          count2 = 0;
          count3 = 0;
          count4 = 0;
          countgas = 0;
          countwater = 0;
          payloadpulse = http.getString();
          Serial.println(payloadpulse);
         }
         else {
          Serial.print("Error code: ");
          Serial.println(httpResponseCode);
         }
        // closes the HTTP connection.
        http.end();
      }
      else {
       Serial.println("WiFi Disconnected");
      }
    }
  }

  //reset timer when done sending data
  if (((millis() - lastTime) > timerDelay)) {
    lastTime = millis();
  }
}

The program is a pulse counter which should add 0.001 pulse everytime it detects one. I expect it to send 0.006 to the server, but instead it sends 0.01. How do I make sure it doesn't send rounded data?

It might be rounded by float to String conversion. You might want to use something like: String(someFloat, 3). Also you have to remember there are limits for the floating point numbers, but in this case it should be ok. Implicitly decimal points are 2 places only: String(double, unsigned char decimalPlaces=2);

@KIIV: This should be an answer.

There are too many String objects here, which are heavyweight and unfriendly to the Arduino memory. guifactor1 & co. should be int or float. counter1 & co. should be ints equal to ±1 that you add to the counters: void pulse1() { count1 += increment1; }.

@EdgarBonet this is not my entire code the guifactor for example is a string because i save it to the spiffs

Is this code run on a NodeMCU (or other ESP8266 or ESP32-based board)? If so, you could use the printf function i.e. Serial.printf("%.5f", someFloat); with "5" being the number of digits you need after the decimal point. The printf format is described here.

The constructor for the String object from float is this:
String(double, unsigned char decimalPlaces=2);

So if you don't want to have 2 decimal digits, you have to use String(someFloat, 3).
Also you have to remember there are limits for the floating point numbers, but in this case it shouldn't be the case.
And as Edgar mentioned, String objects are bit dangerous if they are overused, particularly building that serverPath is the worst way how to do it (every single level of it creates new temp object to be copied into next bigger one and released).
It would be cheaper to do it like:
String serverPath;
serverPath.reserve(100); // reserve space so it doesn't have to resize; should be proper estimate
serverPath += serverName;
serverPath += "?chip_id=";  // on AVR it should be F()
serverPath += chipId;
serverPath += "&count1=";
serverPath += new_count1;
serverPath += "&count2=";
serverPath += new_count2;
serverPath += "&count3=";
serverPath += new_count3;
serverPath += "&count4=";
serverPath += new_count4;
serverPath += "&countgas=";
serverPath += new_countgas;
serverPath += "&countwater=";
serverPath += new_countwater;

or you can use some c++ magic:
template <class T> inline String & operator<<(String & out, T const & what) {
    out += what;
    return out;
}

String serverPath;
serverPath.reserve(100); // reserve space so it doesn't have to resize

serverPath << serverName << "?chip_id=" << chipId << "&count1="
           << new_count1 << "&count2=" << new_count2 << "&count3="
           << new_count3 << "&count4=" << new_count4 << "&countgas="
           << new_countgas << "&countwater=" << new_countwater;

this code takes serverPath << serverName adds serverName into serverPath and the result is serverPath again, and then it continues as serverPath << "?chip_id=" and so on

thank you it works with String(someFloat, 3)


text:
No text in the IDE menu items
I installed arduino 1.8.19 (64-bit) on a Fedora Linux 35 Workstation Edition system. When I started the IDE, and selected the "Open" menu icon, the menu item list appeared, but there was no text displayed with the items. I could open sub-menu items, but there was still no text. It looked like:

I tried several other 1.8.x versions, but with the same result. I haven't found any discussion about this on the Web. so I suspect that it is problem with my configuration. Nevertheless, any suggestions will be most welcome. I have not tried to install the IDE on Windows 10, but that is an option.

wow, that is frustrating ... what is your specific question?

You may want to run it from a terminal and check the output there for clues that you may then want to add to the question.

My specific question is, "What can I do to be able to see the menu items?"
I installed the IDE on Windows 10 and it runs as expected.

Starting the IDE from the command line gives an error, but I don't what it implies nor how to eliminate it.
Gtk-Message: 01:05:10.314: Failed to load module "pk-gtk-module"

google pk-gtk-module

Thanks, jsotola. So far a Google search has turned up 3 suggestions. Sadly, none of them have helped.

Install PackageKit-gtk3-module. dnf responds that it already is installed
Create a new gtk2.cnf that points to /usr/lib64/gtk-2.0/modules. Didn't resolve it.
Extract the missing library from a Fedora 16 system (in the archives) and move it to the "modules" directory.

The 3rd suggestion resolved the missing library, but, alas, did not resolve this issue of no text being displayed. So I am still hoping for suggestions.

There is a incompatibility between Arduino 1.8.19 and Fedora 35. On another PC, where I was running an older version of Arduino, I upgraded to Fedora 36 and the upgrade warned me of the incompatibility with the older Arduino and Fedora 36 and said it was deleting Arduino. After the Fedora upgrade completed, I installed Arduino 1.8.19 and it worked as expected. When I upgraded the original PC, the one with the no text in the menus, to Fedora 36, the menus also worked as expected. Hallelujah!! So, all is well and I have my answer. Thanks for your replies.


text:
Will the atmega8-U2 work with Arduino IDE
I use a homemade board that hosts a PIC16F1829 and an ATmega328P on the same board.  We use the ATmega328P with the Arduino IDE and the PIC with the MPLABX IDE for about 100 EE students a semester at UTSA.  I have 100 pic chips but no ATmega328P chips, I can re-spin the board and adapt it to the ATmega8-U2, since right now I can by 250 ATmega8-U2 chips that are in stock but there are no ATmega328P chips available anywhere and I need 100 at least. I am currently using a different UART to TTL adapter, the CP2102 to connect the ATmega328P to the Arduino IDE.  I have the 2 chips talk via a shared I2C line. How difficult will it be to use the Arduino IDE with the ATmega8-U2?  (Again, not as the UART to USB interface but as the main processor.  Thanks,

ATMega8 can be supported and used as an Arduino, all you need is to add the MCUDude's MiniCore to the IDE instead of using the default Arduino S.A.'s arduinocore-avr.

I never tried, but it seems to me it should work without issues.
In the Arduino IDE, Menu Tools → Board, you can select “Arduino NG or
older”. You then have a menu Tools → Processor where you can select
either “ATmega168” or “ATmega8”. These options don't require you to
install any extra board support package: they come with the default
“classic” AVR core, which does support the ATmega8.


text:
Servo retaining its position every time I send some value
I wanted to control my servo with a Bluetooth module.
I gave certain values for rotating it. When I press those values the servo rotates, but then retains its original position and the PC also makes the sound of the Arduino board disconnecting because I powered the board with my PC (tried with powerbank also). Even my Bluetooth disconnects.
This is my code:
#include <Servo.h>

Servo myservo;
int pos = 0;
char data = 0;

void setup() {
  myservo.attach(9);
  Serial.begin(9600);
}

void loop() {
  if (Serial.available() > 0) {
    data = Serial.read();
    if (data == 'F') {
      // for (pos = 0; pos <= 180; pos += 1)
      myservo.write(180);
      delay(1);
    }
  }
  else if (data == 'B') {
    // for (pos = 180; pos >= 0; pos -= 1)
    myservo.write(0);
    delay(1);
  }
}

Connections:
Servo:
red wire -- 5 V (not working at 3.3 V)
orange wire -- pin9
brown wire -- gnd

Bluetooth (hc05):
5 V -- 5 V
gnd -- gnd
rx -- tx
tx -- rx

I fixed your indentation. You are missing 2 closing curly brackets at the end. Also your for loop for the character F is not doing anything except waiting (you are not writing to the servo there). If your USB connection fails when the servo moves that can indicate a power issue. What type of servo do you have exactly? Have you tried powering the servo seperately from a more capable power source?

There's no servo positioning line for when 'F' is pressed (myservo.write), I'm guessing that's an accidental omission in the code you posted. Your description of the symptoms indicates the arduino board is resetting, presumably a power issue. A full circuit diagram would help diagnose your issue.

@chrisl i powerd it with a charger but still dosent work.

How exactly did you power it with a charger? Through the USB port of the Arduino? Depending on the power draw of the servo you might overload the diode in there. Please try powering the servo directly from the charger (not through the Arduino). And tell us what kind of servo you have

i have 9g servo

your code should never contain }}, unless you are an expert programmer ... always position } at the correct indentation level for each block that they delimit ... prepare yourself for a world of hurt if you do not learn to format your code properly

I tried changing the USB B cable with a better quality one and it worked.

It is OK to answer your own question. Now, please, mark it for future visitors with a similar problem.


text:
Efficient way to save accelerometer data on sd card
I have analog accelerometer that transfer acceleration on 3 axis with frequency 5 kHz. I want to store that data in SD card for in txt file. My sketch is the following:
void loop()
{

  // Get raw accelerometer data for each axis
  int rawX = analogRead(A0);
  int rawY = analogRead(A1);
  int rawZ = analogRead(A2);

  // Scale accelerometer ADC readings into common units
  // Scale map depends on if using a 5V or 3.3V microcontroller
  float scaledX, scaledY, scaledZ; // Scaled values for each axis
  if (micro_is_5V) // Microcontroller runs off 5V
  {

    scaledX = mapf(rawX, 0, 1023, -scale, scale); // 3.3/5 * 1023 =~ 675
    scaledY = mapf(rawY, 0, 1023, -scale, scale);
    scaledZ = mapf(rawZ, 0, 1023, -scale, scale);

  }
  else // Microcontroller runs off 3.3V
  {
    scaledX = mapf(rawX, 0, 675, -scale, scale);
    scaledY = mapf(rawY, 0, 675, -scale, scale);
    scaledZ = mapf(rawZ, 0, 675, -scale, scale);
  }

   String dataString = "";
   // Concatenate string
   dataString += String(scaledX);
   dataString += "\t\t";
   dataString += String(scaledY);
   dataString += "\t\t";
   dataString += String(scaledZ);
   dataString += "\t\t";
   saveSD();
}

// Same functionality as Arduino's standard map function, except using floats
float mapf(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void saveSD()
{
  // create file for writing
  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  // if file is available
  if (dataFile) {
    // save the data
    dataFile.println(dataString);
    // close file
    dataFile.close();
  } else {
    // if file is unavailable
    Serial.println("Error opening datalog.txt");
  }
}

So in loop I open file, write to it and after that close it. When my file will be big enough there will be bottle neck.It will take a lot of time to read and write file.
How to deal with saving data to files on SD card?
UPD:
I measured the time of executing code like that:
  ...
  start_open_t=micros(); // time in milli seconds
  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  delta_open_t=micros() - start_open_t ;
  // if file is available for writing
  if (dataFile) {
    // save the data
    start_write_t=micros(); // time in milli seconds
    dataFile.println(dataString);
    delta_write_t=micros() - start_write_t ;
    // close the file
    start_close_t=micros(); // time in milli seconds
    dataFile.close();
    delta_close_t=micros() - start_close_t ;
    ...

And there is the result:
Open time:
7656
Write time:
2176
Close time:
8076

The open time is increasing there is no surprise (with increasing the file size).
Write to file and close time is almost constant.
I thought to open file in setup() and initialize timer. Write to file in loop() and after some time interval to close the file, after that open new file and so on. But as can be seen the print operation dataFile.println(dataString); takes approximately 2 ms that is 500 Hz, and it is too slow. I need to register with 5 kHz.
If I print in serial the data is printed much faster but I can not  connect to usb because arduino is located to far (approx 30 meters).
May be there is the way to connect to serial with wifi or bluetooth or may be there are another methods to store the data fast?

I thought about offering this as a potential duplicate, but I didn't feel that strongly about it, and you got some good advice (not mentioned there) below that I'm going to vote up. Still, you may find it an interesting read.

Thanks for advice, I'll read

You'd edited to include the line: "May be there is the way ... serial with wifi or bluetooth or ... another methods to store the data fast?" It's a valid question (or at least a kernel) but it is a different question that's been shoehorned in there. And that's been done after the original question had already been given a thoughtful answer. IMO, if you want to ask something like that, remove it from this question and start a new one. You'd need to be careful that you're asking something that can be factually answered and not something that is only a matter of opinion.

I can see it is safe to open/close the file every time, especially closing, as if the Arduino loses power, the entire file can be corrupted possibly.
However, I can find of some 'solutions':

Backup battery

Open the file in setup(), and only close the file when the backup battery becomes active (instead of closing the file after every write). This will however need an external battery, and some implementation to check if it is active. Also, during the external battery is active, no data should be written.

Using multiple files

More easier is to use multiple files, and write each time period (less than the  size of the file that cause problems) in a separate file. You can either close the file after each write, or when starting a new period, meaning when the Arduino loses power, you only lose the last time period.

Using binary format

This can be used in combination with solution 1 and 2, and is to not write the files as text files but in binary format, reducing the size considerably.

Thanks for replying. About battery, for now I'm gonna to use crone battery as main power for arduino because is located away from electrical power. About second your suggestion I thought about it, so I need to measure time of loop and time of opening file with different file sizes and find the max size that it can open not to be too slow to catch data from acceleromerter. And your third suggestion is great I should try it!

If your file doesn't need to be humanly readable, that is the easiest solution. I think it can save a factor 4 , and maybe more if you use interpunction and spaces.

Thanks, I can decode the file after that. I have an update, I measured the time of open, write and close operation and it seems that it not the best way to store logs on sd. See updates

Use binary format, that will reduce the write time.


text:
Library fails to compile
I want to try out this library:
https://github.com/connornishijima/arduino-volume3
I downloaded the zip file from github, renamed it, and included it as a library in the IDE.
So run one of the examples, A4_440HZ
This is its code:
#include "Volume3.h"
#define speakerPin 9

uint16_t frequency = 440;

void setup() {
  // Nothing neeeded here!
}

void loop() {
  for(uint16_t volume = 0; volume < 1023; volume++){
    vol.tone(speakerPin,frequency,volume);
    delay(1);
  }
  for(uint16_t volume = 1023; volume > 0; volume--){
    vol.tone(speakerPin,frequency,volume);
    delay(1);
  }
}

And i get this error:
Error Compiling
A4_440Hz.cpp.o: In function `loop':
/usr/share/arduino/A4_440Hz.ino:12: undefined reference to `vol'
/usr/share/arduino/A4_440Hz.ino:12: undefined reference to `vol'
/usr/share/arduino/A4_440Hz.ino:16: undefined reference to `vol'
/usr/share/arduino/A4_440Hz.ino:16: undefined reference to `vol'
collect2: error: ld returned 1 exit status

I have no idea what is to blame, or how to mitigate it.
This is the first time that an included example from a library does not play out of the box.

It compiles here. What IDE version are you running?

You could have just installed the library from the library manager in the Arduino IDE.

They are using extern Volume vol; in header file, but there is no definition in cpp, nor in the sketch. The Volume vol; will be needed in your code, I suppose

The second part of that library, the TimerOne uses the same pattern, but it has both the declaration in header file and the definition in cpp file line 41 TimerOne.cpp

@timemage It is 2:1.0.5. It does not have a library manager. Perhaps it is an old version? But i installed it recently. I am using Ubuntu Linux.

@user1584421 Very old and a common problem. In case you're wondering, the 2: is not part of the IDE version. That is part of a Debian style package versioning scheme. What you're looking at is IDE version 1.0.5 from 2013. Debian and Ubuntu could do everyone a favour by removing these packages, but they don't. Unpack (optionally install) from the tarball instead.

This is kind of a weird situation. The library declares the object
vol, but fails to define it. On the ancient version of the Arduino IDE
you are using, compilation fails, understandably, because vol has
never been defined. What is weird is that, on a more recent version
(1.8.15 on Ubuntu here), compilation succeeds.
It is worth noting that vol belongs to the class Volume, which is an
empty class. As such, it only plays the role of a namespace for the
functions vol.tone() and vol.noTone(). Strictly speaking, as vol
has no data (its size is zero), the compiler should never need to access
it. My guess is that the newer Arduino manages to compile this only
because it uses different optimization settings than the ancient 1.0.5.
Anyhow, you have two options:

upgrade your installation of the Arduino IDE

declare Volume vol; near the top of the sketch.

Edit: I did some tests and it appears that, as I suspected, this is
related to link-time optimization (LTO). Since version 1.5.7, the
Arduino IDE enables LTO, and when this is the case, the linker doesn't
complain about missing empty objects.
The library could be fixed by defining vol in Volume3.cpp, although
this would create a weird empty object in the BSS. Another option would
be to declare both methods as static within Volume3.h. This would make
the compiler know it doesn't actually need to reference the vol object
when one of its methods is called.
Would you submit a pull request with one of those fixes?

Thank you! I tried both! The library compiles but no sound is heard. I guess it is an old library.

Same regarding optimizer. To be clear, the code was always incorrect. It is only a question of whether the problem manifests from that.

So if i do your suggestions, will the lib work? Did you manage to make it run? BTW, the last sentence is this targeted to me?

@user1584421: It should work, although I tested only on example code with my host compiler. And yes, the last sentence was a suggestion for you.

Thank you. But inside Volume3.cpp i defined Volume vol;. I then used one of the examples.The library compiled/uploaded but nothing is heard from the speakers.


text:
Mildly accurate oscilloscope using Arduino Uno R3
I'm trying to make a mildly accurate oscilloscope using Arduino Uno R3 and I've done some research on the best method to do so. First of all I need to measure the voltage with a rather high sampling rate and then I'm going to transfer my data through the serial port and plot the data using Python or Matlab.
According to what I have read the analogread() function will cause some delay and therefore some inaccuracies and thus it is not suitable for my purpose.
I found on this website some good info about how I should write my code, but I have some questions:

I want my reference voltage to be 1.1 V so that by dividing it to 1023 parts I will have an accuracy of about 1 mV. How should I edit the mentioned code in order to do so?

The code in the void loop() setup is of no use to me (I prefer not to save the measured data on the Arduino and then send to my PC because of memory limitations). After deleting it will the data still be sent to the serial port?

Will sending the data through the serial port affect my sample rate/accuracy? I mean how does it effect my accuracy?

P.S: by mildly accurate this is what I mean: I want to measure voltage accurately with 1 mV precision for frequencies of max. 500 kHz (a bit less or more won't hurt).

That’s an interesting question, even if only to define the limits of “mildly accurate” imposed by the Uno platform. You may need to break your coding down a piece at a time, asking all three questions at once may constrain the answers you receive. I think the analogReference() function may assist with the first question. https://www.arduino.cc/reference/en/language/functions/analog-io/analogreference/

@rowanp thanks for the help with analogreference. I will edit the question for better defining mildly accurate.

When ever hardware is pushed to its limits I find one needs to be very familiar with both the hardware and software.  Just for starters, consider Python is 100s if not over 1000 times slower then, say, compiled C.  I say this even though it sounds like you are running Python on other than an Arduino.  At the other end of the spectrum, even though the ADC has 10 bits this does not necessarily mean you can get 1024 steps of resolution for any single sample.  Noise will likely reduce this considerably.

@st2000 I understand that Python is much slower than C. So will using Matlab as the data analyzer on the other end give better results? since it is C-based or should I just test that?

You won't get anywhere near 500 kS/s (kilosamples per second) with an Uno. The ADC accuracy degrades as you speed up its clock, and it becomes essentially garbage past 1 MHz (which gives 76.9 kS/s). See ADC conversion on the Arduino, by Nick Gammon.

@EdgarBonet after what you said I did some searching about the Nyquist criterium and found out that if we dont want to use sample rates higher than 76.9kS/s the highest frequency we can measure is about 38 khz. am I right?

I don't think any of us want to discourage you @infinite.  It might be better to go into this thinking you might not make it to your target goals.  And if you have fun doing it, all the better.  Also, once you get some experience with your Uno R3, consider stepping up your game with a more advanced / faster processor. The Arudino development IDE has been ported to many many different processors / boards.

@st2000 guess you are right! but so far I've learned a lot about signals and how ADC works and all that stuff so for better learning I'm trying to do this project the best way I can.

I want my reference voltatge to be 1.1v so that by dividing it to
1023 parts I will have the accuracy of about 1mv.

You will have a resolution of about 1 mV. The accuracy will be
significantly worse than that due to the imperfections of the ADC
(offset error, gain error, non-linearity) and noise.

how should I edit the mentioned code in order to do so?

The reference is configured by the bits REFS0 and REFS1 of the
ADMUX register. The internal 1.1 V reference is selected by
setting both bits, as shown in table 24-3 of the
datasheet. You can then patch the original code like this:
@@ -8,7 +8,7 @@
   ADCSRA = 0;             // clear ADCSRA register
   ADCSRB = 0;             // clear ADCSRB register
   ADMUX |= (0 & 0x07);    // set A0 analog input pin
-  ADMUX |= (1 << REFS0);  // set reference voltage
+  ADMUX |= (1 << REFS0) | (1 << REFS1);  // set reference voltage
   ADMUX |= (1 << ADLAR);  // left align ADC value to 8 bits from ADCH register

   // sampling rate is [ADC clock] / [prescaler] / [conversion clock cycles]

the code in the void loop() setup is of no use for me (I prefer not
to save the measured data on the arduino and then send to my pc
because of memory limitations). after deleting it will the data still
be sent to the serial port?

In the linked code, loop() is the only function sending anything to
the serial port. If you remove it, nothing will be sent. You could
Serial.write() in the ISR though, in which case an empty loop()
would be fine.
Note that writing to Serial from within an ISR is generally
discouraged. Your situation though (an oscilloscope code) is one of the
very few cases where it does make sense to do so.

will sending the data through the serial port affect my sample
rate/accuracy?

It can certainly affect your sampling rate. Serial.write() is usually
non-blocking, as all it does is write the data to the RAM-based transmit
buffer. If the buffer fills up, however, Serial.write() will block
waiting for the serial port to actually send the data, and make enough
room in the buffer.
This means that, in order for the oscilloscope to not miss samples, you
have to make sure that the serial port can send the data at least as
fast as the ADC is acquiring it.
Example calculation: If you clock the ADC at 1 MHz, you get one
sample every 13 µs. You can follow the example given in the code
you linked to, and discard the last two bits in order to transmit only
8 bits of the sample. Transmitting those in plain binary will take
10 “bits” worth of the serial port bandwidth (one start bit,
8 data bits and one stop bit). Each bit should then take less than
1.3 µs, which translates to a baud rate of 769,231 bits per
second. You will probably have no other choice than configuring the
serial port for 1 Mb/s.
If you want to transmit the whole 10 bits of the ADC readings, you
will have to lower the sampling rate by a factor two.
At this point you may notice that the serial port, rather than the ADC,
is the bottleneck for the performance of your oscilloscope. If this is
too limiting, you may consider building a scope that works by bursts: it
stores a burst of samples in memory, then sends it at a leisurely rate
through the serial port.

You might want to consider using a Teensy 3.x or Teensy 4.x instead of an Arduino R3.  Teensy 4.1 has a CPU speed of 600MHz vs R3 of 16MHz.  Both use Arduino, and both are in the same price range


text:
Does an 5V 2.1 A will fit for this Led Schema?
Hello I would like to create an Arduino protoype with Led WS2182B.
I currently have
Arduino NANO (not UNO, like in this schema)
65 Led WS2182B = Which gives me 3.9 Amp of suply for full brighness (65*60mAmp)
Power supply of a movil charge wich have 5V 2.1 A
I am currently working with this schema from this website

I have a few questions

Does this battery will work for this schema replacing the usb conector?
Can I use the 68 leds at a medium energy, to make it suitable wih the power supply? Can this damage any device (Because in theory I believe it needs more than 2.1 Amps)
3)If this battery will not be appropiate to this schema. What could I do?

Thank you very much!

Are you using a battery or a wallwart power suppy? What exactly are you using? 2. When you already calculated that you need 4.68A and your supply gives you up to 2.1A, does this sound like it would fit?

@chrisl hello Chris, I am using an portable battery for smarthphone. The amount of Ampers used is at the maximun capacity, my doubt is if I can use at a medium capacity or so

Do you mean a standard USB power bank? You can get max 2.1A/3.9A =  53,8% intensity. Though you should go considerably lower. With your current supply you should always plan with some headroom, like 50% more than you need (especially since power supplies of all kind can get rather inefficient near their maximum rating)

@chrisl yes, indeed a USB power bank, thank you Chris, I think that I get the point, you reccomend me that I use those leds lets say into a 25% of the intensity so it will peak at the full capacity, right? Do you know what I can use to replace this power bank, or from an existing tutorial to work in this type of cases (a portable device which lighlty exceed the capacity of an USB power bank)?

You are using a standard USB power bank. It should be possible to power your project as long as you stay below the current limit (2.1A). Probably you should keep the intensity small enough to not exceed 1.9A in normal operation. That should be enough for about half intensity. You really don't want to exceed the current limit. And you should measure the actual current draw and then approach your own current limit (like 1.9A) from below. Calculations are good, but when operating like this you should look at the real values.
If you exceed the current limit of the power bank it depends on the implementation of the power bank what will happen. Most likely the power bank will cut the power but still work. Though it is also possible, that you fry some electronics inside the power bank and kill it this way.
Note:

While you experiment with your code you can use fewer LEDs, so that they would be able to light up at full intensity. That makes sure, that you don't damage anything from a small programming error. If you write your code in the correct way (for example defining the number of LEDs at exactly one code line and reusing that name everywhere), then it will be easy to increase the number of LEDs to the target and also be sure, that you are staying within your limits.
You already have it in your wiring diagram, but nonetheless I want to emphasize, that you must not power the LEDs through the Arduino. You need to connect them directly to the USB cable to the power bank. The Arduino cannot withstand such currents.
USB power banks often cut power, when not enough current is being drawn from them (and for mine the current of an Arduino Nano wasn't enough to hold it active). If in your project the LEDs get turned of at some time, while the Arduino should keep running, the power bank might cut the power, thus turning off the Arduino. In my experience the bigger, more expensive power banks will do that, while small, cheap ones will just keep outputting the power. If this scenario is relevant for you, you need to test this yourself with your specific power bank.

If this battery will not be appropiate to this schema. What could I do?

You could use multiple of these power banks, each of them powering its own part of the LED strip. One of them can also power the Arduino. Just make sure to connect all grounds together.

Thank you, Chris!


text:
Can I make an Arduino Uno Rev3 pretend to be a joystick?
I want to create a joystick for my flight simulator and I need to make an Arduino Uno Rev3 pretend to be a joystick when I plug it to my computer.

The Uno doesn't have native USB capabilities. It uses an additional microcontroller (the Atmega16u2) as an USB to Serial adapter. In the default configuration this microcontroller is only programmed for providing a serial interface over USB, not a joystick interface. You can hack your Uno and reprogram the Atmega16u2 for providing a joystick interface (and there are tutorials for how to reprogram the Atmega16u2 online). (Note, that you need a genuine Arduino for this to work, since the cheap clones often only have CH430 chips as USB to Serial adapter)
But I would suggest going the easier way and buying an Arduino board, which itself has USB capabilities without the need of hacking the board, like the Arduino Micro. Then you can simply use one of the joystick libraries on it. This way will be a lot easier for a beginner than doing it with an Uno.


text:
Teensy 4.1 / 4.0 When to use FlexPWM vs QuadTimer pins to strobe LEDs
I want to strobe 3 LEDs (at independent frequencies and duty cycles) via mosfets with a duty cycle of 0.05%-1% at a frequency range of 24-100 hz. I would like to hold 1% or better accuracy for both duty cycle and frequency.
The Teensy 4.x seems perfect with its amazing PWM frequency and resolution controls, and generous number of independent PWM timers.

For the purposes of my application, should I use pins with FlexPWM or QuadTimer? Does it matter?
I see that the numbering convention is X.Y, is there any functional significance when X numbers are in common (IE FlexPWM 1.0 and FLexPWM 1.1)?

See "Frequency" section of this page

I had cross-posted, and Paul Stoffregen answered in the Teensy Forum.
Pasting Paul's great answer here for posterity:

1: Really doesn't matter for 0.05% accuracy.
2:See "PWM Frequency" on this page.
The 3 pins identified as "FlexPWM1.0" (1, 44, 45) will always run at
the same frequency. If you want different PWM frequency, you would
need to choose pins from different groups.
More detail on how the hardware actually works can be found in the
reference manual. But usually that ends of being far too much
information. The timers are packed with a mind boggling number of
advanced features, which makes a steep learning curve if you want to
dive into how the hardware really works.
Most applications work fine by simply using analogWrite,
analogWriteResolution and analogWriteFrequency. Everything you've said
sounds like a pretty simple application that can be done easily with
these 3 functions. You're only looking for 9 bit resolution from
hardware than is natively 15 or 16 bits. Just use the easy functions
do the low-level work for you.


text:
Uploading sketch to multiple Arduinos connected in series
I'm currently working on a project where you essentially will have multiple Arduinos (1 Uno, multiple Nanos) daisy-chained, only connected through 2 digital pins and one wire for Serial communication (RX Pin -> TX Pin). (The first one is connected via USB to the PC.)
I figured the serial communication between the first Arduino and PC would also be forwarded through the RX and TX pins, but that doesn't seem to be the case.
As it's fairly tedious to update one at a time, is there a way of updating all of them at once, using only the one-way serial communication wire?
EDIT: Yeh so like imma just add a USB Port to every single component to the chain to update separately, and update every single one of them separately.

Serial communication between the first arduino and PC would also be forwarded through the RX and TX pins ... that would happen only if the bootloader sends back what it receives from avrdude ... you could modify the bootloader to do that ... I think that the avrdude expects some handshaking though

Might be better off making a program to feed nanos instead of a modified bootloader

Try connecting only the RX and reset pins. Serial programming is done by the bootloader, but it needs to be switched into programming mode first, which is done by resetting the chip and then sending a special code to the RX pin within a certain time period. When you program through the serial port (as you are doing with the Uno) the FTDI chip drives this pin for you, but you'll need to cascade that reset signal through to the other chips as well. This still isn't guarenteed to work 100%, because it depends on a number of other factors as well, but at least you'll have a chance.
When I've done stuff like this commercially I've programmed via the ICSP connector instead and made programming rigs out of spring-loaded pin connectors that the target boards simply clip onto. If you're planning on doing this with any degree of frequency then I'd recommend investing a bit of time into doing this yourself.
UPDATE: ok, I can see now why this isn't working. The Nano's CH340 usb-to-serial chip is pulling RX low, preventing the data stream from being read. Would work fine with standalone chips, obviously doesn't on the Nano.
I think your best option is to use ICSP. It's an extra pin, but if you breadboard then it shouldn't make any difference. Plus there are a number of advantages to doing so, including faster programming, the ability to upload/replace the bootloader and the ability to change fuses (e.g. to protect your firmware or disable the bootloader altogether to give you app more Flash space etc).
If you don't already know how to do this then the layout is:

Connect Uno SCLK(D13)/MOSI(D11)/GND pins to all the corresponding Nano pins.
Connect Uno D10 to all the Nano's RESET pins.
Connect Uno MISO(D12) to only the first Nano's MISO pin.
Connect Uno VIN to all the Nano VINs (you don't want all the Nanos being driven from the Uno's regulator)

Should wind up looking something like this:

Prepare the Uno for programming:

Set your IDE board type to Uno
Set IDE programmer type to "AVR ISP"
Upload IDE ArduinoISP sketch to the Uno

And now you're ready to program the Nanos:

Set your IDE board type to Nano
Set IDE programmer type to "Arduino as ISP"
Upload your Nano sketch using "Upload Using Programmer"

Just tried it now with the two Nanos in the photo, worked fine.

What I've also heard so far is, that avrdude also expects handshakes/responses from the programmed board, and if the serial is simply forwarded, out of sync aka timing issues are likely to occur while uploading, but I'll definitely try this later!

@Mikoyan yes, that's true, although I would expect the pauses in between programming chunks to be long enough to accommodate that. But if it doesn't work then writing your own uploader is extremely easy, the Flash function in Device.cs in my Windows Arduino emulator has all the code to do this, and you could just add additional delays as needed.

Connecting only the RX and Reset pins does not work, it appears like the Reset pin is not actually (un)firing (although it might've just been too fast to notice, still: no program on the nano) :/

@Mikoyan gimme a day or so to try it out, I'll reply here with an answer if I can get it working myself.

@Mikoyan answer updated.

As only one Nano has its MISO connected, the programmer can't get feedback from all the others. I wouldn't have dared such a setup, but it's really cool that it works! Note though that, in the “verify” phase of the upload, only the first Nano is effectively verified.

I kinda feel dumb at this point: avrdude: Yikes!  Invalid device signature., I did just as you said buuut yea, it spits this error. I only used one nano to try this, but I don't think that matters.

@Mikoyan first thing to do then is check the command being sent to avrdude. If you're doing it through the IDE then enable verbose output during upload in preferences and see what command it dumps out when you program, should be something like C:\arduino-1.8.19-windows\arduino-1.8.19\hardware\tools\avr/bin/avrdude -CC:\arduino-1.8.19-windows\arduino-1.8.19\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -cstk500v1 -PCOM9 -Uflash:w:C:\Users\your_user_name\AppData\Local\Temp\arduino_build_213021/your_sketch.ino.hex:i

If that checks out then it's probably just a wiring issue. Start by replacing that VIN connection with a connection to their 5V pins (fine if it's just one board) and wire directly to the Arduino pins (as shown in this image) to rule out any problem with its ICSP header.

There is a two-way protocol used by the bootloader which I describe here.
You could conceivably connect all the Rx wires together, and use the Tx wire from the first one (so it responds appropriately), and discard the responses from the other units. If they program at exactly the same rate, and reset at exactly the same moment, that might work.
You might be better off just uploading using a device designed to do that, as I describe on my forum. The Atmega328P programmed using that method can be reprogrammed in about one second (so the time to hook up the wires is the long part). Using the ICSP interface on the chips, and a suitable plug, could make that very quick, and easy.
There are also stand-alone devices, for example the Crossroads standalone programmer which uses the techniques described in my forum post. You can use that in the field because it doesn't require a monitor or PC. You just hook it up via the ICSP port, select what file you want to upload, and hit the "program" button.

"You could conceivably connect all the Rx wires together" -
Actually no, as discussed in another reply, connecting just the RX pins (and reset to bring it into programming mode) does not work as:
"The Nano's CH340 usb-to-serial chip is pulling RX low, preventing the data stream from being read. Would work fine with standalone chips, obviously doesn't on the Nano"

Hmm, OK. You could make up your own boards without a USB to serial chip, since that doesn't seem required in this setup. Or just desolder it from the boards.


text:
How to display only specific data in the serial monitoring?
I got the following data as shown in the figure from imu razor which is connected to Arduino Mega 2560 in the serial monitoring and I want to get only the data that starts with "#A-R= "
Can any one provide me with code to do this?

This is my code:
#define BUFF_SIZE 40
char buffer[BUFF_SIZE];
String header ;
char Bufferheader[4] ;

void setup(){
Serial.begin(57600);
Serial2.begin(57600);
Serial2.write("#osct");
}

void loop() {

int i = 0;
while(Serial2.available()) {
buffer[i++] = Serial2.read();
if(i == BUFF_SIZE) break;
}

for(int j = 0; j < i; j++) {
Serial.print(buffer[j]);

}
}

Change your code so that it only prints the things you want it to print?

Or stop the serial monitor and type grep '#A-R=' /dev/ttyACM0

The method outlined by Majenko is the general way of dealing with this
kind of requirement, and also probably the “cleanest” way. If, however,
you are confident that the incoming data always follows the pattern you
are showing, then you can “cheat” and cut some corners.
Consider this: in the sample you show, the character 'A' only ever
appears as the second character in a line, and always as part of the
sequence "#A-R=". If you are confident that this is always the case,
then you can apply the following algorithm:

the program processes one input character at a time, and decides
whether to print it to its output or not
it has two possible states: either it is printing every character it
reads (because it believes the character belongs to a “#A-R” line), or
it is not
if it is printing and it reads an end of line, it prints that end of
line, and then stops printing
if it is not printing and it reads an 'A', it outputs "#A", then
starts printing all its input.

In code:
void loop() {
    static bool printing = false;  // are we printing what we read?
    if (Serial2.available()) {
        char c = Serial2.read();
        if (printing) {
            Serial.write(c);
            if (c == '\n')  // on end of line, stop printing
                printing = false;
        } else if (c == 'A') {  // on 'A', start printing
            Serial.print("#A");
            printing = true;
        }
    }
}

This code assumes your device uses ASCII LF ('\n') as end-of-line
indicator. You will have to replace '\n' by '\r' if it uses ASCII CR
instead.

Your code is doing literally nothing except reading from one serial port and passing it to another.
You need to throw away pretty much all that code and do some actual processing of the data.
You need to:

Read the incoming data a line at a time (that is, read everything up to the line ending into a buffer)
Examine the start of that buffer
Output whatever data from the buffer your examinations deem appropriate.

I can't go into detail here about how to do it, but there are tutorials covering all those topics available on the web. For the serial reading I have a tutorial that you may find helpful.


text:
Detect where touch happened on a big capacitive electrode
I have a big-ish electrode (10cm x 10cm) that works fine for detecting touch over the whole electrode (as a boolean - simple touch vs. release) but I was wondering if there was a way to detect where on the electrode there was a touch, using filtered data or something? I saw this link where the person made a capacitive touch grid. All their copper tape rows/columns are touching. When I try to connect multiple clips to a single electrode though (more-or-less what they did) my MPR121 becomes unresponsive.
I'm using an Arduino Uno, a Sparkfun MPR121 capsense breakout, and this library for interacting with the MPR121.
Here's a basic program I have running at the moment just to check out an average of filtered data readings to see if there's a pattern. There isn't. The readings are anywhere between 250 and 580 no matter where the electrode is touched.
#include <MPR121.h>
#include "Wire.h"

int readingSum = 0;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  MPR121.begin(0x5A);
  MPR121.setInterruptPin(2);

  MPR121.setTouchThreshold(50);
  MPR121.setReleaseThreshold(40);

  delay(1000);
}

void loop() {
  if (MPR121.touchStatusChanged()) {
    MPR121.updateAll();
    if (MPR121.isNewTouch(0)) {
      for (uint8_t i = 0; i < 8; i++) {
          readingSum += MPR121.getFilteredData(0);
      }
      Serial.println(readingSum / 8);
    }
    readingSum = 0;
  }
}

no, there is not

As @jsotola mentioned in the comments, no I don’t think there is a way to take a single electrode and turn it into a touchpad. Touchpads rely on a grid of addressable capacitance points to resolve a location.
I didn’t spend a lot of time investigating the link you referenced. However I wonder if you allowed for the adhesive backing on the copper tape when you attempted to replicate the example. It looks to me to be rows and columns of copper conductor separated by a thin layer of adhesive. Not the same thing as one big conductor.