text:
Negative currentmA and Shuntvoltage
Why is my INA219 current sensor gives a negative currentmA and Shunt voltage?  My sensor is connected in a glucose test strip connector. The current is from a glucose biosensor? Is it possible that my INA219 is damaged?

Did you connect it the wrong way around? Does the glucose strip maybe produce a voltage?

I connect it according to the schematic. The glucose test strip produce current

Could you show us the schematic? You haven't given us a lot of information to go on.

make sure the ground path is low-impedance between the MCU, the INA, and the sensor.

The "sign" of the INA219 shows the direction of flow of the current. Current isn't either "positive" or "negative", it has a direction. The sign is just used to represent that direction.
It's like a car. It has a speed. That speed could be in the forward direction, or the reverse direction.  It could be going 5 miles per hour forwards, or 5 miles per hour backwards. Either way, it's 5 miles per hour. However the backwards direction could be represented as "minus 5 miles per hour". It doesn't mean that you're doing a negative speed (there is no such thing), but that your speed is in a "negative direction".
This "speed" and "direction" are combined together to create "velocity", which is "speed relative to some arbitrarily chosen 'normal' direction and speed".
At this point the "velocity" can be represented as a 2D vector, with forward velocity in the + direction, and reverse velocity in the - direction.
But that's all a bit of a digression. All it means is that the "-" is meaningless if you don't care about the direction of current flow. If all you care about is the quantity of current you can discard the "-" completely.  The simplest way is:
current = abs(current);

Last month I measure the led with a 9 volts battery and the output is the same as I expected but when I tried it this week it gives negative values

Were the values (about) the same, but negative?

No.  It changed values and become negative

Did you calibrate it correctly?


text:
"SSD1306 allocation failed" when #include SD.h
I'm using the ssd1306_128x64_i2c example file from the 1306's library.
It works perfectly until I add the #include SD.h line, after which it gives the allocation failed error.
Please advise.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SD.h>

Adafruit_SSD1306 display(128, 64, &Wire, 4);

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

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
  }

  display.clearDisplay();
  display.display();
  testdrawchar();
}

void loop() {
}

void testdrawchar(void) {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.cp437(true);

  for(int16_t i=0; i<256; i++) {
    if(i == '\n') display.write(' ');
    else          display.write(i);
  }
  display.display();
}

I had this exact same problem and was glad to see someone had already asked this question.  It is quite shocking that you cannot use SD.h and the adafruit oled library at the same time.

I was able to make it all fit by using the text-only library for the OLED.
SSD1306Ascii Library
Much thanks to Majenko for explaining the problem and greiman for writing the library!

Both the SD library and the SSD1306 libraries want big buffers. That means lots of memory.  You don't have lots of memory.

The SD wants at least 512 bytes for a sector buffer (which is allocated at compile time).
The SSD1306 wants at least 1kiB for a display buffer (which is allocated at runtime).
Serial wants at least 128 bytes for TX and RX buffers (which is allocated at compile time).
The Wire library needs 32 bytes for a TX buffer.

That's 1696 bytes of a total 2048, and that's not taking into account any of the other variables and things that your program, the various libraries, and the Arduino core itself needs, plus the stack (and its specified minimum size safety zone).
There's nothing much you can do about it, short of upgrading your Arduino to one with more memory, or splitting your design across multiple Arduinos.

Is there a way to know exactly how much memory I am over by at runtime?

Not really, no. All you know is that trying to allocate the memory failed.

There is somewhere a "free memory" example / library that can tell you how much free memory there is, though, which could help.

source: Stack Exchange

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

sort: votes


text:
What is the maximum number of sensors that can be operated on a single Aurdino unit
I currently have an Aurdiuno uno and a motor driver shield: (http://www.hobbytronics.co.uk/arduino-motor-shield).
Now, I would like to run the following mechatronic devices:
3 bi-direction motors,
1 servo,
1 hall effect sensor (digital),
2 infra-red sensors,
1 magnetometer,
1 ultrasonic sensor,
Will the Aurdiuno uno paired with the motor sheild be able to run these components or will I need to buy an Aurdiuno mini? Could I please gain some insight into how you figure out what pins are required and how would i connect the sensor pins to the motor sheild since it does not have any direction slip on connections like the Aurdiuno Uno. Will I need to solder the sensor connections on?
Thankyou

Will the Aurdiuno uno ... buy an Aurdiuno mini?

The main differences between the uno and mini are:

footprint
6 (uno) vs 8 (mini) analog inputs

You will get two extra analog inputs and a much smaller size at the cost of the shield not fitting anymore.

Now, I would like to run the following mechatronic devices: 3 bi-direction motors, 1 servo, 1 hall effect sensor (digital), 2 infra-red sensors, 1 magnetometer, 1 ultrasonic sensor, Will the Aurdiuno uno paired with the motor sheild be able to run these components?

According to the website the shield supports up to 4 motors or 5 servos, so i would guess that it would work.
if the shield can't do 3 motors and 1 servo at the same time, then you can just use the servo library and a pin for that.
The shield requires 3 pins to function; so you need 3 or 4 pins depending on configurations.
Inputs 1 digital, 4 analog; 1 Digital I\O, 1 Analog In
so it looks like you need 4-5 DIO pins and 4 analog pins, which the uno has so yes.
If you were using motor driver boards instead of a shield the cost would be
2x PWM per Motor/driver combo = 6 PWM
1 DIO for servo
1 DIO for digital input
4x Analog Inputs
Which also fits in the budget all 6 of the PWM DIO pins, + 2 more (leaving 6 of the 14) and 2/3rds of the analog pins (also good you can leave A3,4 alone since they share a timer and only use the other ones)

Thanks for the concise answer. Just to clarify when you say budget is that the number of pins avaliable?

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


text:
Pipe serial dump to SD card file
I am using the RFID module to read mifare NFC chips and the library has only methods to send the data to the serial monitor. I need them to be saved to an SD card file. I have been adding custom methods to the library files to return strings that I then write to the SD card but this is a pain; there must be a quicker way to simply pipe all the data automatically but I do not know how to do this in cpp.
Here is an example of the function to dump to serial, that needs to be piped to the file on the SD card.
void MFRC522::PICC_DumpDetailsToSerial(Uid *uid) {
    Serial.print(F("Card UID:"));
    for (byte i = 0; i < uid->size; i++) {
        if(uid->uidByte[i] < 0x10)
            Serial.print(F(" 0"));
        else
            Serial.print(F(" "));
        Serial.print(uid->uidByte[i], HEX);
    }
    Serial.println();

    // SAK
    Serial.print(F("Card SAK: "));
    if(uid->sak < 0x10)
        Serial.print(F("0"));
    Serial.println(uid->sak, HEX);

    // (suggested) PICC type
    PICC_Type piccType = PICC_GetType(uid->sak);
    Serial.print(F("PICC type: "));
    Serial.println(PICC_GetTypeName(piccType));
}

Thanks!

the arduino does not have an operating system, so there is no "pipe" as is in linux ....... maybe there is a way to redefine the Serial object

Have the MFRC522 objects remember where you want them to send the output
by adding a data member to the class like this:
private:
    Print &output;

This is a reference to a Print object, i.e. any object where you can
print() or println() to. This reference should be initialized in the
constructor, like this
MFRC522:MFRC522(...other arguments..., Print &my_output = Serial)
: ...other initializations..., output(my_output)
{
    ...constructor body...
}

Notice that, by default, the output is initialiazed as a reference to
Serial. Thus, unless you explicitly ask for the output to go
elsewhere, the class will behave as before.
Last step is to change, in the implementation of the class, every
reference to Serial by output. This is just a global find and
replace.
At this point, the MFRC522 class can be used exactly as before, and it
will behave identically. This means that every user of the library
should be able to use your modified version with no issues. I thus
encourage you to submit the changes to the original author, so that they
have a chance to be incorporated into the canonical version of the
library.
Now, if you want this debugging output to be sent elsewhere, just
provide the destination as the last argument of the constructor:
MFRC522 my_RFID_module(...other arguments..., my_SD_card_file);

As long as the destination is an instance of the Print virtual class
(basically anything you can print() to should be OK), it should work
as expected.


text:
"AtLibUsbDfu.dll not found" when using FLIP on Uno R3
Attempting to flash a new firmware with FLIP results in a "AtLibUsbDfu.dll not found" error and windows says that "Arduino Uno" already has the latest drivers.
How do I fix the AtLibUsbDfu.dll error? All sources say to update the driver to fix this but I already have the latest driver and windows wont let me change it.

A quick google for AtLibUsbDfu.dll results in many "How to fix..." websites. And even some videos. I'm sure they can help you quicker and better than we can...

And you don't care about the Arduino Uno drivers. They are irrelevant. They are only for the CDC/ACM firmware, which you are replacing.


text:
Arduino Uno unable to detect serial port on MAC os Mojave 10.14.2
Ive upgraded to Mojave.  I've never used Arduino before.  I was given Arduino Uno.
Arduino Uno does not find any serial ports... can't load Blink example (the first step)
In blind frustration, I tried the three ports available... None of work.
I've loaded the
CH34x_Install_V1.4.pkg
to no avail.
How do I get a serial port package that will enable serial ports in general (and more importantly for arduino)
thx,
Bruce
On a related Note: the list of things that Mojave broke is long!  To solve many problems, re-install xcode FIRST!!! and read articles on apache, there is a "new and improve" apache server embedded in mojave.

you have it mixed up .... the Arduino Uno does not detect a serial port ..... the MAC detects the Arduino Uno as a USB serial port which can then be selected in the Arduino IDE

OK.  What can I do to get the serial port to show up in the IDE?  Currently the IDE sees /dev/cs.Bluetooth-Incoming-Port, /dev/cu.BrucesiPhone-WirelessiAP and /dev/cu.SSDC

I have this problem too ... plug the arduino into a USB port and nothing happens. (https://www.youtube.com/watch?v=mlejsgxOxrU)

If you are using a genuino or genuine Arduino, the most common cause of this is using a USB power only cable to connect rather than a data cable. (You only need the CH34x_Install_V1.4.pkg if you are running an Arduino clone based on that chipset)
If I ran the world, the USB standard would include some way to distinguish whether it's power only or power and data without having to test it with a multimeter. I know, I know, that's crazy talk.


text:
Error with AT+CIPSEND in ES8266 with arduino
I'm making simple web-server on esp8266 module connected to Arduino. And when +IPD,0,GET... I'm sending AT+CIPSEND=0,16. Then I write HELLOMYDEARFRIDE.
It says : send 16 bytes recived. OK. But in browser it says me that server haven't given any right response. What is problem in?
Code:
#include <SoftwareSerial.h>

SoftwareSerial softSerial(10, 11);
String ssid = "***";
String password = "***";
String _response = "";
#define DEBUG true
void setup()
{

  Serial.begin(115200);

  softSerial.begin(115200);
  connectWifi();
}

void connectWifi() {

  do {
    sendData("AT+RESTORE\r\n", 5000, DEBUG);
  } while (softSerial.find("OK"));
  do {
    sendData("AT\r\n", 2000, DEBUG);
  } while (softSerial.find("OK"));
  do {
    sendData("AT+CWMODE=1\r\n", 1000, DEBUG);
  } while (softSerial.find("OK"));
  do {
    sendData("AT+CWJAP=\"" + ssid + "\",\"" + password + "\"\r\n", 5000, DEBUG);
  } while (softSerial.find("OK"));

  do {
    sendData("AT+CIFSR\r\n", 1000, DEBUG);
  } while (softSerial.find("OK"));
  do {
    sendData("AT+CIPMUX=1\r\n", 1000, DEBUG);
  } while (softSerial.find("OK"));
  do {
    sendData("AT+CIPSERVER=1,5000\r\n", 1000, DEBUG);
  } while (softSerial.find("OK"));

}

String sendData(String command, const int timeout, boolean debug)
{

  String response = "";

  softSerial.print(command);        long int time = millis();
  while ((time + timeout) > millis())
  {
    while (softSerial.available())
    {
      char c = softSerial.read();
      response += c;
    }
  }

  if (debug)
  {
    Serial.print(response);
  }

  return response;
}
int connectionId,pin;
void loop()
{
    if (softSerial.available()) {
    Serial.write(softSerial.read());
  }
  if (Serial.available()) {
    softSerial.write(Serial.read());
  }

}

what is the browser expecting to receive?

Google Chrome is expecting reciving

you misunderstand what i asked .... the browser expects the web page to have a specific format .... investigate what the required format is ..... start by saving a simple web page to your computer and then examine the saved file with a text editor

you must return a valid HTTP protocol response

Browser receive a "Hello World!" as html code. And it can be showed as page.

Juraj how can I do It?

"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n" but you need to send this line by line (without \r\n) if you send it from Serial Monitor

Thank you. Juraj it didn't worked.


text:
Myoware reading multiple fingers?
So I have recently been trying to use the Myoware Muscle sensor to control an 3d printed arm, but it is only able to read the muscle of the entire arm. Is there anyway i could make the Myoware sensor read different fingers at the same time?

I don't think so. I have already a lot of trouble to have a consistent results with Myoware. The muscles for the fingers are smaller and a little deeper. I think that you can not use the muscles to measure motion of the fingers. You need to measure the mechanical motion or bending of the fingers, for example with a glove with stretch sensors.

Ooo ok then thx for the help, i'll see what i can do

Our MyoWare sensor is a single channel EMG sensor and should only be used to detect a single muscle at a time. BUT, if you have 5 sensors, then you can indeed use them to measure each finger's flexion or extension individually. It would take 10 sensors to do both flexion and extension of all your fingers.
However, keep in mind that there are many muscle groups on top of each other in the forearm (e.g. finger muscles, wrist muscles, forearm rotation muscles) and the MyoWare uses surface electrodes. The sensor will detect the activity of any muscle(s) that get activated under the area of the electrodes and you could get a lot of cross-talk between these muscles. For example, the muscles that control your wrist are under the muscles that control your fingers. Any activation of your wrist muscles when trying to measure the finger muscles would cause the sensor to falsely register activity for your finger muscles.

If you are thinking of using it to detect finger position, I would advise using a flex sensor or something similar than a muscle sensor. Muscle sensor sensors are usually used to detect force or as an on/off switch given a threshold value to activate the switch.

I would also recommend using the MyoWare Cable Shield with electrodes smaller than the standard 1" ones that are usually sold along side the sensor. This would help you target smaller muscles without as much cross-talk from adjacent muscles.

Ok i will keep that in mind thx


text:
Powering arduino with battery
I haven't tried so don't know if it works or not. So I got a 6v battery AA, is it possible to run my arduino uno which already got a code in it if I plug + pin to vin and - to GND? Without its USB?

Get a 5 battery holder and put 5 alkaline batteries into it. (5 battery holders are sometimes used to provide 6 volts from ni-cat or NiMh batteries, which provide ≈1.2V.
5 alkaline AA batteries would give you ≈7.5V, which gives you more "wiggle room" for the voltage regulator.
EDIT:
As Gerben pointed out in their comment, 5 AA batteries will drop below the minium voltage input to the Arduino's voltage regulator well before they are depleted. A 6 battery holder would let you use more of the total battery capacity. (At the cost of wasting the excess voltage as heat.)

With only 5 batteries, the voltage will drop below 6V when the individual batteries reach 1.2V. This will use, at best, only 66% of the capacity of an AA battery. I'd suggest a 6 AA battery holder.

The UNO recommends at least 7 Volts on the Vin. 6 Volt is the absolute minimum. As the AA batteries drain, the voltage will be below this 6 Volts very quickly.
I tend to use a 3xAA battery holder, giving around 4.5Volt, and connect that straight to the Vcc pin (bypassing the voltage regulator). This works just fine in most cases.

Sorry im quite new to this, but where is the vcc pin?

Is it the one in the ISCP?

Because my idea is that i want to use both the 3.3v and 5v pins, without using adapter or the usb cable

That is a very bad idea. You should never feed unregulated power into the VCC pin.

Eh, feeding battery power to VCC is only a moderately poor idea, and not always even that bad.

I meant the 5v pin.

Go and buy some 9v Duracell battery and use it . Put the plus in Vin and the negative in gnd  .
Also i noticed that you are a newbie to arduino  so  be aware.
5v pin in arduino it's an output voltage.
3.3 v also output voltage.
Vin is the vcc is An electronics designation that refers to voltage from a power supply connected to the "collector" terminal of a bipolar transistor. In an NPN bipolar (BJT) transistor, it would be +Vcc, while in a PNP transistor, it would be -Vcc.
Gnd mean ground .
Read this please.
https://www.pcmag.com/encyclopedia/term/53705/vcc


text:
Method to iterate over the bits in a byte sent over serial
In my current project which integrates Arduino/avr IC with Raspberry-Pi, and each communicating via serial, I'm looking to send a byte of data to the Arduino from the RPi, which then would be iterated over, bit by bit.
Each bit represents a setting. If a bit is 0, then the Arduino would turn that respective device off, if a bit is 1, then Arduino would turn that respective device on. For example, a byte such as: 01100110, would mean the Arduino would have to turn four devices off, and four devices on.
I'm looking for information on how to take a byte over serial, and iterate over that byte bit by bit, and have the Arduino make decisions based on the value of each bit.
Excuse my post for lacking much technical detail, I'm refraining from using terms that are still very vague to me.
Regards.

your question is a C++ programming question  ..... it is not related to the Arduino  specifically

In all the examples below, value is the value of the byte
LSB -> MSB - so 00001111 would turn ON the first 4 devices and turn OFF the last 4
for(int i = 0, mask = 1; i < 8; i++, mask = mask << 1)
{
    if (value & mask)
    {
        // bit is on
    }
    else
    {
        // bit is off
    }
}

Alternatively, you can do the following, but value will be altered
for(int i = 0; i < 8; i++, value = value >> 1)
{
    if (value & 1)
    {
        // bit is on
    }
    else
    {
        // bit is off
    }
}

Working the other way around in each byte:
MSB -> LSB - so 00001111 would turn OFF the first 4 devices and turn ON the last 4
for(int i = 0, mask = 128; i < 8; i++, mask = mask >> 1)
{
    if (value & mask)
    {
        // bit "i" is on
    }
    else
    {
        // bit "i" is off
    }
}

Alternatively, you can do the following, but value will be altered
for(int i = 0; i < 8; i++, value = value << 1)
{
    if (value & 128)
    {
        // bit is on
    }
    else
    {
        // bit is off
    }
}


text:
Servo not moving
I have connected my servomotor (MG996R) to my L293D motor shield, which is connected to an Arduino Uno R3 Board.
I use 4x AA 1.2V NiMH batteries to power the shield, and a regular 9V battery to power the Arduino separately. I've removed the jumper wire on the shield.
I've tried uploading all the example codes I could find, multiple times, yet none of them work. The servomotor simply doesn't move at all.
Is there anyway I could see if my servomotor is broken ?
Maybe the wiring is wrong, but I don't think so. Orange is for signal, Red is for + and Brown is for GND.
Could someone help troubleshoot the problem ? Thanks !
PS : here is the example code I use
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

You said that you are using L293D shield. What is pin 9 then? And why are you trying to use <Servo.h>? Your code is intended to work with servos attached directly to Arduino. It will not work with servos attached to some external shield. Your shield is supposed to have its own library/protocol for controlling stuff attached to it.

Pins 9 and 10 are the ones used to control the Servo pins on the L293D.
I've just tried to plug in another servomotor and it works just fine when I use pin 10, which matches the "SERVO1" pin on the L293D.

You have two problems
Both of them is related to your power supply :

1st, max. Voltage requirement for your servomotor is 6 volts, not 9 volts

2nd، your batteries are weaker than servo's need.
Your servomotor need 2.5 Amps. In the max. Torque.

So, over-voltage and not enough current is your fault
(According to 996R servomotor datasheet).
Change your power supply by suitable one


text:
Split serial monitor output to only save part of the output
This is the output i get from the serial monitor from using a HM10 in . How could i go about splitting the data using arduino uno.  I only want to save the last 12 digits before the :- (4CAA0DE091B7) for it to then be in a format to send as an SMS using a GSM module
OK+Set:1OK+Set:1OK+RESETOK+DISISOK+DISC:00000000:00000000000000000000000000000000:0000000000:4CAA0DE091B7:-062OK+DISC:00000000:00000000000000000000000000000000:0000000000:38F9D379C9E5:-062OK+DISC:00000000:00000000000000000000000000000000:0000000000:446B17218E0C:-073OK+DISC:00000000:00000000000000000000000000000000:0000000000:649BDE9A25C5:-077OK+DISC:00000000:00000000000000000000000000000000:0000000000:DF12A8020D32:-042OK+DISC:00000000:00000000000000000000000000000000:0000000000:4AAC2B4B1C7C:-081OK+DISC:00000000:00000000000000000000000000000000:0000000000:7F4B515BC186:-079OK+DISC:00000000:00000000000000000000000000000000:0000000000:42AB41C03534:-059OK+DISC:00000000:00000000000000000000000000000000:0000000000:7D2A86B2A8CD:-082
OK+DISCEOK+DISISOK+DISC:00000000:00000000000000000000000000000000:0000000000:38F9D379C9E5:-063OK+DISC:00000000:00000000000000000000000000000000:0000000000:42AB41C03534:-063OK+DISC:00000000:00000000000000000000000000000000:0000000000:4CAA0DE091B7:-062OK+DISC:00000000:00000000000000000000000000000000:0000000000:4AAC2B4B1C7C:-073OK+DISC:00000000:00000000000000000000000000000000:0000000000:446B17218E0C:-071OK+DISC:00000000:00000000000000000000000000000000:0000000000:7F4B515BC186:-079OK+DISC:00000000:00000000000000000000000000000000:0000000000:649BDE9A25C5:-089OK+DISC:00000000:00000000000000000000000000000000:0000000000:0CF98919DB7C:-077OK+DISC:00000000:00000000000000000000000000000000:0000000000:DF12A8020D32:-041OK+DISC:00000000:00000000000000000000000000000000:0000000000:56
OK+DISISOK+DISC:00000000:00000000000000000000000000000000:00000OK+DISISOK+DISCEOK+DISC:00000000:00000000000000000000000000000000:0000000000:4AAC2B4B1C7C:-071OK+DISC:00000000:00000000000000000000000000000000:0000000000:38F9D379C9E5:-080OK+DISC:00000000:00000000000000000000000000000000:0000000000:7F4B515BC186:-081OK+DISC:00000000:00000000000000000000000000000000:0000000000:4CAA0DE091B7:-063OK+DISC:00000000:00000000000000000000000000000000:0000000000:0CF98919DB7C:-077OK+DISC:00000000:00000000000000000000000000000000:0000000000:446B17218E0C:-070OK+DISC:00000000:00000000000000000000000000000000:0000000000:649BDE9A25C5:-077OK+DISC:000
OK+DISCEOK+DISISOK+DISC:00000000:00000000000000000000000000000000:0000000000:4AAC2B4B1C7C:-075OK+DISC:00000000:00000000000000000000000000000000:0000000000:4CAA0DE091B7:-076OK+DISC:00000000:00000000000000000000000000000000:0000000000:38F9D379C9E5:-063OK+DISC:00000000:00000000000000000000000000000000:0000000000:649BDE9A25C5:-078OK+DISC:00000000:00000000000000000000000000000000:0000000000:DF12A8020D32:-044OK+DISC:00000000:00000000000000000000000000000000:0000000000:42AB41C03534:-059OK+DISC:00000000:00000000000000000000000000000000:0000000000:446B17218E0C:-071OK+DISC:00000000:00000000000000000000000000000000:0000000000:7D2A86B2A8CD:

implement a circular buffer of say 30 characters.
clear the circular buffer
read into the circular buffer, char by char
when the last 13 characters in the buffer are: :4CAA0DE091B7 Then the prior 12 characters are the data of interest


text:
Where are the implementations of the SdFat BlockDriver methods?
This is most probably more of a C++ question than an Arduino question; but since this is an Arduino library, I am asking here.
I am using the SdFat library for my project. The library defines a BlockDriver object in one of its header file which only declares the typedef of BaseDriver to some other classes.
#if ENABLE_EXTENDED_TRANSFER_CLASS || ENABLE_SDIO_CLASS
typedef BaseBlockDriver BlockDriver;
#else  // ENABLE_EXTENDED_TRANSFER_CLASS || ENABLE_SDIO_CLASS
typedef SdSpiCard BlockDriver;
#endif  // ENABLE_EXTENDED_TRANSFER_CLASS || ENABLE_SDIO_CLASS
#endif // BlockDriver_h

typedef SdSpiCard BlockDriver; makes sense to me. But if ENABLE_EXTENDED_TRANSFER_CLASS or ENABLE_SDIO_CLASS are defined, BlockDriver is typedeffed into BaseBlockDriver. BaseBlockDriver is an abstract base class (as defined here). An instance of the BlockDriver object is later used directly in the FatVolume class here.
My question is, how does BlockDriver's method get defined when it abstract base class BaseBlockDriver is typedeffed to BlockDriver?

did you read the answer?

I read it. It does not fully clarify it for me, so I am reluctant to accept it.

what is unclear in the answer?

I am not so good with programming which makes it difficult for me to understand. Basically I do not understand what "The typedef in BlockDriver.h is only for pointer type, not for instance of the object." means or implies. Even though we are declaring it as a pointer, we later call methods on it. How do those method work when BlockDriver is a BaseBlockDriver. Hope that clarified my confusion.

the SdSpiCard class should be derived from the BaseBlockDriver. but for AVR this consumed memory. so the author decided to leave out the base class for AVR. but then everywhere in the code where BaseBlockDriver was used as parameter type, an object of type SdSpiCard could not be used as value. He solved it with creating a macro BlockDriver which is BaseBlockDriver or SdSpiCard

I think I understand. Unfortunately, it is not clear for me yet on account of lack of understanding of OOP. I will accept your answer, but kindly elaborate on it and provide more background if you can find some time. Thanks for your patience and contribution.

there is nothing more. did you read my question to Bill Greiman and his answer on GitHub?

yes i did. Your answer does not explain the thing in detail and I believe can be improved. It takes for granted that the reader is well versed in OOP.
I still do not get how one can call virtual methods. I.e. when BlockDriver is a BaseBlockDriver object, what are its actual methods? If my BlockDriver points to a BaseBlockDriver object (which in itself shouldnt be possible as that is an Abstract class), how do its methods get called. you tell me "The object is always of type SdSpiCard" whereas the typedef i quoted in my question clearly shows thats not the case.

if BaseBlockDriver class it not excluded, it is a base class for SdSpiCard. a pointer type to base class can point to an instance of a derived class. like you can refer to some Labrador as "a dog".

I think I now have some kind of understanding on this. Thank you for bearing with me. I will accept this answer. However, I still feel the answer could be much clearer.

The typedef in BlockDriver.h is only for pointer type, not for instance of the object. The object is always of type SdSpiCard, but in one case it is not an implementation of BlockDriverBase, so the function parameters can't refer it by base type.
#if ENABLE_EXTENDED_TRANSFER_CLASS || ENABLE_SDIO_CLASS
class SdSpiCard : public BaseBlockDriver {
#else  // ENABLE_EXTENDED_TRANSFER_CLASS || ENABLE_SDIO_CLASS
class SdSpiCard {

use of BlockDriver typedef
class FatFileSystem : public  FatVolume {
 public:
  bool begin(BlockDriver* blockDev, uint8_t part = 0) {

I was curious why the version without BaseBlockDriver. I asked the author Bill Greiman and he answered:

This is due to history. Long ago using a virtual base class cost lots
  of RAM and flash so I did this mainly for 328 boards


text:
AnalogRead value constant for a varying voltage (for LED brightness variation)
Having the 11~ pin on OUTPUT mode that delivers a varying voltage (from 0 to 5 : 0 to 255).
and the A0 pin on INPUT mode to read the voltage, I find that the value read by A0 being either 0 or 1016 instead of it gradually taking multiple values between the two. what is the catch?
The circuit and the code i am using:

int volt = 0;
int sign = 1; //values: (1, -1), increments or decrements "volt" by 5.
float potential;

void setup() {

  pinMode(11, OUTPUT);
  pinMode(A0, INPUT);
  Serial.begin(9600);

}

void loop() {

if (volt == 0){sign = 1;}
if (volt == 255){sign = -1}

volt = volt + sign * 5; //raises brightness to 255 from 0, then to 0 from 255.
analogWrite(11, volt);

potential = analogRead(A0);

Serial.println(potential);

delay(30);
/*
*/

}

even filtered, you won't see a value between the LED's Vf and 5v, keep that in mind.

As CrossRoads says, there really isn't any such thing as analog output on an Arduino. (Any Arduino unless it has a built-in DAC.) It uses pulse-width modulation to vary the "duty cycle" of the output from 100% on to 0% on, which simulates an analog voltage.
If you drive an LED with PWM (and the required current limiting resistor) your eyes will not see the flashes, and will average out the brightness based on the duty cycle of the PWM signal.
If you want an actual analog voltage from PWM you will need to add a filter capacitor to average out the voltage over time. With a simple single capacitor filter you'll still have flutter in the output but it will be closer. If you want a clean constant voltage you'll need a more complex filter.

@Gerben you edited my answer to talk specifically about Arduino Uno. My answer applies to all Arduinos. (Arduini?)

both the Arduino Zero and Arduino Due have built-in DACs (Digital to Analog Converter). And then there are the numerous Arduino-compatibles from Sparkfun, Adafruit and other vendors that use chips with DACs. For example the ESP32 based boards, or the popular SAMD21. So definitely not all Arduini (Arduinos?).

I stand corrected then. I made my answer not specific to the UNO, but to all Arduinos that lack DACs

The PWM output pin does not vary voltage - it only outputs 0, or 5V. The amount of time that 5V is on, from 1/255 of about a 2mS period, to 255/255 of the same period, determines how bright the LED is perceived to be.
You really need a current limit resistor in series with the LED to keep from burning out the uC output pin, or from burning up the LED.

Thanks, if the OUTPUT voltage isn't really varying, how does the LED brightness vary?
https://streamable.com/vc106

@Huskarnov It flickers too fast for your eye to catch, the more it is on the brighter it seems.

The amount of on-time is perceived by the eye as dimmer or brighter.  It's the way our brain works.

@Huskarnov this GIF might help visualize it.


text:
Number of cycle depending on the number and type of statements
I did this little experiment to count the number of cycles per second in two different configurations:
1-The variable a is initialized at zero and incremented by one each cycle of the loop.
 -The value of a is written each cycle
 -at millis() = 1000, the incrementation ends, and the value of millis() is written to check the precision of timing.
Code:
long a = 0;
int v = 1;

void setup() {

Serial.begin(9600);

}

void loop() {

if (v == 1){
a = a + 1 ;

Serial.println(a);

if (millis() >= 1000){
Serial.println(millis());
v = 0;}

}
}

Result:
1
2
.
.
.
227
1000
2-Same as 1, but the value of a is written only at the end.
Code:
long a = 0;
int v = 1;

void setup() {

Serial.begin(9600);

}

void loop() {

if (v == 1){
a = a + 1 ;

if (millis() >= 1000){
Serial.println(millis());
Serial.println(a);
v = 0;}

}
}

Result:
1000
265174
-So, 227 cycles for 1, and 265174 for 2, is this correct, and can such a simple modification slow the cycling by 1000?

Serial.print() takes a lot of time, so result is correct.

Writing via the serial interface takes a lot of time (just consider the baud rate you selected).
You should always keep in mind that changing the amount you are printing might change your programs behaviour.
That means, your 2. configuration is (more) reliable.

When the serial buffer (64 bytes) is full the print waits until bytes are send away at 9600 baud.

You could use micros() as well to increase resulution to 4uS, vs 1000uS.
Up the speed to 115200, that should show some improvement as well.


text:
Adding a common activation pin to a group of buttons
I'm working on an Uno, which has only two interrupt capable pins, but i need at least three buttons to wake it up from its power saving mode.
Is there a way to wire buttons such that, in addition to their individual pin, they will also activate a common pin (in this case, the interrupt one)?

Why not using the PinChange Interrupt instead? That can also wake the Arduino from sleep modes. And it works with nearly every pin. Though you have one interrupt for a group of max 8 pins and you need to check, which button was pressed, inside the ISR.

Thanks! Will this also work while in CPU sleep mode from the avr/sleep.h library?

You could use diodes to "or" multiple buttons together. But in this case I'd go with the pcint solution proposed by chrisl.

You can connect all the buttons to a single interrupt pin by ORing them via diodes (like Gerben wrote in the comments). That would look like this:

simulate this circuit – Schematic created using CircuitLab
The diodes isolate each input pin from the other, but allow the buttons to pull down the interrupt pin.
Though that is not the way, that I would suggest. Instead you could simply use the PinChange interrupt. That is a different type of interrupt, which can react to all pins of a port in a single ISR for the whole port. You can mask unused pins of the port away, so that the interrupt doesn't trigger for them. Nearly every pin is usable that way.
If you want to use the Arduino framework for this, you can just use the attachInterrupt() function, which can use the PinChange interrupt in the background.
If you want to go more down into the hardware side and configure the interrupt yourself, you should look into the corresponding sections of the datasheet. The Uno uses the Atmega328p. From 12.2.4 on you see the registers used for the PinChange interrupt (aka PCINT).

With the bits in PCICR you can enable the PinChange interrupt for the ports (3 distinct interrupts for the Uno).
The PCMSKn (n meaning number between 0 and 2) is used to mask unused pins of the port away. You should set the bits for the used pins to 1, the others to zero.

Then you need to define the actual Interrupt Service Routine (ISR) in your code:
ISR (PCINTn_vect) // handle pin change interrupt for D8 to D13 here
{
    ...
}

Here again substitute the n for the number of the PinChange interrupt, that you are using. Inside the ISR you need to read all the input pins of the buttons, that are connected to this PinChange interrupt, and execute your code accordingly. Note: As the name states, the interrupt is triggered on every change of the pin. Inside the ISR you need to sort out, what change that was. It comes down to just reading the pin, but you should keep that fact in mind.
Also make sure to never do long things inside an ISR; it has to be as short as possible; Do long things inside the main code, which can get triggered via a flag variable from the ISR)
If you google for something like "Arduino pin change interrupt" you can find detailed tutorials for this, which can go way deeper, than I can on this Q&A site.

Will this also work while in CPU sleep mode from the avr/sleep.h
library?

According to Table 9-1 in Chapter "9.1 Sleep Modes" in the datasheet, the PinChange interrupts are on the same level as the External Interrupts INTn in regard of sleep modes. So this should work just like with the INTn interrupts.


text:
RAM cost of entering functions
A friend has told me I shouldn't rely on functions because, during execution, they occupy a significant amount of RAM.
Is that true or, if it isn't, what's the maximum suggested level of function nesting at runtime?

http://wiki.c2.com/?PrematureOptimization

A friend has told me I shouldn't rely on functions because, during execution, they occupy a significant amount of RAM.

I wouldn't say "significant", but some RAM is used, yes.
Every time a function is called any registers used in the execution of that function are placed onto the stack. Also some parameters to the function may be passed on the stack (depending on the ABI for the architecture you're using). Further, any local variables used inside the function also go on the stack.
These are only temporary allocations and are released again when the function exits.
Depending on your program the "call stack" can be insignificant compared to the local variables.

what's the maximum suggested level of function nesting at runtime?

Low enough that you don't run out of memory. When you have plenty of memory then your call stack is irrelevant. When you only have a couple of hundred bytes, or a hardware stack (like on the low-end PIC microcontrollers) with a limited depth, then keeping your program flatter can be better.
The main reason for flattening a program is usually for execution speed rather than for memory use.

Also, if a function is only called in one location, or is very short, the compiler will try to inline the function, negating the "cost" associated of the function call.

I guess avoiding functions may have been relevant with dumb compilers, a
few decades ago. Compilers today are pretty good at optimizing and,
since recently, the Arduino environment enables “link time
optimization”. This means the optimizer can see the whole program at
once, which enables:

function inlining across compilation units (and the optimizer does
this pretty aggressively)
saving, in the function prologue, only the registers that really need
to be saved.

In most cases, the “optimal” size for a function is whatever size
optimizes the readability of the code. In the rare cases where you would
need to merge a function into its callers for performance purposes, you
can qualify the function as
inline __attribute__((always_inline))

But this only makes sense after you disassembled the program and noticed the
compiler did not make the right optimization choices. A quite infrequent
situation.


text:
TinyGPS++ isn't being updated or SoftwareSerial isn't reading
I'm trying to read the GPS data on an Arduino Uno from a Neo-6M module and print it on a LCD display. However, no variable is being changed by the read function. This could either be because of an incorrect reading of the gps variable or a wrong use of the SoftwareSerial library.
Here's the code:
#include <TinyGPS++.h>

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <splash.h>

#include <SoftwareSerial.h>

Adafruit_SSD1306 display;  // Create display
SoftwareSerial gpsSerial(4,3);//rx,tx
float lati=0,longi=0;
float sat=0;
TinyGPSPlus gps; // create gps object

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  gpsSerial.begin(9600); // connect gps sensor
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // Initialize display with the I2C address of 0x3C
  display.clearDisplay();
  display.setTextColor(WHITE);
}

void loop() {
  // put your main code here, to run repeatedly:
  display.clearDisplay();

    gps.encode(gpsSerial.read());
    display.setCursor(80,3);
    display.print("R");

  //if(gps.location.isUpdated())
  {
    lati = gps.location.lat();
    longi = gps.location.lng();
    sat = gps.satellites.value();
    display.setCursor(100,3);
    display.print("U");
  }

  display.setCursor(20,20);
  display.print(lati);
  display.setCursor(20,40);
  display.print(longi);
  display.setCursor(100,40);
  display.print(sat);
  display.drawRect(0,0,127,63,WHITE);
  display.display();
}

EDIT: The data coming from gpsSerial is a series of -1
EDIT 2: Swapping SoftwareSerial gpsSerial(4,3); to SoftwareSerial gpsSerial(4,3); makes it output a series of ints. However, encoding it with gps.encode(gpsSerial.read()) still doesn't update the data.

no prints to Serial? why not use it for debug prints or connect the gps to it?

then connect the module to Serial and don't use SoftwareSerial

pins RX and TX. 0 and 1.

did you connect RX to TX?

read returns -1 if no data is available


text:
Returning to parent directory with the SD library
I have a File variable called dir and i'm building a simple file explorer for my device. Is there a way to get a reference to dir's parent directory?

Doesn't dir.name() return dir's name with the path?

Unfortunately it only returns the name

Then probably the only way is to keep a list of the directories you traversed while going to that file, or while building the directory structure from root. There may be an other way, but I don't know the SD library well enough.

I don't think there is an inbuilt function returning the parent, but you could do:
FS &file_system = SD; // pick whichever file system you use

File get_parent(File dir) {
  String dirPath = dir.path();
  int lastSlashIndex = dirPath.lastIndexOf('/');
  if (lastSlashIndex != -1) {
    String parentDirPath = dirPath.substring(0, lastSlashIndex);
    File parentDir = file_system.open(parentDirPath.c_str());
    return parentDir;
  }
  return File();
}

but there is no path function in the Arduino SD library. (and no FS type)

I only have esp32-S3 at hand here, and path() is available in framework-arduinoespressif32 -> FS.h, I don't know the situation for other platforms/architectures.


text:
Error: Does not name a type
I have made a class called subjects and I have then made a subject called math. I am trying to set a classroom for math but it is giving me the error 'math' doesn't name a type.
Code for the class
class subject {
public:
  char subjectname[];
  char classroom[];

};

Code for the classroom and math
subject math;
math.classroom = "A1";

How can I set the classroom of math to A1?

class subject {
public:
  char subjectname[];
  char classroom[];

};

This creates a class subject which has two char arrays of unspecified size as its members. This will attempt to create an array of size 0 (see here). This is not what you want. You can e.g. statically allocate the space with a maximum number of characters beforehand and then strncpy() your new string inside the buffer.
This would look like
class subject {
public:
  char subjectname[32];  //32 bytes buffer
  char classroom[32];
};

And later
subject math;
strncpy(math.classroom, "A1", 31); //copy at max 31 bytes to not overwrite the NUL terminator
Serial.print("Classroom is: ");
Serial.println(math.classroom)

Or, just use the Arduino String class.  For example
#include <Arduino.h>
class subject {
public:
  String subjectname;
  String classroom;
};

Then your first usage code can be used unmodified.
Example
#include <Arduino.h>

class subject {
public:
  String subjectname;
  String classroom;
};

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

    subject math;
    math.classroom = "A1";

    Serial.print("Classroom is: ");
    Serial.println(math.classroom);
}

void loop() { }

I tried using this code but it gives me the error 'math' does not name a type at the math.classroom line.
`#include <Arduino.h>
class subject {
public:
     String subjectname;
     String classroom;

};

subject math;
math.classroom = "A1";`

@TechnicProblem I can compile https://pastebin.com/5hVgtTi7 just fine. Does that compile for you?

Thank you. Didn't know I should've put some of the code in void setup(). Now it works.

@TechnicProblem You can put global variables outside of function scopes but not assignments and operations on them. Those must be in functions.

+1 for your excellent answer. FWIW, the String sketch's compile size is 3644 bytes, and the strncpy sketch is 2112 bytes. +100 for using a class in your sketch. The difference in compile size (using the strncpy sketch) VS the same strncpy sketch with all the added OOP code is 0 bytes. Using a class costs you nothing, and gives you a lot. It is unfortunate that there are 3 votes to close this question, stating it's off topic. According to this page: https://arduino.stackexchange.com/help/on-topic , "Specific questions about Arduino boards, code…" are "On Topic".


text:
Unexpected results when creating 32-bit int from byte array
I'm having problems creating a 32-bit integer from a 4-byte array. In the following complete, minimal, and verifiable example, converting a byte array containing 0x00, 0x04, 0x04F, 0x45 results in 4F45 (expected result would be 44F45). I must be overlooking something fundamental here.... can anyone see where I went wrong?
void setup()
{
    Serial.begin(9600);
    while(!Serial);
}

void loop()
{
    uint8_t bytes[4] = {0x00, 0x04, 0x4F, 0x45}; //00044F45
    int32_t theInt = byteArrayToInt32(bytes);
    Serial.println(theInt, HEX); //Print 4F45
    delay(250);
}

uint32_t byteArrayToInt32(uint8_t* bytes)
{
    uint32_t i = 0;
    i |= bytes[0] << 24;
    i |= bytes[1] << 16;
    i |= bytes[2] << 8;
    i |= bytes[3];
    return i;
}

@jsotola in what way?

@jsotola I went ahead re-tested with it as uint32_t, no difference :(

The problem is that you are trying to shift uint8_t more than 8 bits and then OR it with int32_t.
You have to cast the uint8_t to int32_t before doing the shift.
void setup()
{
    Serial.begin(9600);
    while(!Serial);
}

void loop()
{
    uint8_t bytes[4] = { 0x00, 0x04, 0x4F, 0x45}; //00044F45
    int32_t theInt = byteArrayToInt32(bytes);
    Serial.println(theInt, HEX); //Print 4F45
    delay(1000);
}

int32_t byteArrayToInt32(uint8_t* bytes)
{
    int32_t i = 0;
    i |= (int32_t) bytes[0] << 24;
    i |= (int32_t) bytes[1] << 16;
    i |= (int32_t) bytes[2] <<  8;
    i |= (int32_t) bytes[3];
    return i;
}

Note that if the most significant bit of bytes[0] is set, then (int32_t) bytes[0] << 24 will shift it into the sign bit, which is undefined behavior. It is safer to cast to a uint32_t, which can in turn be safely assigned to an int32_t.

Hmm, so doing as you suggested fixes the problem, however I'm very perplexed as to why the left shift by 8 bits worked originally, then?

it appears that the left shift function uses a 16 bit buffer .... possibly because it uses the same code for 16 bit shifts


text:
Memory usage: #define vs. static const for uint8_t
I'm writing an Arduino library to communicate with an I2C device, and I'm wondering what the best way is to declare all the register addresses so as to save memory.
Using #defines:
#define REGISTER_MOTOR_1_MODE 0x44
#define REGISTER_MOTOR_2_MODE 0x47

Or using static const:
static const uint8_t REGISTER_MOTOR_1_MODE = 0x44;
static const uint8_t REGISTER_MOTOR_2_MODE = 0x47;

(Obviously I have more than just two registers I need to declare, but I thought two would illustrate the point just fine)

define's are just "find and replace"s, and can bit you, if you do anything other than numbers. For example #define LED_MASK  0x01<<2. A safe(r) way to write that would be  #define LED_MASK  (0x01<<2). See also https://stackoverflow.com/questions/6542270/what-is-the-standard-to-declare-constant-variables-in-ansi-c

You'll find no noticeable difference memory-wise between the two.
The only real difference is that the const method also imposes a type to the value, which can be useful for function overloading or mathematical operations.

Macros also have types. #define REGISTER_MOTOR_1_MODE 0x44 would cause REGISTER_MOTOR_1_MODE to have a type of int. The difference is more in the explicitness of the type.

@Pharap Almost...  Macros do not have a type. However, the content of the macro can have either an implicit or explicit type. That type is nothing to do with the macro.

The type of the expression that the macro substitutes for is for all intents and purposes the type of the macro. Unless the macro accepts arguments then the expression will always have the same type. You can stick a macro in a decltype and get a valid type. Strictly yes, the macro is gone by the time the actual compilation phase begins, and yes, not all macros will substitute for a valid expression with a type, but the point is that if you put a macro into the code and that macro substitutes for a valid expression then the resulting value won't be 'untyped'.

A #define is a preprocessor macro. As Gerben says in his comment, it's just an automated find-and-replace.
If you use it to hold things like C string constants, e.g. #define ERROR_STRING "You messed up, bud!" it could actually cause your program to take more memory, since that same string literal will be duplicated every time you reference it. In that case a static const would be both type-safe AND reduce memory usage.

Would it be duplicated? I mean, isn't it the job of the compiler to ensure "You messed up, bud!" occurs exactly once in the string constant table?

@juhist: C++ explicitly states that the compiler can choose to duplicate identical strings, or not.  Most compilers have a flag to either do this, or not. I think, by default, most compilers do not merge strings, in case the app relies on them being unique.

@MooingDuck I compiled a program having many std::printf("%p\n", "foo"); lines in it. All of them print the same address.

@MooingDuck: While few compilers will guarantee that strings will always be merged, I think the normal reason is that upholding such a guarantee may impose extra build-time costs and complexity, and the savings in storage from merging strings may or may not be worthwhile.

@juhist: Sure. In your compiler and your compiler flags.  With my compiler and my flags, I get different addresses.

@supercat: Possible, but I'm dubious, since they already have to have similar logic for all inline methods (including almost all templates) anyway.

@MooingDuck: At least historically, good compilers would often include logic so that if memory got low, they could jettison information that wasn't needed for correct compilation.  Compilers might try to hold onto information that would let them merge identical strings or inline functions, but that doesn't mean that they promise to hold such information and use it even when they would be short on memory.

Theoretically both approaches should consume the same amount of space and will probably result in the same code.

However, rather than that meaning "pick any one", what that actually means is that you should turn your attention to other factors when deciding which one to use.
As a rule of thumb you should generally avoid macros because they don't respect scoping rules due to how they work.
This can lead to some serious problems in certain cases.
See Why are preprocessor macros evil and what are the alternatives?.

However, I'd like to point out a third option: constexpr.
constexpr uint8_t motorMode1Register = 0x44;

constexpr implies const and is a better expression of the intent that the value should be capable of being evaluated at compile time.
constexpr literally means "this is a constant expression and thus can be evaluated at compile time".
As a result of this, constexpr variables can be used in situations where other variables cannot, such as template parameters.
See Constexpr vs Macros.


text:
Weird behavior with char/uint8 arrays
So I'm trying to read an 8-byte character string from an I2C device and print it to the serial console. This raw 8-char array is not terminated when it comes from the device, so I'm pretty sure I need to manually terminate it. Unfortunately, when I go to print the resultant string, the serial monitor just fills up with line breaks. Could someone take a look at this code and tell me where I went wrong?
uint8_t* HT_Controller::readMultiple(uint8_t reg, uint8_t num)
{
    Wire.beginTransmission(i2cAddr);
    Wire.write(reg);
    Wire.endTransmission();

    Wire.requestFrom(i2cAddr, num);
    uint8_t* data = new uint8_t[num];

    for(int i = 0; i < num; i++)
    {
        data[i] = Wire.read();
    }

    return data;
}

char* HT_Controller::getManufacturer()
{
    uint8_t* data = readMultiple(REGISTER_MFR, NUM_MFR_BYTES); //Read the bytes from the controller
    char* dataTerminated = new char[NUM_MFR_BYTES + 1]; //Our new array that will have a null char at the end
    memcpy(data, dataTerminated, NUM_MFR_BYTES); //Copy the bytes into the new array
    delete(data); //We're done with the original array, remove it from the heap
    dataTerminated[NUM_MFR_BYTES] = 0; //Add that null char. NB: we don't need to '+1' the index because arrays start at 0, not 1

    return dataTerminated;
}

And here's how it's used in the main sketch:
void loop()
{
    char* data = mc1->getManufacturer();
    Serial.println(data);
    delete(data);
    delay(500);
}

Hint#1: Check the parameter order for memcpy(), http://www.cplusplus.com/reference/cstring/memcpy/. And try writing code without all the heap usage (new/delete).

@MikaelPatel how can I avoid heap usage, keeping in mind this is for a library?

Hint#2: Use the stack and pass return values by reference. e.g. "char dataTerminated[NUM_MFR_BYTES + 1]; readMultiple(REGISTER_MFR, NUM_MFR_BYTES, dataTerminated);"

@MikaelPatel wait but isn't returning a pointer to a local array a no-no?

Oh I think I see what you mean now

@MikaelPatel hmm so that's all well and good for readMultiple(), but in order to apply that to getManufacturer() the user would need to know that the array they pass in to be outputed to needs to be 9 chars big...

Your memcpy is backwards.
SYNOPSIS
   #include <string.h>

   void *memcpy(void *dest, const void *src, size_t n);

So the line:
memcpy(data, dataTerminated, NUM_MFR_BYTES); //Copy the bytes into the new array

should be:
memcpy(dataTerminated, data, NUM_MFR_BYTES); //Copy the bytes into the new array


text:
Emit region-neutral keyboard signals
The Keyboard API allows the Arduino boards such as the Micro or Leonardo to emit USB signals mimicking a physical keyboard. However, the signal seems to transmit key strokes and not characters which means that machines with different region settings interpret the USB signal differently. For example, a y will be interpreted as z in a German OS since the keyboard layout has these keys swapped.
Is there any way to output a signal that will result in the correct character being transmitted regardless of the OS settings without any modifications to the machine the Arduino is attached to?

@jsotola AFAIK most keyboards send the pressed physical key and not the character represented by that key. However I have heard about attempts to allow a keyboard to specify its layout and haven't found any further resources on this.

stumbled across this today ........ https://github.com/NicoHood/HID/blob/master/src/HID-Settings.h

Download Device Class Definition for Human Interface Devices (HID)
https://www.usb.org/sites/default/files/documents/hid1_11.pdf
See section 6.2.1 HID Descriptor
bCountryCode 0x09 German
also see section E.4 (page 67)
E.4 HID Descriptor (Keyboard)
Part            Offset/Size  Description                                         Sample
                (Bytes)                                                          Value
----------------------------------------------------------------------------------------
bLength           0/1        Size of this descriptor in bytes.                    0x09
bDescriptorType   1/1        HID descriptor type (assigned by USB).               0x21
bcdHID            2/2        HID Class Specification release number
                             in binarycoded decimal—for example, 2.10 is 0x210).  0x101
bCountryCode      4/1        Hardware target country.                             0x00
bNumDescriptors   5/1        Number of HID class descriptors to follow.           0x01
bDescriptorType   6/1        Report descriptor type.                              0x22
wDescriptorLength 7/2        Total length of Report descriptor.                   0x3F

That field is ignored by all operating systems. It was intended to be used, but no one does. Keyboard manufacturers didn't want to have to create separate controllers for each and every language of keyboard - it is so much cheaper to just have one and change what's printed on the keyboard. Also I know of no operating system that can apply keymaps to individual inputs - it's only set on the user session as an entirety. All inputs are amalgamated first and then mapped from key codes to characters afterwards.

No. There is no such facility.
If you take a German keyboard and plug it into a US configured computer the key layout will be wrong. You have to tell the computer that you're using a German keyboard.
Keyboards don't know what is printed on the keycaps. All they understand is where the buttons are physically located.
The same with the Arduino. It's sending the keypresses that correspond to the keyboard layout of a US keyboard, and you have to tell the computer that you're using a US keyboard - because that is effectively what you are using.
If you want to change the keyboard map the Arduino uses you will have to manually modify the Keyboard library (file Keyboard.cpp, array _asciimap[128]).


text:
Cannot make sense of values from Bluetooth HC-01
I have a simple script that listens on pin 0 for input, and if it gets anything, it Serial.prints it. But I cannot make sense of the results. I have a basic app that sends text over Bluetooth (in the code I see utf8.encode(message) if that helps), and I'm able to validate that the message is not corrupted by the module, by simply touching the RX and TX pins together, the app receives the same message it sent. But the Arduino cannot understand it.
Here's my code:
void setup() {
    Serial.begin(9600);
}

void loop() {
    if (Serial.available() > 0) {
        Serial.print("New value: ");
        Serial.println(Serial.read());
    }
}

The TX on the HC-01 is connected to pin 0, and the RX is connected to pin 1. Power and ground are connected to the Arduino's (and I even tried different grounds just in case that one was fried). The Arduino is powered by USB and I'm using the Serial moniter. Here is some sample input-output:
Me through the app: a. Arduino: 255
Me through the app: a. Arduino: 254
Me through the app: a. Arduino: 254
Me through the app: a. Arduino: 254
Me through the app: a. Arduino: 254
Me through the app: a. Arduino: 255
Me through the app: aa. Arduino: 254
Me through the app: aaa. Arduino: 252
Me through the app: aaaa. Arduino: 252

I just don't understand any of it. Please help me out.

What is the model if the arduino you are using? On some pins 0 and 1 are also connected to the USB port connected to your PC. If this is the case you may have a conflicted usage of the port.

So should I take out the USB and just power with a battery? I can also have like an LCD print the value. Would that work?

And for reference, I'm using the latest UNO   and kept pin 1 disconnected for that reason

So how did you disconnect pin 0 from the USB? Remeber the PC will be sending a signal on this connection which will likely interfere with the signal coming in from the HC-01. Even if there is no USB activity it will still be LOW or HIGH electrically. FWIW, in your question you imply both TX and RX on the HC-01 are connected to pins 0 and 1 on the arduino. Did you try using a mega or leonardo (Serial1 for the HC-01) if you have them? Or possibly SoftwareSerial on Uno (again FWIW I have never successfully got s/w serial to work reliably but it should be ok for testing)

You may have better luck with the LCD Approach, but it will be harder to debug (no serial monitor). If you have a mega (or something else with two serial ports) life might be easier at least in the "WTF is going on here? phase you are in right now! In my case I always use my leonardo to test bluetooth, xbee and similar "Serial devices" then if appropriate move it over to Uno (cos I've got lots of them) for "production".

Yeah so I did connect both pins and experimented with unplugging pin 1. I also used SoftwareSerial on pins 10 & 11. I have a nano I could hook up... Idk if that will help since SoftwareSerial didn't work.

Glad it's not just me that has problems with it. :-) so my next suggestion would be to replicate the test where you shorted the tx and rx on the HC-01 but in software. That is, 1) connect pins 0 and 1 to tx and ex. Then 2) change your program to read Serial.print(Serial.read()); in place of the prints you have inside the if statement. 3) To be safe, you will need to upload the program, disconnect the USB, then power your arduino via the round power connector (or if you are comfortable/brave enough) via the vin and gnd pins. Then repeat your loop back test you mentioned in your question...

Let us continue this discussion in chat.


text:
timer library on Arduino DUE
I'm trying to call an interrupt routine (let's call it handler() ) every second on my arduino DUE.
I thought the simplest way to do this was to use this library
but it seems that i don't know how to use it...

I guess you mean start(1000000).

yep............... this is embarassing ahahah
Do you have a guess on why wasn't it working with start(1000) ? is Serial.print too long to execute ?

Serial print in an ISR is not recommended. Set a flag in the ISR and poll in the loop() instead.

You are trying to print 6 characters ("test\r\n"), i.e. 60 bits
including the start and stop bits, 1000 times per second. This requires
a baud rate of at least 60 kbit/s, yet the serial port has been
configured for only 9.6 kbit/s. Something has to give...
As Mikael Patel wrote in a comment, it is generally inadvisable to
Serial.print() from within an ISR. It is supposed to work, though, as
long as you don't fill the Serial output buffer. The problem is that
your code does fill the buffer, as it is writing to it faster than the
UART can empty it. Once the buffer is full, the program will
malfunction.

thank you ! I will definitly use a flag now


text:
Real-time Pub/Sub thru MQTT between JoyStick and OnBoard Drive units [both ESP8266] - Connection issues
I looked around for solutions to my issue by searching on the forum and elsewhere and haven't seen similar issues - (https://arduino.stackexchange.com/search?page=2&tab=Relevance&q=MQTT%20ESP8266)
I am describing below what I am trying to achieve: (I am relatively new)
I would like to pass streaming joystick data from a "Remote Control" through MQTT to a "OnBoard" unit to drive my robot. Both the "Remote Control" and "OnBoard" units are NodeMCUs ESP8266.
I am able to separately send data from my Joystick to the MQTT broker and also separately read streaming data from the MQTT broker on any MQTT client. However, the moment I connect the "Remote Control" and the "OnBoard" Units to run their respective code, I keep receiving a Lost Connection to MQTT server error. I also observe this happens right after my Joystick ESP8266 connects.
I suspect this is related to one of the following -

0>> I am doing something fundamentally wrong [Syntax, usage of libraries, logic?]
connection parameters to the MQTT client [keep alive?, QoS?, delay?] b) there
is something to with sequence of Sub & Pub?
the version of ESP MQTT libraries i am using??
this is not the best way to stream data to
control devices? WebSockets?

I am copying my code for both units below:
RemoteControl Unit: [Joystick input is given through Serial]
#include <PubSubClient.h>
#include <EspMQTTClient.h>

void onConnectionEstablished();

EspMQTTClient client(
  "mywifi",           // Wifi ssid
  "somepwd!",           // Wifi password
  "iot.eclipse.org",  // MQTT broker ip
  1883,             // MQTT broker port
  "usr",            // MQTT username
  "mqttpass",       // MQTT password
  "test1",          // Client name
  onConnectionEstablished, // Connection established callback
  true,             // Enable web updater
  true              // Enable debug messages
);

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

void onConnectionEstablished()
{
  Serial.println("Remote Connection Established");
}

void loop()
{
  if (Serial.available() > 0) {
    Serial.println("Inside Serial");
    char bfr[101];
    memset(bfr,0,101);
    Serial.readBytesUntil('\n',bfr,100);
    client.publish("DriveChannel", bfr);
  }
  client.loop();
}

OnBoard Unit:
#include <PubSubClient.h>
#include <EspMQTTClient.h>

void onConnectionEstablished();

EspMQTTClient client(
  "mywifi",           // Wifi ssid
  "somepwd!",         // Wifi password
  "iot.eclipse.org",  // MQTT broker ip
  1883,             // MQTT broker port
  "usr",            // MQTT username
  "mqttpass",       // MQTT password
  "test1",          // Client name
  onConnectionEstablished, // Connection established callback
  true,             // Enable web updater
  true              // Enable debug messages
);

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

void onConnectionEstablished()
{
  client.subscribe("DriveChannel", [] (const String &payload)
  {
    Serial.print("In Connection payload---> ");
    Serial.println(payload);
  });
}

void loop()
{
  delay(3000);
  client.loop();
}

try different client names

@Juraj perfect... missed that. Thank you for pointing out.

was it the cause?

Yes @juraj. I think that was the issue. Since the other mqtt clients (app or browser based) assign their own client id I wasn't having an issue subscribing to it but these two had the same client ids and that seemed to conflict. I have a steady stream of data flowing now with no loss of connection. However, I am seeing a significant delay, it almost feels like instructions being sent to Mars Rover :) , about 10 to 20 second delay for the signals to reach my Onboard unit from the joystick unit.

and the 3 secs delay in loop?

@Juraj the 3 seconds was only during test , i had removed it but continue to see the delay. Maybe my network or a free version of the broker that's causing the delay.


text:
Rfid stops scanning after wrong card scanned
My Rfid reader stops scanning cards after scanning the wrong rfid card. It doesn't scan it anymore after turning off the relay. *It turns on the relay if my rfid card is the right one
#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9
#define relay 2
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
int touchPin = 8;
unsigned long previousMillis = 0;        // will store last time LED was updated
unsigned long tacc = 5000UL;           // interval at which to blink (milliseconds)
boolean opened = false;
void setup()
{
  pinMode(touchPin, INPUT);
  pinMode(relay, OUTPUT);
  digitalWrite(relay, HIGH);
  Serial.begin(9600);   // Initiate a serial communication
  SPI.begin();      // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522
  mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);
  Serial.println("Approximate your card to the reader...");
  Serial.println();
}
void loop()
{
  unsigned long currentMillis = millis();
  int touchValue = digitalRead(touchPin);
  if (touchValue == HIGH) {
    digitalWrite(relay, HIGH);
  }
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    return;
  }
  //Show UID on serial monitor
  Serial.print("UID tag :");
  String content = "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.println();
  Serial.print("Message : ");
  content.toUpperCase();
  if (content.substring(1) == "72 02 EF E9" ) {
  Serial.println("Authorized access");
    digitalWrite(relay, LOW);
    opened = true;
  }
  if (((unsigned long)(currentMillis - previousMillis) >= tacc) && (opened== true)) {
  digitalWrite(relay, HIGH);
    previousMillis = currentMillis;
    opened = false;
  }
}

It turns on the relay if my rfid card is the right one - more than once?

@JaromandaX yes

There is probably an error here: if (((unsigned long)(currentMillis - previousMillis) >= tacc)


text:
I have this compilation error:
C:\Users\MGMCETIT\Desktop\Dumpster\Dumpster.ino: In function 'void loop()':
C:\Users\MGMCETIT\Desktop\Dumpster\Dumpster.ino:40:28: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
 if(esp8266.find("+IPD,"))

                        ^

did you write the esp8266.find function? if you did, that's a simple fix - though, that's just a warning isn't it? the code still compiles

@JaromandaX it is core Stream class. it is only a warning

I did notice it's just a warning :p @Juraj

It appears Arduino decided that it would be a good idea to use char * instead of const char * for functions that don't modify the parameter. It should always be const char * unless you have a good reason not to.  Silly Arduino.

I have submitted a bug report (gently) berating them.

@Majenko, it is there 8 years. commit comment: "This from Michael's TextFinder library, incorporated into the Stream class: find(), findUntil(), parseInt(), parseFloat(), readChars(), readCharsUntil(), readCharsBetween(), setTimeout()."


text:
FastLED Rainbow Wheel Fade on an 8 Pin RGB Matrix
So, I have an RGB matrix (using PL9823 LEDs) that's 32 x 8 that I'm trying to run a circular spinning rainbow pattern across in a continuous loop. Now, there's lots of code online for different ways to do this with a traditional daisy chained matrix, but I have mine set up to where each of the 8 rows of LEDs goes to a different pin on my Teensy 3.2 controller (pins 4-11) and I have no idea how to get this (or any) rainbow effect working on it. I'm using the FastLED library and this is how I have the program set up to address individual pins as the different rows of LEDs:
#include "FastLED.h"
#define LED_TYPE PL9823
#define NUM_STRIPS 8
#define NUM_LEDS_PER_STRIP 64
#define NUM_LEDS NUM_LEDS_PER_STRIP * NUM_STRIPS

#define COLOR_ORDER GRB

uint8_t hue = 0;

CRGB leds[NUM_STRIPS * NUM_LEDS_PER_STRIP];
CRGB row_1[64];
CRGB row_2[64];
CRGB row_3[64];
CRGB row_4[64];
CRGB row_5[64];
CRGB row_6[64];
CRGB row_7[64];
CRGB row_8[64];

void setup() {
  FastLED.addLeds<PL9823, 4>(row_1, 0, NUM_LEDS_PER_STRIP);
  FastLED.addLeds<PL9823, 5>(row_2, 0, NUM_LEDS_PER_STRIP);
  FastLED.addLeds<PL9823, 6>(row_3, 0, NUM_LEDS_PER_STRIP);
  FastLED.addLeds<PL9823, 7>(row_4, 0, NUM_LEDS_PER_STRIP);
  FastLED.addLeds<PL9823, 8>(row_5, 0, NUM_LEDS_PER_STRIP);
  FastLED.addLeds<PL9823, 9>(row_6, 0, NUM_LEDS_PER_STRIP);
  FastLED.addLeds<PL9823, 10>(row_7, 0, NUM_LEDS_PER_STRIP);
  FastLED.addLeds<PL9823, 11>(row_8, 0, NUM_LEDS_PER_STRIP);

}

Does anyone know how I can make this setup run a spinning wheel of fading color values in the form of a spinning rainbow? I'm hoping to use suggestions as a place to start to build other patterns with and without rainbows as well and I'm a bit of a noob, so an explanation is appreciated.

why don't you start with basics and learn how to display a simple monochrome circle

why are you using a separate data pin for each row?

The display is set up as such that the rows cannot be daisy chained and all the inputs are on on side

Also, I am able to address individual LEDs on the matrix, set their color, and move them more or less by building frames one LED at a time.

that kind of setup is unlikely to have easy, built-in support with existing libraries, since all the animation call would be broken up 8 ways. can't you wrap the data lines around?

You're able to light any given pixel in any given colour, so am I correct in saying that what you want now is an algorithm to give you the rainbow effect? Could you confirm exactly what effect you are looking for? A star with different coloured lines coming out from the centre?


text:
Component with controllable resistance from Arduino?
I'm new to Arduino and building circuits, and was wondering if there is a type of component, or some other way to do the following task:
I want to control the resistance of a circuit from my computer linked to my Arduino, presumably using an output analog PIN.
Basically what I have is an LED whose brightness I want to control from my computer. I want to be able to control the resistance of the circuit to limit the electricity going to the LED, and I want to be able to do this from my computer (not physically, with a potentiometer) (unless a potentiometer's resistance can also be controlled from a PIN?).
How can I do this?

The easiest way to drive an LED with variable brightness is to use one of the pulse width modulation (PWM) output pins on an Arduino.
A PWM pin takes an input value from 0 to 255 (or is it 0/1023? I don't remember.) and converts it to a ratio of on-time to off-time. At the highest value, the output pin is in the on state, 100% of the time. At the halfway point, the output pin is HIGH 50% of the time, and LOW 50% of the time.
Our eyes average out the flashes and see a variable brightness. It works very well.
If you absolutely must have a variable resistance controlled by a digital value, there are devices known as digital potentiometers. These are variable resistors controlled by digital inputs. For an Arduino, you should think about an I2C or SPI potentiometer, which is controlled by serial port commands. You tell it the resistance you want, and it sets itself to that resistance.
As CrossRoads points out in their comment below, you still need a current limiting resistor to drive an LED from a logic pin, to protect both the LED and the output driver on the Arduino. You want to limit the current to the max current for your LED, and then use PWM to lower the brightness from the absolute max set by the current limiting resistor. CrossRoads explains how to calculate the resistor value.

I'll try all of this, thanks for the help!

See this example: https://www.arduino.cc/en/tutorial/fading

Cool, thankyou for that

A PWM pin takes an input value from 0 to 255.  (analogRead() returns 0-1023).  Don't forget a current limit resistor so you don't damage the IO pin, or the LED.  (5V - Vf)/.02A = resistor.  Say the LED has 2.5V across it when on (measure it, or read its data sheet), then (5V - 2.5V)/20mA = 125 ohm.  20mA with current LEDs will be really bright. 250 ohm or 270 ohm may be plenty bright for the max brightness.


text:
Correct Pins for Nodemcu 8266
I am building a small electronic project, and I am incorporating module nodeMcU 8266 in a box.
I would like to know which pins are for "flash" and for "reset"
I know there are 2 buttons on the module for those 2 actions, but I would like to add 2 external buttons for those function on the case of the project, like that I will not need to open the box everytime. I looked on the net, and I guess that for "reset", I must connect to pin "Rst" and pin "Grd", I mean those 2 pin must be shorted, but I prefere to get confirmation before to go further.
And also for the "flash", what are both pins that I must connect the external push button to, to replicate the button present on the module itself.
Also I would like to connect an external LED to the module, following the state of the blue SMD led.
The thing is that there is an SMD blue led on the module, I want to know what are the 2 pins that are similar to the contacts of the blue SMD led.
I want the External LED that I plan to incorporate to the case of the project, to light up when the SMD blue led on the module is on, and when the led to be off when the blue SMD led is off. I want that both follow the same state.
Blue SMD led "On" >>> external led "On"
and
Blue SMD led "Off" >>> external led "Off"
Sorry for the little confused explanation, and thanx in advance for any help and support.

What nodemcu version? There are several board revisions: v0.9, v1.0, v3

some info here https://circuit-diagramz.com/esp8266-12e-pinout-schematic-circuit-diagram/ ......... https://github.com/nodemcu/nodemcu-devkit-v1.0/blob/master/NODEMCU_DEVKIT_V1.0.PDF .............. https://www.esp8266.com/wiki/lib/exe/fetch.php?media=schematic_esp-12e.png

The v0.9 and v1.0 NodeMCU boards have 2 LEDs: One on the AIthinker module, and one on the actual NodeMCU board.
The AIthinker module's LED is connected between Vcc (3.3V) and GPIO2 (labeled D4 on nodeMCU). It turns ON when D4 is set LOW.
The NodeMCU LED is connected between Vcc (3.3V) and GPIO16 (labeled D0 on nodeMCU).  It turns ON when D0 is set LOW.
The pin labeled RST is the Reset signal from the AIthinker module, and is active-high, meaning you connect RST to GND to put the device in a reset state.
The pushutton labeled FLASH is connected between GND and GPIO0 (labeled D3 on nodeMCU). When the this pin is LOW when the ESP8266 comes out of a reset state, the chip is in flash-bootloader mode, meaning it is ready to receive a new sketch. On a NodeMCU, however, the ESP8266 chip is placed in flash mode by the USB chip and the flashing software, so there is not a need to manually press this button.

Thank for the reply and the great information.
I think I have the NodeMCU board, on its back side it is righted "NODEMCU Amica"
unfortunatly I could not get any info on the version.
so for the additional Reset switch I follow your instruction, and the point is resoved.
About the additional Flash button, I think I will go without it, as you instructred.

About the additional external LED,so I followed your instruction and added a LED between PIN D0 and GND. It is ON when the blue Led on the Board is off, and turns off when the Board's Led light up.
so or external LED or included LED board is on. Me I am looking that they follow the same state,
Included LED ON >>> external LED ON
I fund some line the the sketch that I am supposed to flash to the board, maybe iit has something to do with it. maybe somebody can take a look.
void setup() {
#ifdef USE_LED16
pinMode(16, OUTPUT);
digitalWrite(16, LOW);
#endif

To swap the on/off for your external LED: If the legs are between GND and IOPIN, then reverse LED (anode - cathode) and connect between VCC and IOPIN.

I do not find PIn IOPIN, I looked on the board, and also tryed the different picture I could find, like from this site:
https://circuit-diagramz.com/esp8266-12e-pinout-schematic-circuit-diagram/
I see there are different GPI, maybe you meant GPIO0, so writed Pin D1 on the Board itself?

I mean whatever I/O Pin you are controlling it with

After a few combination, it is working!!
Here what I did:
anode to 3.3V
and
catode to D4
my additional Led light up following the included Blue Led on the Board!!
Exactly what I was looking for!
Thanx a lot ;)


text:
HC-SR04 Echo Pin Fails To Go Low After Trigger Pulse
I have implemented an HC-SR04 distance sensor using an Arduino.  After power up, the sensor operates well when objects are within range of the sensor.  However, if the distance to be measured exceeds the maximum (about 15 feet) distance, the sensor times out (which is what I expect).  However, after a time-out and with the distance between the object and the sensor in range, the Echo pin fails to be set low after a trigger pulse is generated.  The only way to fix this condition is to power down the sensor and power it back up again.  (I have verified the state of the Echo pin by using an oscilloscope.)

Can you post your code?  I might have one kicking around to try this with.   I checked out a basic HC-SR04 hookup guide (https://dronebotworkshop.com/hc-sr04-ultrasonic-distance-sensor-arduino/) and it didn't mention this failure mode.  I'm wondering if the sensor is wonky.   Can you try their code, and see if you get the same effect?

After many hours of research, I discovered that the problem is related to the fact that there is (apparently) a well-known bug in the HC-SR04 which is a Chinese clone of a Devantech SRF04.  I replaced the HC-SR04 with an SRF04 and the problem was solved.  Now, the ECHO pin always goes low after a trigger and after a time-out (i.e. the object is beyond the maximum measurement distance).


text:
ESP - Nodemcu amica - attachInterrupt crash program
I get new boards from the shop but they are little different from the previous version. I got software what works ok on Nodemcu lolin v3 now I get Nodemcu Amica what is almost same board but if I got attachInterrupt function in the program it crashes immediately.
    attachInterrupt(6, bowlingCall, RISING);
//attachInterrupt(digitalPinToInterrupt(D1), statekCall, RISING);

I try different pins but not change. I debug all program(comment all out and left just attachInterrupt and it crashes again).
    ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v8b899c12
~ld

The board cycle in the reboot sequence, even serial output do not work ok. Why did esp crash at attachInterupt on this board?

https://github.com/esp8266/Arduino/issues/6142

thanks @Juraj.
Ok, so all you need is rewrite all your interrupt function.
For example:
void getStatusFromMaster()

to
void ICACHE_RAM_ATTR getStatusFromMaster()


text:
Getting weird characters from Arduino
My arduino is connected to ultrasonic sensor and I am trying to read the value from it. When I tried running "tail -f > /dev/ttyACM0" my arduino is sending some weird characters that I am not able to decode

Did you ssty?

What is that means? Can you explain?

In addition to the answers, be sure to "Serial.println(sensorValue, DEC)", to be sure it's printed decimally and not as individual incorrect ASCII characters

Have you looked at the data coming back in hex or binary? That might make it easier to see if the source is possibly using a different character set page in Unicode. The graphics symbols are not standard ASCII. I saw a mention of the source being Audi so it's possible the character set is a European one.

This other post looks similiar: (https://arduino.stackexchange.com/questions/12617/arduino-serial-monitor-shows-strange-ascii-characters?rq=1) and I have to ask if you have any documentation or reference on the sensor. It's just as likely to be sending data in binary, do you have any reason to suspect that it should be ASCII values?

It would seem you failed to configure the port on the Linux side. By
default, it is configured to who-knows-what baud rate, and to a “cooked”
mode where the data is preprocessed by the kernel driver. You want
instead to set it to the correct baud rate and to “raw” mode. The stty
(meaning, “set terminal”) command does this:
stty -F /dev/ttyACM0 raw 9600

Replace 9600 with whatever baud rate your Arduino is using.
If you Arduino program attempts to read the serial port, it will see the
echo of the characters it sends. In that case you probably want to
disable this echo also:
stty -F /dev/ttyACM0 raw -echo 9600

I have done this with the right baudrate but no change in the output

@SanthoshkumarSundararaj: There may be something wrong with the sending code. Try to replace it with something trivial, like void setup(){Serial.begin(9600);} void loop(){Serial.println("Hello!");}.

Unfortunately I cant change the code. I am working with AUDI autonomous car. So it has four arduino micro connected with 5 ultrasonic sensors. My task is to establish the connection and get the values from arduino.

Most likely this is incorrect baud rate. You can try with a program dedicated to serial ports, my personal choice is picocom but it can by minicom or any other:
$ picocom -b 9600 /dev/ttyACM0

The -b parameter is used for specifying the baud rate, depending on the sketch it can be something else than 9600, the most common ones are: 9600, 14400, 19200, 28800, 38400, 57600
Another solution is to configure the /dev/ttyACM0 with correct baud rate using stty:
stty -F /dev/ttyACM0 9600 cs8 -cstopb -parenb

This will configure the serial port to 9600 bps, 8 bits, 1 stop bit, no parity, and allow the tail command to read it correctly, if the communication parameters match what the arduino is sending

I have tried both but still it is giving the same strange characters


text:
EEPROM Esp8266 Memory Issue
I had assembled a board with esp8266ex bare chip with 4MB eeprom for esp and also can be shared with host MCU. I had gone through some googling and found that using eeprom function I am able to write data in eeprom using esp8266ex. But I had seen the limitation of 4KB. Then I had researched more than I found that there is a way to increase that.
So my question is, Is there are any issue if I changed that 4KB to 2 MB or more in esp8266 library?
I am using arduino IDE for Esp programming.

eeprom or flash? only 4kB can be used for EEPROM emulation in esp8266 flash memory layout

flash. I am asking if what will happen if I increase the 4KB to 2MB.

use SPIFFS file system. it can use to 3MB of 4MB. https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html

I tried the spiffs, every time it shows unable to find file, but the file path is right and even the file name.

try more. try the examples. it works.

ok I will check tomorrow for another example for spiffs.

the basic example is called ConfigFile and FSBrowser is a complex example

Actually I tried the basic example in which it will go to the directory, open the file and try to print the file data on serial monitor. But I always for the result as Unable to open the file.

yes. the example is wrong. it expects the SPIFFS initialized. read the doc on the link few comments above


text:
ESP8266 Connection with WPA2-PEAP Enterprise Network
I am trying to connect my nodemcu 12E module to WPA2-entrprise network but not able to connect.
I had gone through the Espressif Forum and GitHub but still not able to resolve my problem.
here is the code I am using
#include<ESP8266WiFi.h>
#include<EEPROM.h>
extern "C" {
#include "user_interface.h"

#include "wpa2_enterprise.h"
#include "c_types.h"
}

// SSID to connect to
char ssid[] = "TEST";
char wlpasswd[] = "";
char username[] = "test@test.local";
char password[] = "test1234";

#define addr_username 0x0000
#define addr_password 0x007F
#define addr_certificate 0x00FF

unsigned char ca_cert[] = {
  0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
  0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x31, 0x37, 0x61, 0x61,
  0x31, 0x33, 0x62, 0x62, 0x37, 0x31, 0x33, 0x61, 0x37, 0x62, 0x34, 0x36, 0x66, 0x39, 0x66, 0x63,
  0x61, 0x37, 0x64, 0x62, 0x61, 0x31, 0x30, 0x32, 0x61, 0x33, 0x35, 0x63, 0x65, 0x33, 0x36, 0x38,
  0x31, 0x39, 0x31, 0x33, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45,
  0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x00,
};

void setup() {

  WiFi.mode(WIFI_STA);
  Serial.begin(115200);
  delay(1000);
  Serial.setDebugOutput(true);
  Serial.printf("SDK version: %s\n", system_get_sdk_version());
  Serial.printf("Free Heap: %4d\n",ESP.getFreeHeap());

  // Setting ESP into STATION mode only (no AP mode or dual mode)

  // Clean up to be sure no old data is still inside
  wifi_station_clear_cert_key();
  wifi_station_clear_enterprise_ca_cert();
  wifi_station_set_wpa2_enterprise_auth(1);

  wifi_station_set_enterprise_username((uint8*)username, strlen(username));
  wifi_station_set_enterprise_password((uint8*)password, strlen((char*)password));
  wifi_station_set_enterprise_ca_cert(ca_cert, sizeof(ca_cert));

  WiFi.begin(ssid);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");

    delay(100);
  }

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

void loop() {

}

Here are the logs I am getting
SDK version: 2.2.2-dev(38a443e)
Free Heap: 47672
WPA2 ENTERPRISE VERSION: [v2.0] enable
scandone
.............................scandone
state: 0 -> 2 (b0)
.state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1
cnt
...................................................................................................pm open,type:2 0
........................................................................................................................................................................................................state: 5 -> 0 (2)
rm 0
pm close 7
reconnect
.scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
.state: 3 -> 5 (10)
add 0
aid 1
cnt
...................................................................................................pm open,type:2 0
........................................................................................................................................................................................................state: 5 -> 0 (2)
rm 0
pm close 7
reconnect
.scandone
state: 0 -> 2 (b0)
.state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1
cnt
...................................................................................................pm open,type:2 0
........................................................................................................................................................................................................state: 5 -> 0 (2)
rm 0
pm close 7
reconnect
.scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1
cnt
....................................................................................................pm open,type:2 0
........................................................................................................................................................................................................state: 5 -> 0 (2)
rm 0
pm close 7
reconnect
.scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1
cnt
....................................................................................................pm open,type:2 0
........................................................................................................................................................................................................state: 5 -> 0 (2)

Any help in this?


text:
Is there an Arduino library that uses ARP to get list of connected devices on network?
I have been looking for a library that can execute an ARP (Address Resolution Protocol) command to return a list of connected devices on the network. The idea is that it would send the request to the gateway and get a list of MAC addresses of currently connected devices as a sort of "who's home" request.
I have searched around Arduino's libraries and have not found any that specifically perform this type of functionality so I was hoping that maybe it was available in a function within a broader networking library.
The particular networking interface (wifi via ESP8266/ESP32 or Ethernet) does not matter as I have not chosen a specific board for the job yet. I'm interested in any library solution that would allow me to poll the gateway to see which devices are currently online without having to buy a special device like FingBox.
Any recommendations for a library that includes this functionality or an approach that would allow me to send ARP commands over the network?

the way i do this is by looping from 0 to 255 and scanning each local IP.

@dandavis, I feel like that's what the DOS arp command and apps like Fing do as well. I'm thinking something like WiFi.ping()

ARP isn't generally used the way you described. Per the spec, to resolve an IP address into a MAC address, you broadcast an ARP request for the IP address, and receive  a unicast response from the host whose address it is - not a router. It also only resolves a single IP address in one request; it doesn't return the contents of the entire ARP cache.
While you could potentially unicast ARP requests to a router, it's anybody's guess as to whether the router would respond - it's not required to. By spec only the computer who's IP address is being queried should respond - so a router should not unless you've sent it an ARP request for its IP address. You'd also have to send one request for each IP address in the range specified by the LAN's network mask.
You're better off using SNMP, if the router supports it. SNMP can read the router's entire ARP cache with very little overhead (and very few packet exchanges).
The are SNMP implementations for the ESP32 and ESP8266, but they're likely to be difficult to use. Googling will find them for you.

Thanks, I'll take a look for SNMP libraries. I thought ARP was the name of the protocol that returns the routing tables as that is the DOS command that returns the list of connected devices. MAC addressing would be most useful as device IPs are generally subject to change.

It is the name of that command, but what it returns isn't a routing table, it's the MAC address translation table of the computer you run it  on, not the router. The protocol is different from the command.

I was searching for the same function but I think you don't need to query the gateway.
My idea is to loop through all the valid ip addresses, send a ping to each one (it does not matter if they don't answer the ping), and we should have the MAC for this ip. Then check if this MAC is in a list saved in some non volatile space (may be an sd card) and if it's not in the "known peers" list, add it and send a message warning about a new device added to the network.
Using the MAC address instead of the ip for identifying the devices should avoid problems with dynamic ips recognized as new.