text:
SPI synchronization with Arduino DUE and ADIS16364 IMU
I'm trying to use an Arduino Due to interface with an ADIS16364 IMU from Analog Devices (product info here) via SPI.
There are two modes for retrieving the measurements from this particular IMU (six 16 bit values, 3 acc, 3 gyros):

The first mode is, if I'm not wrong, the standard one with SPI, in which each successive transfer command retrieves the last data requested and indicates which one should be retrieved next.

The second possibility is a so called "burst mode". For this one you have to request the 0x3E00 register. After that, the IMU will burst out the six measurements (plus a few other bits of information like temperature and supply voltage). From the specs sheet:

The problem is, I can not manage to make the Arduino read the data using this burst mode. This is the code I'm using to test the communication:
#include <SPI.h>
#define SerialBT Serial2

short supply, xgyro, ygyro, zgyro, xacc, yacc, zacc, xtemp, ytemp, ztemp, aux;
volatile byte fDataIMUtoRead = 0;
int pauseBetweenTransfers;

void setup() {

  SerialBT.begin(230400);

  pinMode(52, OUTPUT);

  // Configure SPI
  SPI.begin(52);
  SPI.setClockDivider(52, 200); // 84e6/200 = 420kHz
  SPI.setDataMode(52, SPI_MODE3);
  SPI.setBitOrder(52, MSBFIRST);

  // Set sample rate
  float Fs = 1; // Target sampling frequency [Hz]
  float tb = 0.61035 * (Fs >= 12.7009) + 18.921 * (Fs < 12.7009);
  unsigned long tbsel = 0 * (Fs >= 12.7009) + 1 * (Fs < 12.7009);
  unsigned long Ns = (uint16_t) round((1000.0 - tb * Fs) / (tb * Fs));
  float Feff = 1000 / (tb * (Ns + 1));
  SerialBT.print("Selected freq: ");
  SerialBT.println(Feff, DEC);

  digitalWrite(52, LOW);  // Doesn't seem to be necessary
  SPI.transfer16(52, (0L << 15) | (0x36L << 8));                       delayMicroseconds(100);
  SPI.transfer16(52, (1L << 15) | (0x36L << 8) | (tbsel << 7) | Ns );  delayMicroseconds(100);
  SPI.transfer16(52, (0L << 15) | (0x36L << 8));                       delayMicroseconds(100);
  zgyro = SPI.transfer16(52, 0x00);
  digitalWrite(52, HIGH);

  SerialBT.print("SMPL_PRD = ");
  SerialBT.println(zgyro, HEX);

  attachInterrupt(3, availableIMUData, RISING);
}

void loop() {

if (fDataIMUtoRead) {

SerialBT.print("Loop... ");

// Read values (standard mode)
pauseBetweenTransfers = 100;
digitalWrite(52, LOW); // Doesn't seem to be necessary

        SPI.transfer16(52, 0x0400, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
xgyro  = SPI.transfer16(52, 0x0600, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
ygyro  = SPI.transfer16(52, 0x0800, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
zgyro  = SPI.transfer16(52, 0x0A00, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
xacc   = SPI.transfer16(52, 0x0C00, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
yacc   = SPI.transfer16(52, 0x0E00, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
zacc   = SPI.transfer16(52, 0x0000, SPI_CONTINUE);

digitalWrite(SS, HIGH);

/*
// Read values (burst mode)
pauseBetweenTransfers = 5;
digitalWrite(52, LOW);    // Doesn't seem to be necessary

         SPI.transfer16(52, 0x3E00);    delayMicroseconds(pauseBetweenTransfers);  // Request data burst
supply = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
xgyro  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
ygyro  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
zgyro  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
xacc   = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
yacc   = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
zacc   = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
xtemp  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
ytemp  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
ztemp  = SPI.transfer16(52, 0x0000);

digitalWrite(52, HIGH);
*/

SerialBT.println(zgyro, DEC); // Print the reading

fDataIMUtoRead = 0; // Reser the "there is new data"-flag

}

}
void availableIMUData() {
fDataIMUtoRead = 1; // Set the "there is new data"-flag
}
The standard way to communicate seems to work without any problem, provided that I set the right delays after each transfer16 command. But I'm not able to make the Arduino read the data in burst mode (commented in the code above).
So does anybody have any ideas on how to make the Arduino retrieve the readings in this burst mode? I understand this is a tricky unless you have (had) access to the same hardware, but any suggestion will be welcome.
Thanks a lot.

You seem to be correct about everything said, so far as I can tell.  I would put a scope on the signals and make sure they look okay.

Thanks timemage. Unfortunately I have no scope. Only a cheap logic analayzer, which wasn't of much help

First of all, this may not related to your question, but you are using old SPI methods setClockDivider(), setDataMode(), and setBitOrder() that has been deprecated since 2014. It is recommend to use use transactional SPI APIs which I have some explanation here.

Why I actually need those delays?

If you read page 6 of ADIS16364 datasheet, there is a tSTALL time between each data transmission that could be as long as 75uS (when operating on Low Power mode), this value can be much lower if you operate on Normal or Bust mode.

why this combination of delays with the 200 clock divider?

The clock divide set the clock used for the SPI SCLK rate, for Due a clock divide of 200 means 84,000,000 / 200 = 420,000Hz, Why this rate? again, you have to look into datasheet, on page 6 table 2, max fsck is 2MHz for Normal mode, and 1MHz for Bust mode, and only 300kHz at Low Power mode.

Shouldn't this be done automatically by the SPI library?

This is a wrong perception, SPI library do nothing than handling the communication. All the timing requirements are component/chip specific, and therefore if you want to communicate with the chip at SPI communication level, you will have to deal with all the timing requirements yourself. Most of the people in the Arduino community get used of using some pre-written library which was written by someone who care to read the datasheet and provide high level abstract API so that users don't need to deal with all the timing.

Any ideas on how to make the Arduino retrieve the readings in this burst mode?

Update
As suggested by the datasheet, "To start a burst read sequence, set DIN = 0x3E00", what this means is that you need to WRITE into the register 0x3E00 first to setup the burst mode. Fig 11. of the datasheet indicate that a WRITE operation would have a set most significant bit to 1, so you will need to send 0x3E00 | 0x8000 or 0xAE00 for writing into register 0x3E00. What you did is basically reading form 0x3E00, not writing into 0x3E00.
I re-read the datasheet and you are right, it should be okay to just send out 0x3E00. I never use an Arduino Due before, but I realised that the SPI.transfer16() might send out the 0x00 first instead of 0x3E. I modified the code to send out two bytes 0x3E and 0x00 separately using SPI.transfer()
I don't have the IMU, but I think the follow code should works for bust mode:
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));    //initialises SPI clock speed, mode and bit order
digitalWrite(SS, LOW);              // adjust this as per your chip select pin
SPI.transfer(0x3E);
SPI.transfer(0x00);
delayMicroseconds(1);               //bust mode only 1uS required as per datasheet
xgyro_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
ygyro_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
zgyro_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
xaccl_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
yaccl_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
zaccl_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
data16    = SPI.transfer16(0x0000);
delayMicroseconds(1);
data16    = SPI.transfer16(0x0000);
delayMicroseconds(1);
data16    = SPI.transfer16(0x0000);
delayMicroseconds(1);
data16    = SPI.transfer16(0x0000);
delayMicroseconds(1);
digitalWrite(SS, HIGH);   // deselect slave
SPI.endTransaction();

Thanks for you detailed reply, hcheung.
Your indication to WRITE to the 0x3e00 seemed to be the key, but it didn't solve the problem. After checking the specs sheet again, on page 12, end of first paragraph of the second column: "Reading the GLOB_CMD register (DIN = 0x3E00) starts the burst read sequence." So SPI.transfer16(0x3E00) should actually do the job, if I get it right.
Any other ideas?

I use the old syntax for SPI communication because I just wasn't able to make the new SPI.beginTransaction command work. No idea what I'm doing wrong. The old one seems to be working fine, though (unless you see any reason this should be preventing the burst mode to work)

I just discovered yesterday that with sample rates as high as 150 Hz the IMU still works in low-power mode, which explains the high delays needed, as you suggest.

You are right, it should be okay to just send a read cmd to 0x3E00. Please see my update answer and also the change of the code to send  out two bytes (0x3E, 0x00) separately. Please try, I think it should work.

The old APIs still work even though it is deprecated as long as your SPI bus do not have multiple SPI devices on it. The SPI.begintransaction is designed to allow multiple devices to operate with each has its own configuration settings.

I don't think you need to change the order of the two bytes, hcheung. I've tried, just in case, but it didn't have any effect. Reading in standard mode works fine with lines like {SPI.transfer16(52, 0x0A00, SPI_CONTINUE)}

I've edited the main question with the complete code I'm using for testing, with both standard and burst modes, just in case you can see anything wrong there.


text:
Arduino 5v pin outputting lower power than expected
I have hooked the pin v5 of an Arduino Nano 33 BLE to the A0 pin and measured the value by doing Serial.println(analogRead(A0));. I would expect to see 1023 however instead I see the value oscillating around 810.
Any ideas why I am not getting 1023?
P.S.: I am powering the Arduino board through the USB connector.

You should probably stop doing that until you have an answer.

use a voltmeter

it is not lower power ... it is lower voltage ... the two are not the same thing

I hope you didn't  solder the 5 V pin pads on the bottom side of the board. the 5 V pins is not connected to not make 5 V circuits just like you did. because the input pins on this board are for 3.3 V max. https://www.arduino.cc/en/Guide/NANO33BLE#please-read

@Juraj I have soldered the 5v pin, because my sensors both require 5v. I have a Beetle Bluno BLE board that outputs 5v, I don't really understand the limitation. How am I supposed to power the sensors, with an extra external 5v power source?

and why do you wire 5 V to A0?

Because I don't have a voltmeter, so that was the only way for me to see what value was coming out from the 5v pin

With a divider it should be an okay way to measure.  If you connect A0 to your 3.3V pin, do you not see 1023 (or so) then?

Yes I see around 1023 if I connect A0 to my 3.3V pin

Well, that's the last thing I could think to ask that could disconfirm what I think is going on.  If I think of anything else, I'll ask.

Well, I thought by now someone else would have answered it.  But, I'll try.  I'm not familiar with this chip and board, so what I can tell you is pretty limited.
In short, you have a 3.3V micro-controller and generally speaking you don't hook 5V signals to them.  There are some 3.3V parts that have "5V tolerant" inputs, but that only makes sense for digital inputs so far as I know.
Barring anything unpleasant happening, the behaviour I would expect to see with hooking 5V to the input of a 3.3V ADC is that it would clip at the high end value.  So yeah, for 10-bit resolution, which appears to be the default for the Nano 33 BLE and with VDD as the reference, which also appears to be the default, I would expect to see a value at or near 1023.  Up until the point that you fry something that is.
I don't know why you're seeing lower values, but since you seem to be operating it out of specifications, I'm not sure that really matters why.  If you want to measure 5V with your 3.3V max ADC, you should involve a voltage divider.

the 5 V pin is not connected from factory on this board

Again, I don't know what you're talking about.  If you have an answer, post it as an answer.

https://www.arduino.cc/en/Guide/NANO33BLE#please-read

It's nice that they have an official warning about it.  The O.P. seems to remain unconvinced, for what reason I don't know.

source: Stack Exchange

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

sort: votes


text:
ESP8266 Arduino Json object array deserialisation into struct
I'm trying to de serialize an array of JSON objects into a struct.
Following the instructions given by the Arduino JSON assistant, I managed to produce this helper function:
void JsonPreprocessor(const char* buf)
{
  StaticJsonDocument<96> filter;

  JsonObject filter_ResponseData_Metros_0 = filter["ResponseData"]["Metros"].createNestedObject();
  filter_ResponseData_Metros_0["Destination"] = true;
  filter_ResponseData_Metros_0["ExpectedDateTime"] = true;
  filter_ResponseData_Metros_0["Deviations"] = true;

  StaticJsonDocument<512> doc;

  DeserializationError error = deserializeJson(doc, buf, DeserializationOption::Filter(filter));

  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }

  JsonArray ResponseData_Metros = doc["ResponseData"]["Metros"];
  for (int i = 0; i < MAX_ELEMENTS; i++)
  {
    strcpy(dep_arr[i].destination, ResponseData_Metros[i]["Destination"]);
    strcpy(dep_arr[i].destination, ResponseData_Metros[i]["ExpectedDateTime"]);
  }
}

The function writes into an array of structs declared like this:
struct Departure {
   char* destination;
   char* departure;
   int  deviation;
} depart;

struct Departure dep_arr[MAX_ELEMENTS];

And the JSON passed as a constant character array to the preprocessor function. Uploading and running this function keeps crashing my ESP8266 without any debug output. Without posting the whole json object, which is long enough as is without the filters, My object array in JSON looks similar to this after filtering:
{
  "ResponseData": {
    "Metros": [
      {
        "Destination": "Destination_1",
        "ExpectedDateTime": "2021-04-29T05:15:30",
        "Deviations": 1
      },
      {
        "Destination": "Destination_2",
        "ExpectedDateTime": "2021-04-29T05:21:30"
      },
      {
        "Destination": "Destination_2",
        "ExpectedDateTime": "2021-04-29T05:30:30"
      },
      {
        "Destination": "Destination_1",
        "ExpectedDateTime": "2021-04-29T05:36:30"
      },
      etc...
    ]
  }
}

In my test code I've defined my MAX_ELEMENTS macro to be 3.
I'm at a complete loss due to not having any debug output. I'm using ArduinoJson6 and my code is written and compiled on Arduino IDE 2.0.0-beta.5

No memory is allocated for the strings.
You should declare your struct like so:
struct Departure {
   char destination[32];
   char departure[32];
   int  deviation;
} depart;

This assumes the max length for both strings is 31 characters.
Then, pass the max size to strlcpy():
strlcpy(dep_arr[i].destination, ResponseData_Metros[i]["Destination"], 32);
strlcpy(dep_arr[i].destination, ResponseData_Metros[i]["ExpectedDateTime"], 32);

If your strings are very long, you can use a String instead of char[].
See the example JsonConfigFile.ino, it shows all of this.

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


text:
Reading Multiple Analog Input Pins
I am having a bit of trouble trying to read multiple Analog Input Pins (A0 and A3, in this instance). I am using a Pololu A-Star 32U4 LV Robot Controller (https://www.pololu.com/product/3116), and am using the Arduino IDE to program the board; it is recognized as a Arduino Leonardo. I am using the Joystick Library (https://github.com/MHeironimus/ArduinoJoystickLibrary/tree/version-2.0) to have the controller be recognized by Windows as a Game Pad (irrelevant to the issue I am seeing, I believe).
I am simulating an Axis by using a potentiometer, with the data line running into the Analog Input, the 5V baseline coming from the board, and the Ground on the opposite of the Analog Input. This does indeed cause the values to change.
The issue that I am specifically running into is when I attempt to get the analog value for each pin that I am monitoring, it appears that the values of the other pins change at the same time. Because I am trying to use the Analog Pin values to drive an X/Y Axis, this issue manifests itself in an X/Y graph that appears linear with some sort of defined slope (with an X change leading to a Y change); rather than the expected X Horizontal only movement and Y Vertical only movement.
Further.. when I remove the second Axis (ie. only using X or only using Y), it appears to track as I expect, with the Pot moving the axis (changing the value of the Analog Input).
Here is where I check the pins in the loop:
      // Read the Analog Pins and update the controller
      for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
        checkAnalogAxisState(a, axisPins, axisPinVals);
        delay(10);
      }

And here is where I attempt to send the X/Y Axis changes based off of the readings coming from the Analog Pins:
    // Checks the Analog Pin for a value to be used as the Axis value. Only updates the state if it
    // has been found to have changed. Will update the Joystick Axis based on which pin it is currently
    // looking at
    void checkAnalogAxisState(uint8_t pinIndex, uint8_t analogPins[], int analogPinVals[]) {
        uint8_t analogPin = analogPins[pinIndex];

        // The trick when using multiple analog sensors is to read them twice, with a small delay after each read (10ms is good)
        // then discard the first reading. This is because the ADC multiplexer needs switching time and the voltage needs
        // time to stabilize after switching.
        int currentState = analogRead(analogPin);
        delay(10);
        currentState = analogRead(analogPin);
        delay(10);

        if(currentState <= analogPinVals[pinIndex] - 5 || currentState >= analogPinVals[pinIndex] + 5) {
            if(analogPin == X_AXIS_PIN) {
                Joystick.setXAxis(currentState - ANALOG_ADJUSTMENT);
            } else if(analogPin == Y_AXIS_PIN) {
                Joystick.setYAxis(currentState - ANALOG_ADJUSTMENT);
            }
            analogPinVals[pinIndex] = currentState;
        }
    }

I try to keep the Pin and the Value of that pin in an array, but even when I do this with 2 separate variable and function calls, I still see that the Analog values change at the same time.
Here is the full sketch, I can include the full contents of ControllerDefines.h and ControllerFunctions.h if they will be helpful, but I have pulled the relevant functions from each:
    #include <AStar32U4.h>
    #include <Joystick.h>
    #include "libraries/ControllerDefines.h"
    #include "libraries/ControllerFunctions.h"

    void setup() {
      // Setup pins for the Axis controls
      for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
        pinMode(axisPins[a], INPUT);
      }

      // Setup Joystick
      Joystick.begin();
      Joystick.setXAxisRange(-ANALOG_ADJUSTMENT, ANALOG_ADJUSTMENT);
      Joystick.setYAxisRange(-ANALOG_ADJUSTMENT, ANALOG_ADJUSTMENT);

      // Setup Serial Comm
      Serial.begin(9600);
    }

    void loop() {
      // Read all button states and update the controller
      for(uint8_t b = 0; b < TOTAL_BUTTONS; b++) {
        checkButtonState(b, buttons, buttonStates);
      }

      // Read the Analog Pins and update the controller
      for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
        checkAnalogAxisState(a, axisPins, axisPinVals);
        delay(10);
      }

      // Delay before polling buttons again
      delay(50);
    }

Edit:
I have taken a plot of the 2 Array values over time, as can be seen here. This is with the Pot hooked up to A3, which is axisPinVals[0]:

Moving the Pot to A0 gives the following:

Using the modified code below:
      // Read the Analog Pins and update the controller
      for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
        checkAnalogAxisState(a, axisPins, axisPinVals);
        delay(10);
      }

      // For the plotter
      Serial.print(axisPinVals[0]);
      Serial.print(",");
      Serial.println(axisPinVals[1]);

As you can see, the two values track together. This same behavior is not present in the buttons presses, and multiple buttons can be held at the same time with no issue.
I would expect each variable (line) to track independently of one another, when the Pot is moved from A0 to A3.

Just to clarify, do you have two pots connected while testing? If not, you are reading "floating" input which will not give valid results.

I think you're on to the issue, will figure out definitively tomorrow

I can't reproduce your problem. Your code is a bit lengthy to say for certain whether or not A0 and A3 clash when read in quick succession. Try this test code and see what results you get:
void setup() {
 Serial.begin (115200);
 while (!Serial) {}  // wait for Serial

 Serial.println ("Starting");
}

void loop() {

int a, b;

  a = analogRead (0);
  b = analogRead (3);

  Serial.print ("A0 = ");
  Serial.println (a);
  Serial.print ("A3 = ");
  Serial.println (b);
  delay (100);
}

I found on my Micro (which has the same processor) that the two inputs were completely independent. For example changing A3:
A0 = 0
A3 = 195
A0 = 0
A3 = 453
A0 = 0
A3 = 680
A0 = 0
A3 = 879

And then changing A0:
A3 = 0
A0 = 64
A3 = 0
A0 = 292
A3 = 0
A0 = 427
A3 = 0
A0 = 474
A3 = 0
A0 = 294
A3 = 0
A0 = 48

This was with two potentiometers connected at all times. If you only had one you might get a "floating" input.
I suggest you try the code above and confirm whether or not you get similar results. If you do, then the problem is not "Reading Multiple Analog Input Pins" but something else entirely, like logic in your code.
Even when I changed the delay in my code to 10, the figures reported were still independent. That is, one pot did not influence the other at all.

This is what I expected to see, I'll give it a shot; could be how I have things setup or a problem with the board itself. Luckily, I have a couple Micros on the way as they better suit my project in the end.

Well, it's definitely the board. Running your code, both numbers still track each other, even when I have a single Pot changing the values. Thanks for the help and the test code. I'll accept this after a bit here.

You need to have a pot in each input at the same time for a valid test.

Your joystick would, of course, do that. Your problem might be that you are testing with a single pot, and such a test is not reproducing the live situation correctly.

Ah yeah I can give that a shot too, that would make too much sense actually. I'll try that out here tomorrow.

That was the issue; I was reading a floating pin.

Try reading each input twice in a row, and use the value from the 2nd read.  The input source may need additional time to charge up the sample & hold cap that is read by the ADC in the uC.

I encountered the same problem with arduino UNO and managed to find a solution.
It is necessary to reduce the sampling frequency of the ADC.
The sampling capacitor does not have time to charge or discharge if the source resistance is too high and the potential difference between the channels and the sampling frequency are high enough
I used a third party library for the ADC, which has the ability to configure analogPrescaler and set polling frequency to 125 kHz

Can you tell us what "third party library" you used?


text:
Obtaining wrong analog readings using the ESP32 devkitc v4
I know that the topic is not related to Arduino, but I am completely sure that someone can help me find the problem.
I am testing 6 temperature sensors, (3 digital, 3 analog). The digital ones are "DS18B20" which I trust, the analog ones are "MCP9701A", "TC1047A" and "MCP9700A".
By reading the analog sensors using Arduino Uno or Arduino Mega, the results of the 6 sensors are almost identical and I don't face any problem. But when make the test using the ESP32-devkitc-v4, I obtain wrong reading from the 3 analog sensors. In the code "serial monitor", I obtain a voltage value completely different from the one I measure physically by a multi-meter.
For example:
The 3 digital sensors a giving the value of 23.56C to 23.81C but for the "MCP9701A" analog sensor I obtain 16.26C and the voltage obtain in the serial monitor is 0.718 volts, however it is 0.851 volts by the multi-meter. And according to the calculations from the data-sheet: (0.851-0.4)/(19.5mVolts)= 23.12C which is so close to the digital sensors. I have the same problem with the other analog sensors, so if you can help me find my error, I will appreciate it.
Here are the data-sheets of the analog sensors:
MCP9701A and MCP9711A
https://ww1.microchip.com/downloads/en/DeviceDoc/20001942G.pdf
TC1047A
https://ww1.microchip.com/downloads/en/DeviceDoc/21498D.pdf
Here is my code:
#include <OneWire.h>
#include <DallasTemperature.h>
#include "driver/adc.h"

// GPIO where the DS18B20 is connected to
const int oneWireBus = 4;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);

// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);

#define analogInPin0 35
#define analogInPin1 32
#define analogInPin2 33

float analogTempTC1047=0.0;
float analogTempMCP9700=0.0;
float analogTempMCP9701=0.0;

float volt0=0.0;
float volt1=0.0;
float volt2=0.0;

int sensorValue0 = 0;
int sensorValue1 = 0;
int sensorValue2 = 0;

void setup() {
  // Start the Serial Monitor
  Serial.begin(9600);
  // Start the DS18B20 sensor
  sensors.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
  sensorValue0 = analogRead(analogInPin0);
  sensorValue1 = analogRead(analogInPin1);
  sensorValue2 = analogRead(analogInPin2);

  volt0= (3.3/4096.0)*sensorValue0;
  analogTempMCP9701= ((volt0-0.4)/0.0195);

  volt1= (3.3/4096.0)*sensorValue1;
  analogTempTC1047= ((volt1-0.5)/0.01);

  volt2= (3.3/4096.0)*sensorValue2;
  analogTempMCP9700= ((volt2-0.5)/0.01);

  sensors.requestTemperatures();
  float temperatureC1 = sensors.getTempCByIndex(0);
  float temperatureC2 = sensors.getTempCByIndex(1);
  float temperatureC3 = sensors.getTempCByIndex(2);
  Serial.print("S1= ");
  Serial.print(temperatureC1);
  Serial.print("ºC");
  Serial.print(", S2= ");
  Serial.print(temperatureC2);
  Serial.print("ºC");
  Serial.print(", S3= ");
  Serial.print(temperatureC3);
  Serial.print("ºC,------- ");

  Serial.print("input sensor1= ");
  Serial.print(sensorValue0);
  Serial.print(", volt1=  ");
  Serial.print("= ");
  Serial.print(volt0, 3);
  Serial.print(", Analog sensor MCP9701 = ");
  Serial.print(analogTempMCP9701);

  Serial.print("----");
  Serial.print("input sensor2= ");
  Serial.print(sensorValue1);
  Serial.print(", volt2=  ");
  Serial.print("= ");
  Serial.print(volt1, 3);
  Serial.print(" --Analog sensor TC1047 = ");
  Serial.print(analogTempTC1047);

  Serial.print("----");
  Serial.print("input sensor3= ");
  Serial.print(sensorValue2);
  Serial.print(", volt2=  ");
  Serial.print("= ");
  Serial.print(volt2, 3);
  Serial.print(" --Analog sensor MCP9700 = ");
  Serial.println(analogTempMCP9700);
  delay(4000);
}

And here is the serial monitor output:
S1= 23.56ºC, S2= 23.81ºC, S3= 23.50ºC,------- input sensor1= 895, volt1=  = 0.721, Analog sensor MCP9701 = 16.47----input sensor2= 747, volt2=  = 0.602 --Analog sensor TC1047 = 10.18----input sensor3= 752, volt2=  = 0.606 --Analog sensor MCP9700 = 10.59
S1= 23.56ºC, S2= 23.75ºC, S3= 23.50ºC,------- input sensor1= 894, volt1=  = 0.720, Analog sensor MCP9701 = 16.42----input sensor2= 747, volt2=  = 0.602 --Analog sensor TC1047 = 10.18----input sensor3= 755, volt2=  = 0.608 --Analog sensor MCP9700 = 10.83
S1= 23.56ºC, S2= 23.75ºC, S3= 23.50ºC,------- input sensor1= 905, volt1=  = 0.729, Analog sensor MCP9701 = 16.88----input sensor2= 746, volt2=  = 0.601 --Analog sensor TC1047 = 10.10----input sensor3= 753, volt2=  = 0.607 --Analog sensor MCP9700 = 10.67

see if your 4095 code is really 3.3v and not 3.15v or something. Keep in mind that the shoulders and toes of esp32 adcs are a little sluggish too. 0.851v / (895/4095) is 3.89v, so something is off on the ceiling

Not a full answer, only a direction to consider:
The ESP32 ADC seems to be shipped with a ADC calibration tolerance of ±6%, as stated in the ESP32 datasheet, chapter 4.1.2. Here are the calibration docs.
It seems like you're still off by more than those 6% (didn't calculate it through). Maybe your power supply is a bit weak, pulling the internal reference voltage down?


text:
Keypad as game input device?
I have been trying to get a button matrix to work but im not experienced enough in programming.
I Have tried to read up but i don't know how to execute so some help would be greatly appreciated.
I want the keypad to function as a game controller of sorts. when i pres the 1 key on the keypad i want the read light to light up and only go out when i release the button. code was copied from "mstanley" on arduino forum.
Q: How do i use the Keypad.h library to get my keypad press to run one line of code when i press a button and another line when i release the button.
I Was testing with leds now, the code is identical, digitalWrite(1, HIGH); then digitalWrite(1, LOW); this can easily get exchanged for joystic.PressButton 1 and Joystick.ReleaseButton 1

#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {9,8,7,6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5,4,3,2}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

char holdKey;
unsigned long t_hold;

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

  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
}

void loop(){
  char key = keypad.getKey();

   if (key){
     holdKey = key;
     Serial.println(key);
   }

   if (keypad.getState() == HOLD) {
      if ((millis() - t_hold) > 100 ) {
          switch (holdKey) {
              case '1':
                  digitalWrite(11, HIGH);
                  delay(200);
                  digitalWrite(11, LOW);
                  break;
              case '2':
                  digitalWrite(12, HIGH);
                  delay(200);
                  digitalWrite(12, LOW);
                  break;
              case '3':
                  digitalWrite(13, HIGH);
                  delay(200);
                  digitalWrite(13, LOW);
          }
          t_hold = millis();
      }
   }
}

What do you mean by "game input device"? Do you want to use it as gamepad for your PC? Or is this just about the LEDs?

I Was testing with leds now, the code is identical,
digitalWrite(1, HIGH); then digitalWrite(1, LOW); this can easily get exchanged for joystic.PressButton 1 and Joystick.releasebutton 1

do you have a question? ... it is unclear what problem you are having

sorry it was unclear. Q: How do i use the Keypad.h library to get my keypad press to run one line of code when i press a button and another line when i release the button.

I did a post about keypad handlers. I'm reluctant to mention it because we aren't supposed to post "link only" answers.
It refers to a library available on GitHub which handles keypads. In particular you can have a callback function for both the keydown and the keyup, for multiple keys.

How do i use the Keypad.h library to get my keypad press to run one line of code when i press a button and another line when i release the button.

That seems to be what you want to do.
Example code:
/*
 *
 * Example of using Keypad_Matrix with a 4x4 keypad matrix.
 *
 */

#include <Keypad_Matrix.h>

const byte ROWS = 4;
const byte COLS = 4;

// how the keypad has its keys laid out
const char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'},
};

const byte rowPins[ROWS] = {6, 7, 8, 9}; //connect to the row pinouts of the keypad
const byte colPins[COLS] = {2, 3, 4, 5}; //connect to the column pinouts of the keypad

  // Create the Keypad
Keypad_Matrix kpd = Keypad_Matrix( makeKeymap (keys), rowPins, colPins, ROWS, COLS );

void keyDown (const char which)
  {
  Serial.print (F("Key down: "));
  Serial.println (which);
  }

void setup()
{
  Serial.begin (115200);
  Serial.println ("Starting.");
  kpd.begin ();
  kpd.setKeyDownHandler (keyDown);
}

void loop()
{
  kpd.scan ();
  // do other stuff here
}

You can also use setKeyUpHandler to do another function when a key is released. You can also call isKeyDown to see if a key is down (eg. when pressing key A is key B also down?).
Note that (as mentioned in the linked post) you need to use diodes to stop having false (ghost) key presses if more than two keys are pressed at once.

Hi! Thank you for the answer!

How do i use the Keypad.h library to get my keypad press to run one
line of code when i press a button and another line when i release the
button

Edit 1:
void loop() {
  char key = keypad.getKey();

  if (key != NO_KEY) {
    Serial.println(key);
  }

  if (keypad.isPressed('*'))
  {
  randomr = random(10, 2000);
  Serial.println(randomr);
  }

}

From the link: https://playground.arduino.cc/Code/Keypad/ you can find all the functions supported by the Keypad library.
One relevant function is
KeyState getState()

It returns the current state of any of the keys.
The four states supported are IDLE, PRESSED, RELEASED, and HOLD.
Hence you can use this function for the keys you are interested in.
Also, if helpful consider this function as well.
setHoldTime(unsigned int time)

Set the number of milliseconds the user will have to hold a button until the HOLD state is triggered.

You can find the keypad.h library in action here. I motivate you to also try the code with this online Arduino emulator
you already have a builtin function defined to get the status of the key pressed
void loop() {
  char key = keypad.getKey();

  if (key != NO_KEY) {
    Serial.println(key);
  }
}

I have a poorly taken screenshot for the same for your quick reference.
Original Arduino emulator link: (you can play with the logic)

https://wokwi.com/playground/keypad

Disclosure: I use wokwi.com, to create interesting tools and libraries for the Arduino community
https://github.com/wokwi
for a more free demonstration of the libraries:
https://github.com/wokwi/arduino-libraries

Hi! Thank you for your answer. im aware och the KeyState getState() command but i do not understand how to implement it in code. i have not found an example that shows it doing what i'm after. in kombination wit the keyStateChanged() komand i feel like it should definitely be possible.

@OpticalOpal I will get back to you with an example


text:
About maximum length of matrix can be use for matrix invertsion on atmega32
what is the maximum length for matrix can be used for matrix inversion on atmega32,for example,can we implement matrix inversion for 15x15 matrix on atmega32? And if  it can be done on atmega32..does this will make the atmega32 to be slower?
I want to implement kalamn filter 15 states for euler angles estimation...the data of the matrix will be floating point..

This is not a very well defined question. Did you have a particular application in mind (so it can be optimized) or do you need a general matrix inversion algorithm? What do you mean by “would this make the ATMega32 slower”? No, the ATMega32 would remain just as fast. Your code might become slower, but that depends on question #1: what do you need this for?

What data type do you store in the matrix? How is the matrix defined? Please show us some code.

I want to implement kalamn filter 15 states for euler angles estimation...the data of the matrix will be floating point..

I want to implement kalamn filter 15 states for euler angles estimation...the data of the matrix will be floating point..

does this will make the atmega32 to be slower? - slower than what? It would certainly be slower than not inverting any matrices, of course.

Floats in the Arduino IDE are normally 4 bytes. So you can work out with a calculator that your matrix will take at least 15 x 15 x 4 bytes (900 bytes). That is out of a total of 2048 bytes of RAM on the Atmega32.
That may seem to be enough RAM, but other things, like the libraries, will also take RAM. I did an answer to a question about RAM a while back. Even a very simple sketch (in this case) took 346 bytes.
Also, your library, or whatever-it-is you are using for matrix inversion, may require RAM for variables, etc.
My suggestion would be to make your code invert a very small matrix (eg. 1 x 1) and see how much RAM that uses. Then you can extrapolate out fairly simply to how much would be needed for a larger matrix.

To invert, you will need at least 2 arrays (src, dest), so 15x15 is very questionable.

Couldn't you do it in place? Not that the library they are proposing to use would necessarily do that.

I may well be wrong about that. After reading Inverse of a Matrix
using Elementary Row Operations it sounds like you may well need more memory for the inversion operation.


text:
How do I make LEDs lights up one by one according to how long the button was pressed and hold
In my project, I am trying to create a timer display with LEDs base on how long a button was pressed and hold.
There are 8 LED lights in total, when the toggle button was pressed, 1st LED lights up; keep holding/ pressing the button, the 2nd LED lights up after 1sec, the 3rd LED lights up after 2sec and so on. So 7s after the button was pressed and hold, all 8 LEDs shall light up. When the button was released at anytime, all LEDs would be off.
Something is wrong with my code which the timer seems not working (saving the time when the button was pressed) and calculate the time difference ("current time" - "time when button pressed") in order to lights up the LED.
My codes:
 int current;
 long millis_held;
 long prev_secs_held;
 unsigned long firstTime;
 byte previous = LOW;

 const int buttonPin = 13;

 void setup() {
 pinMode(buttonPin, INPUT);
 pinMode(2,OUTPUT) ;
 pinMode(3,OUTPUT) ;
 pinMode(4,OUTPUT) ;
 }

 void loop() {
 current = digitalRead(buttonPin);

 if (current == HIGH && previous == LOW) {
 firstTime = millis();
 digitalWrite(2, HIGH);

 millis_held = (millis() - firstTime);

 if (millis_held >= 1000 && firstTime <2000){
 digitalWrite(3, HIGH);
 }

  if (millis_held >= 2000){
  digitalWrite(4, HIGH);
 }
 }

 else {
 digitalWrite(2, LOW);
 digitalWrite(3, LOW);
 digitalWrite(4, LOW);
 }
 }

Hope you guys can help, thanks a lot.

We can’t help you without seeing your code.

if I waited too long before initiating the 1st button press, same thing happens with all LEDs light up together ... that indicates that you are not waiting for the button to be pressed before starting the timer

Thanks for your reply, I have added the codes I am currently working on for your reference. See id you can help. Thanks!

your code is improperly indented ... that makes the code difficult to read and leads to errors during code development

There are multiple errors in your code.
In the loop, the first if might not have the use you intended it to have. You are checking for previous == low, but you never set previous to high. Therefore this check can be removed entirely, or you could restructure your code a bit and add a previous = high.
Secondly, this if is also flawed:
if (millis_held >= 1000 && firstTime <2000){
    digitalWrite(3, HIGH);
}

You are checking for firstTime < 2000 which means you need to press the button within 2 seconds of the power-up of the Arduino or else this code will not run.
Lastly, for this to run you probably only want to set firstTime = millis() once when you press the button, and not every time the loop() runs thereafter while you keep the button pressed. You would need to move the bracket on line 32 to line 22, that is from just above the else to the line above millis_held = (millis() - firstTime); and then add previous = HIGH; in the first if.
I am leaving it to you to fix your code, since that would be good practice to get some feeling for it. Happy coding!
Lastly you still need to add the last 5 leds, but once the first few work you should be fine.

Thanks a lot for your advise, I think I kinda get it, allow me some time to digest and work on it. I will get back to you soon. Appreciate your help!!!

Great thanks to Ananas_hoi, I was finally able to get my code work accordingly!! The following code only show the 4 LED to be lights up one by one every second when the button was pressed and hold:
int current;
long millis_held;
unsigned long firstTime;
byte previous = LOW;

const int buttonPin = 13;

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(2,OUTPUT) ;
  pinMode(3,OUTPUT) ;
  pinMode(4,OUTPUT) ;
  pinMode(5,OUTPUT) ;
}

void loop() {
  current = digitalRead(buttonPin);

  if (current == HIGH && previous == LOW) {
     firstTime = millis();
     digitalWrite(2, HIGH);
     previous = HIGH;
  }

  millis_held = (millis() - firstTime);

  if (millis_held >= 1000 && previous == HIGH) {
      digitalWrite(3, HIGH);
     }

  if (millis_held >= 2000 && previous == HIGH) {
      digitalWrite(4, HIGH);
     }

  if (millis_held >= 3000 && previous == HIGH) {
      digitalWrite(5, HIGH);
     }

  if (current == LOW) {
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  previous = LOW;
 }
}

Thanks for posting the solution. (voted.) Lots of new users don't give back like that. This way others can learn from your project. The indentation in your answer is much better than in your original question, but still needs some cleanup. Could you indent the code inside the braces from the if (current == low) statement? And it would be better for new readers if you cleaned up the indentation of your original question. It's pretty hard to read as is.


text:
BJT - BC547 not working with LED strip
I'm connecting an LED strip that takes 12V input to an Arduino Uno R3's 5V VCC using a B547 transistor.
Here's my circuit:
Base -> 1K ohm resistor -> DO13
Collector -> -ve of LED strip
Emitter -> GND
VCC 5V -> +ve of LED strip

Nothing happens when I try to turn on the LED strip. However if I remove the 1K resistor and turn on the LED, Arduino's built in LED gets dimmer but the LED strip does not turn on.

What am I doing wrong?
TIA!

What kind of LED strip? You can't run a typical 12V LED strip from 5V. Not even slightly.

@Majenko, thanks for the reply. I'm giving 12V current to the Arduino using an adapter. I just got the LED strip to shine dimly. Would it work if I lower the base resistance of the transistor or if I change the VCC to VIN instead of 5V?

Please show a photograph of your actual setup.

@Qumber do not pass the LED supply current through the arduino ... there is a chance that the arduino will act as an expensive fuse

there's a nice circuit diagram tool that will help us diagnose your problem better. Generally though, to switch 12 volts with the Arduino, I would connect 12 v to collector pin, base to arduino IO pin, and emitter to ground. Also you should check if your transistor can handle the power requirement of the LED strip or else it will burn out

I'll definitely make a diagram and share in a bit. :)

BC547 is good for 100 mA only

You have a 12 Volt LED strip and power it with 5V. That could be the reason why the lights shine dimmy.  The transistor is not made for driving big loads. It's collector power dissipation is specified with 500 mW. I would recommend to use a MOSFET and use the 12 Volt Powersupply at the Strips V+ directly.

Connecting the + of the leds strip to VIN will give the strip 12V. Definitely don't connect the 12V adapter to Vcc, or you'll blow up the Arduino. Also, don't remove the 1k resistor, or you'll damage the Arduino's output pin. You can try lowering the value, but don't go below 220 Ohm. Though, unless your led strip is very short, the BC547 isn't going to cut it.

Thank you. I'll replace BC547 with a MOSFET and will try giving the strip its 12 volts from an external source instead of Arduino.

Ok. First off, if you have a 12V LED strip then you have to power it from 12V. Powering the Arduino from 12V and then powering the LED strip from the 5V pin of the Arduino is not powering the LED strip from 12V, it's powering the Arduino from 12V and the LED strip from 5V.
The LED strip's anode (+) must be connected to the + of the 12V supply or, if it's only a very short LED strip then you can use VIN on the Arduino.
LED strips typically have a number of LEDs (eg 3) in series with a resistor to make one "segment", and many "segments" in parallel. This gives a total forward voltage of typically 9V or more - so you must provide at least that to get the LEDs to light.
Secondly the BC547 is not a good transistor to use for switching an LED strip.  It has a maximum continuous collector current of 100mA. That means that you can only have a maximum of 100mA going through your LED strip before the transistor blows.
For reference, 100mA is the equivalent of 5 "normal" (5mm, of the kind you'd use in a breadboard) LEDs at full current and brightness. A typical LED strip (depending on length) can use many hundreds or thousands of mA.
Really you should be using an N-channel MOSFET that is rated for at least as much current as your LED strip requires to run. For safety, and to reduce heat dissipation, you ideally want it to be many times more powerful than the LED strip needs.
A common choice is the IRF530, which is rated at 10A with a switching voltage (the "threshold" voltage) that is low enough for a 5V Arduino to control (there are more suitable ones, but these seem to be the "go-to" component for many Arduino users - they're adequate for most uses).

simulate this circuit – Schematic created using CircuitLab

Thank you so much for the thorough answer. I do understand (a bit) the schematics now. I'll get my hands on the MOSFET, and will try it out as soon as I get home. :)

I gave the strip 12V directly and switched BC547 with a TIP120 and it did work. I'll try a small 12V LED powering up from VIN as well. Thanks for the help. This was my first ever project. :)


text:
MQ-4 Sensor working fine with Beetle Bluno BLE but not with Arduino Nano 33 BLE
I have an MQ-4 sensor connected to a Beetle Bluno BLE that seems to work fine, however, when I change the board to an Arduino Nano 33 BLE, the sensor doesn't seem to work well (I get an arbitrary oscillation in values coming from the sensor but these don't increase or decrease with the presence of gas).
Beetle Bluno BLE setup:

MQ-4:GND -> Beetle:GND
MQ-4:VCC -> Beetle:5v
MQ-4:AO -> Beetle:A1

Arduino Nano 33 BLE setup:

MQ-4:GND -> Arduino:GND
MQ-4:VCC -> Arduino:3.3v
MQ-4:AO -> Arduino:A1

(image slightly missleading because VCD is actually not connected to 5V but to 3.3V)
The only difference is the 5v instead of 3.3v, however, I also tried powering the sensor externally with 5v and it makes no difference.

A schematic might be helpful, particularly for the Arduino, along with "not working well" actually means.

Description updated with a schematic and a definition

You fixed the 5V jumper and verified it's putting out 5V?

No, I am not using the 5v but the 3.3v pin instead

AFAIK that sensor requires 5V according to sources like the SparkFun.

I see, well I tried powering the sensor with 5v externally with the same results

Which is why a schematic would be helpful to see if there's a missing shared ground or something.

I really don't know how to make schematics, but what I've done is connect the VCC and GND of the MQ-4 sensor to my other Beetle Bluno board to pins V5 and GND, and pin A0 stayed in Arduino Nano

I think the ground connection would also need to be hooked up to the Arduino if I'm understanding what you're saying.

After adding the ground to the Arduino, it seems like it is reading the values from the sensor, however, the values are "micro-oscillating" up and down in a way that doesn't happen in the Beetle Bluno

There are any number of reasons that could be happening; wiring and power supplies are often the first places to look when dealing with analog signals. (Which is not what I usually do, so I'm probably useless :)

Try hand drawing the schematic. There are a lot of videos on line that will explain it to you. Frizzing is not considered a schematic it leaves to many things unconnected. A hint when the supplier says 5V they do not expect it to work with much less or more, that is a very important parameter. Also it is a big help when you post links to the technical information on the hardware items. The next most important thing is current, can your power supply supply enough current. The Arduino a Power Supply it is NOT! Violating this rule can cause a lot of problems especially with analog hardware.


text:
How to reduce AnalogRead noise?
Currently trying to read off values from a photodiode through analogread. It's constantly so noisy and I thought it might be something wrong with my low-pass filter, but I decided to just connect a 1.5V battery to an analog pin and had just as much noise (upwards of 10mV oscillations). Is there a way around all of this noise? Because this makes the collected data unusable for my project.

Code to read off analog values:
int diodePin = A0;
int sensorValue = 0;
int sensorVoltage = 0;

void setup() {

  Serial.begin(57600);

}

void loop() {

sensorValue = analogRead(diodePin);
sensorVoltage = sensorValue*(5000/1024);
Serial.println(sensorVoltage);
delay(10);

}

Without a schematic it'll be impossible to help, although it may be more relevant on the electronics SE. 0.01V out of 3.3V/5V doesn't sound that bad, but it depends on context and hardware.

are the readings noisy if the sensor is exposed to sunlight only?

no. noisy readings at all times. as i said, even if I literally just try to read the voltage of a AA battery off of an analog input, it doesn't give me a smooth reading at all.

sure: take 3 readings, sort, keep only the middle one.

I need continuous good readings so that I can perform a Fourier transform on the collected data

Please post the schematic, not a frizzy thing. Your question is a tough one and without being there the next best thing is the schematic you drew as you wired it. Links to technical information on the hardware devices makes it easier for all of us. At this point all we can do is guess.

Just to make sure I understand: you're putting 1.5V into an analog pin (5V reads 1024, so 1.5V would be ~307), it's a 10-bit ADC so ~5mV with the default analog reference. You're seeing values from 306-308. What are you using to power the Arduino? Have you tried using a different reference or a stable AREF input? Have you checked things like [this] (https://forum.arduino.cc/t/help-with-weird-analog-input-problem-unstable-analog-reference/82011)? Without a solid reference voltage this still doesn't seem that unusual. Analog had a lot of moving parts.

Per your frizzy thing you should get zero as the Arduino does not have any power and the A+ and Ground are connected together on the + terminal. Posting a schematic would help a lot, Dave Newton suggested that a few days ago.

I always do two things for when "reading" analog data with an Arduino.

Measuring the voltage supply of the arduino board through its internal reference and calibrating with another 'good" voltmeter ("4 1/2" digits-20000 points or "3 3/4" digits-6000 points). ( Usefull link  https://www.instructables.com/Secret-Arduino-Voltmeter/ )

Sampling more analog datas to calculate a "mean" ... This can remove some "noise" and add "some bits". 16 samples would add "4" bits at your "readings". Of course, the global sample rate will be lower.

Don't forget, ground star of wires !!!

Keep in mind that averaging samples will increase the resolution but might not improve accuracy. Only random noise can be "averaged out"...systemic inaccuracy will remain.

Right. Only in the case if "linearity" is better than 1/16 LSB min ... which is very "rare". Some cases of 1/4 LSB of very good converters.


text:
Seeking to write a ton of information to an SD card as close to live as possible
So I've recently started a project where I am using an accelerometer, along with a SD card breakout board. I've been able to get information to write properly to the SD card with no issues whatsoever. However, my speed is a bit lower than I would like, at about only 40Hz or so, where my accelerometer can log data at 260Hz (MPU-6050). Each reading contains an X, Y, Z, and timestamp value since recording started. Each reading is output into a .txt file for later separation via comma-separated-value sorting in Excel(I wish) or GNUplot, which handles the massive sample size much better.
I've referenced https://forum.arduino.cc/t/how-to-write-data-with-high-sampling-rates-to-a-sd-card/281496/9 to try and figure this out, but I couldn't get much out of it. I don't understand arrays very well beyond the fact they are just tables like in excel, and can be set up in 1, 2, 3, or more dimensions.
I've read around a bit and it seems my problem is that I'm closing and opening the file each and every write cycle. However, I don't know how to get out of doing this as the program seems to not run properly if I don't close out the file or if I use flush. My general idea of how this could flow without opening/close cycles every single time would be:

Create arrays for each variable (X, Y, Z, elapsedTime)
Take all my recordings for a given time, maybe five-hundred readings or so which would come out to about 12 seconds, or whatever possible value I can squeeze out of my Atmega328P and maintain program stability, and shove them into their respective arrays. Ideally the longer the better, but I understand I have memory constraints.
In one write-cycle, I write all the values into CSV form, or even multiple print cycles cycling through each array cell continuously until all the values are input with the proper format.
Clear the arrays of all the info they held, and return to step 2.

Really appreciate any help you guys can offer. Thank you!
//

#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
int recordStatus = false;                                                   //Default recordStatus is zero.
int recordingLed = 3;
const int chipSelect = 10;
Adafruit_MPU6050 mpu;

void setup(void) {
  pinMode(2, INPUT_PULLUP);
  pinMode(3, OUTPUT);
  Serial.begin(500000);
  while (!Serial)
    delay(10); // will pause Zero, Leonardo, etc until serial console opens

                                                                           //SD CARD WRITE CODE BEGIN
 {
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
}
                                                                              //SD CARD WRITE CODE END

  Serial.println("Adafruit MPU6050 test!");                                   //MPU6050 ACCELEROMETER INITIALIZATION CODE BEGIN
  // Try to initialize!
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  switch (mpu.getAccelerometerRange()) {
  case MPU6050_RANGE_2_G:
    break;
  case MPU6050_RANGE_4_G:
    break;
  case MPU6050_RANGE_8_G:
    break;
  case MPU6050_RANGE_16_G:
    break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  switch (mpu.getGyroRange()) {
  case MPU6050_RANGE_250_DEG:
    break;
  case MPU6050_RANGE_500_DEG:
    break;
  case MPU6050_RANGE_1000_DEG:
    break;
  case MPU6050_RANGE_2000_DEG:
    break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_260_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
  case MPU6050_BAND_260_HZ:
    Serial.println("260 Hz");
    break;
  case MPU6050_BAND_184_HZ:
    Serial.println("184 Hz");
    break;
  case MPU6050_BAND_94_HZ:
    Serial.println("94 Hz");
    break;
  case MPU6050_BAND_44_HZ:
    Serial.println("44 Hz");
    break;
  case MPU6050_BAND_21_HZ:
    Serial.println("21 Hz");
    break;
  case MPU6050_BAND_10_HZ:
    Serial.println("10 Hz");
    break;
  case MPU6050_BAND_5_HZ:
    Serial.println("5 Hz");
    break;
  }
                                                                                //MPU6050 ACCELEROMETER INITIALIZATION CODE END
}

unsigned long startMillis;
unsigned long currentMillis;
unsigned long elapsedTime;
int rawMillis;
void loop() {
  digitalWrite(recordingLed, LOW);
  int buttonRecord = digitalRead(2);                                                //Check button for GND input
  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

// make a string for assembling the data to log:                                    //SD CARD VALUES ASSIGN BEGIN
  int X = "";
  int Y = "";
  int Z = "";
  String timeofRecord = String(millis()/1000.0, 10);
  X = (a.acceleration.x/9.81);
  Y = (a.acceleration.y/9.81);
  Z = (a.acceleration.z/9.81);
  if(buttonRecord == false){                                                        //Toggle record status upon pin 2 going to GND
    delay(500);
    recordStatus = !recordStatus;                                                   //If button is pressed, make recordStatus switch from true to false.
    startMillis = millis();
  }

if(recordStatus == true){                                                           //While record is toggled, do below
    rawMillis = millis()-startMillis;
    String elapsedTime = String(rawMillis/1000.00, 3);
    File dataFile = SD.open("datalog.txt", FILE_WRITE);
      if (dataFile) {                                                               // if the file is available, write to it:
    digitalWrite(recordingLed, HIGH);
    dataFile.print(elapsedTime);
    dataFile.print(", ");
    dataFile.print(X);
    dataFile.print(", ");
    dataFile.print(Y);
    dataFile.print(", ");
    dataFile.print(Z);
    dataFile.println("");
    dataFile.close();
  }
}
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
    }
}

UPDATE
So I've been messing with this a while, and I believe I just about have it figured out. I have arrays set up for time, X, Y, and Z and they are populating values correctly. However, I can't seem to get into my SD card file. There is no issue when the setup initializes, it's like it skips the

if (dataFile){

entirely. The modified code is below here. There's no shutdowns, and the program loops continuously so I don't think I'm running out of memory or having any power issues. The red LED on the SD card is flashing as though it's being written. Even if I remove the if(dataFile) check and force the commands contained in the if statement to execute, my txt file is still left empty. Previously I was writing to this just fine. Memory problem? I have less than 500 bytes of memory available. Possibly this is the cause? Or is it the for loop causing my trouble?
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
int recordStatus = false;                                                   //Default recordStatus is zero.
int recordingLed = 3;
const int chipSelect = 10;
Adafruit_MPU6050 mpu;

void setup(void) {
  pinMode(2, INPUT_PULLUP);
  pinMode(3, OUTPUT);
  Serial.begin(500000);
  while (!Serial)
    delay(10);
                                                                           //SD CARD WRITE CODE BEGIN
 {
  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
}
                                                                              //SD CARD WRITE CODE END

  Serial.println("Adafruit MPU6050 test!");                                   //MPU6050 ACCELEROMETER INITIALIZATION CODE BEGIN
  // Try to initialize!
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_4_G);
  switch (mpu.getAccelerometerRange()) {
  case MPU6050_RANGE_2_G:
    break;
  case MPU6050_RANGE_4_G:
    break;
  case MPU6050_RANGE_8_G:
    break;
  case MPU6050_RANGE_16_G:
    break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  switch (mpu.getGyroRange()) {
  case MPU6050_RANGE_250_DEG:
    break;
  case MPU6050_RANGE_500_DEG:
    break;
  case MPU6050_RANGE_1000_DEG:
    break;
  case MPU6050_RANGE_2000_DEG:
    break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_260_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
  case MPU6050_BAND_260_HZ:
    Serial.println("260 Hz");
    break;
  case MPU6050_BAND_184_HZ:
    Serial.println("184 Hz");
    break;
  case MPU6050_BAND_94_HZ:
    Serial.println("94 Hz");
    break;
  case MPU6050_BAND_44_HZ:
    Serial.println("44 Hz");
    break;
  case MPU6050_BAND_21_HZ:
    Serial.println("21 Hz");
    break;
  case MPU6050_BAND_10_HZ:
    Serial.println("10 Hz");
    break;
  case MPU6050_BAND_5_HZ:
    Serial.println("5 Hz");
    break;
  }
                                                                                //MPU6050 ACCELEROMETER INITIALIZATION CODE END
}

float startMillis;
float elapsedTime[3];
float rawMillis;

float X[3];
float Y[3];
float Z[3];

void loop() {
  digitalWrite(recordingLed, LOW);
  int buttonRecord = digitalRead(2);                                                //Check button for GND input
  /* Get new sensor events with the readings */
  if(buttonRecord == false){                                                        //Toggle record status upon pin 2 being pulled down to GND
    delay(500);
    recordStatus = !recordStatus;                                                   //If button is pressed, make recordStatus switch from true to false.
    startMillis = millis();
    Serial.print("BUTTON PRESSED");
  }
  if(recordStatus == true){                                                         //While record is toggled, do below
   digitalWrite(recordingLed, HIGH);
    sensors_event_t a, g, temp;
    mpu.getEvent(&a, &g, &temp);
for(int arrayNumber = 0; arrayNumber <= 3; ++arrayNumber){
    sensors_event_t a, g, temp;
    mpu.getEvent(&a, &g, &temp);

    X[arrayNumber] = (a.acceleration.x);                                             //SD CARD VALUES ASSIGN BEGIN/DO MATH TO CALCULATE G'S
    Y[arrayNumber] = (a.acceleration.y);
    Z[arrayNumber] = (a.acceleration.z);

    rawMillis = millis()-startMillis;
    elapsedTime[arrayNumber] = rawMillis;
    Serial.println(elapsedTime[arrayNumber]);
    Serial.println(X[arrayNumber]);
    Serial.println(Y[arrayNumber]);
    Serial.println(Z[arrayNumber]);
    Serial.println(arrayNumber);                                                     // diagnostic for checking to make sure arrays are being populated properly
}

    File dataFile = SD.open("datalog.txt", FILE_WRITE);
    Serial.print("LEFT LOGGING LOOP, ENTERING WRITE LOOP");

  if (dataFile) {                                                                    // if the file is available, write to it
    for(int arrayNumber = 0; arrayNumber <= 3; ++arrayNumber){
 Serial.print("NOW INSIDE WRITE LOOP");                                              // confirmation of being inside the write loop, and writing data to the file
    String(dataString) = (
    elapsedTime[arrayNumber] + String(", " ) + X[arrayNumber] + String(", ") + Y[arrayNumber] + String(", ") + Z[arrayNumber]         //Format data for output to the comma separated format for excel/gnuplot
  );
    dataFile.println(dataString);
       }
       dataFile.close();
       Serial.println("WRITE LOOP DONE");
    }
  }
}

Can you be more specific regarding "does not run properly"? In any case, there's this, this, and this. Without knowing what the issue/s with arrays is/are it's hard to help.

How about writing to external memory such as RAM or Ferroelectric RAM. That will take it as fast as you can write it, there is no write delay. Then when the test if finished transfer it to the SD card. The Ferroelectric RAM will remember even if the power is off.

Have you considered writing a binary file instead of text?

Why not writing a whole string of data at one time ?  "faster" ?

@DaveNewton Thank you for the links. The third one is especially helpful for me. The link recommends executing the SD.open and SD.close command outside the loop. However if I try to do that, this goes back to my "not run properly" statement as the program seems to go through one cycle and never repeat. I'm not really sure why this is? I figure the file should be able to be opened in setup and closed at any time you really want, and while the file is open, new data can be brought in, manipulated, and written. Does having a file open stop other functions or prevent looping? Thank you

@Gil Hey Gil, appreciate the info on FRAM. Unfortunately, I don't think using that will solve my problem as I believe this is more a problem with my code being slow. I will keep that in mind for the future though.

@jsotola I didn't even notice. When I merged two example programs together to make this, I must have left it in there by mistake. Removed from the code as of now.

@EdgarBonet I would consider doing that, but this data is likely going to be going to other people who will be simply taking the device, popping an SD card in, getting data, and pulling the SD card out. If I make them mess around with binary, I feel like it's just going to wind up not getting used. I could process the data for them, but then they'll be forced to come to me every time in which I think the same outcome would follow.

@Antonio51 Antonio, that was a great addition to the program. I am now only printing to the file once instead of multiple times each cycle. Thanks!

Logical ... for a caracter you open the file, write, then close. All operations that takes "some" time ! I had to resolve that problem in saving parameters of Temp, humidity and some others things (100 caracters) every 5 seconds, so I know ...

@Antonio51 Ideally, I'd like to squeeze at least 260Hz out of these write operations, as that's the speed of my MPU-6050s recording ability. I'm measuring some really high accelerations that are dampened quickly, so I really want to maximize my readings/second

Don't add datas that you really don't use ... as labels ... You know what and how you are saving your data, save only these, eventually as binary datas in place of strings of caracters. You can also use a "data set" record. A little more complicated but usefull.

@Antonio51 I also noticed I was using a lot of strings unnecessarily. Unfortunately I need both decimal places as well as positive/negatives, so I'm guessing floats are the only way to have all that, even though the acceleration values will never exceed 64 m/S^2

If I remember well, I could read 8 kbytes /second and writing quasi similar but did not measure this because every 5 seconds. (on an Arduino 16 MHz). I thing it would be beter on a LGT328 (?) which is running at 32 MHz.

@Antonio51 A faster microcontroller is probably what I need, but I'm certain this has to be possible. I'm merely logging XYZ values and time. I guess now I've got some personal attachment to trying to solve this. I'm also a beginner so it's a good learning opportunity for me.

If datas are 2 bytes large enough (15 bits + sign), you can save all as word ... but when reading out, change or correct the type of variables accordingly. Good luck !

So I spent a while longer banging my head on the wall, and I finally found a solution to my issue. @DaveNewton provided several links that lead to other links, and I found my way to here where some not-so-common knowledge is explained. It appears that for some reason the FILE_WRITE function is slow, and takes a lot of time to execute.
This can be substituted by using

O_CREAT | O_WRITE | O_APPEND

as this first checks if the file is created, and if not, creates it. Once the or check passes for the O_CREAT section, it moves on into the O_WRITE command. Then the O_APPEND checks if there is any data already present and if so, move to the end of the line to begin new data logging.
My finished code in it's entirety is below, I hope it helps someone in the future. I'm using a MicroCenter 32GB (class 10) Micro SD card to store the data, this SD card breakout board, and this MPU-6050 based accelerometer.
// This program is designed to log data to an SD card via an arduino Uno, and SD card breakout board, and a MPU-6050 accelerometer module.

// MPU-6050:                https://www.amazon.com/HiLetgo-MPU-6050-Accelerometer-Gyroscope-Converter/dp/B078SS8NQV
// Micro SD Card Breakout:  https://www.adafruit.com/product/254
// Micro SD Card I used:    https://www.microcenter.com/product/485584/micro-center-32gb-microsdhc-card-class-10-flash-memory-card-with-adapter

// Link to original Arduino StackExchange submission where I worked through this code:  https://arduino.stackexchange.com/questions/84961/seeking-to-write-a-ton-of-information-to-an-sd-card-as-close-to-live-as-possible

#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>

int recordStatus = false;                                                   //Default recordStatus is zero.
int recordingLed = 3;                                                       //Output to show us whether we are recording or not.
const int chipSelect = 10;                                                  //Use pin 10 as our CS pin
Adafruit_MPU6050 mpu;

void setup(void) {
  pinMode(2, INPUT_PULLUP);                                               //Set pin 2 to have a default HIGH state using the internal pull up resistor.
  pinMode(3, OUTPUT);
  Serial.begin(500000);
  SPI.begin();
  SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));       //I have no idea if this really does anything, but I figure I'd just leave it since it's not causing any problems.
  while (!Serial)
    delay(10); // will pause Zero, Leonardo, etc until serial console opens
                                                                           //SD CARD WRITE CODE BEGIN
 {

  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
}
                                                                              //SD CARD WRITE CODE END

  Serial.println("Adafruit MPU6050 test!");                                   //MPU6050 ACCELEROMETER INITIALIZATION CODE BEGIN
  // Try to initialize!
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_16_G);                            //I originally had this at 4 but was capping results, so I moved it up to 16. Feel free to lower this if you know your application will not exceed 4Gs
  switch (mpu.getAccelerometerRange()) {
  case MPU6050_RANGE_2_G:
    break;
  case MPU6050_RANGE_4_G:
    break;
  case MPU6050_RANGE_8_G:
    break;
  case MPU6050_RANGE_16_G:
    break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);                                //I'm not using the gyro at all, but 500 degrees seems like a good value to use here.
  switch (mpu.getGyroRange()) {
  case MPU6050_RANGE_250_DEG:
    break;
  case MPU6050_RANGE_500_DEG:
    break;
  case MPU6050_RANGE_1000_DEG:
    break;
  case MPU6050_RANGE_2000_DEG:
    break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_260_HZ);                              //Select maximum frequency for recording.
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
  case MPU6050_BAND_260_HZ:
    Serial.println("260 Hz");
    break;
  case MPU6050_BAND_184_HZ:
    Serial.println("184 Hz");
    break;
  case MPU6050_BAND_94_HZ:
    Serial.println("94 Hz");
    break;
  case MPU6050_BAND_44_HZ:
    Serial.println("44 Hz");
    break;
  case MPU6050_BAND_21_HZ:
    Serial.println("21 Hz");
    break;
  case MPU6050_BAND_10_HZ:
    Serial.println("10 Hz");
    break;
  case MPU6050_BAND_5_HZ:
    Serial.println("5 Hz");
    break;

   SPI.endTransaction();
  }
                                                                                //MPU6050 ACCELEROMETER INITIALIZATION CODE END
}
float X;
float Y;
float Z;
float startMillis;
float currentMillis;
float rawMillis;
int tickMillis = LOW;

void loop() {
  int buttonRecord = digitalRead(2);                                                //Check button (pin 2) to see if it is grounded through momentary switch.
  // Get new sensor events with the readings.

if(buttonRecord == LOW){                                                           //If buttonRecord switches to GND, switch tickMillis to it's opposite value as a toggle and store startMillis, then wait 300ms as a debounce.
    tickMillis = !tickMillis;
    startMillis = millis();
    delay(300);
}
    if(tickMillis == HIGH){
    File dataFile = SD.open("datalog.txt", O_CREAT | O_WRITE | O_APPEND);           // Create datalog.txt. If already created, move to end of stored data, and begin write function
    if (dataFile) {                                                                 // if the file is available, write to it:

  for(uint8_t i = 0; i < 250; i++){                                                 // For i = 0, execute the below code. Then increment i by 1. Once past 250, exit for() loop
    digitalWrite(recordingLed, HIGH);

    sensors_event_t a, g, temp;                                                     // Commands to trigger event sensing and acceleration logging.
    mpu.getEvent(&a, &g, &temp);

    X = a.acceleration.x/9.81;                                                      // Divide normal acceleration return values to calculate G forces
    Y = a.acceleration.y/9.81;
    Z = a.acceleration.z/9.81;

    rawMillis = millis()-startMillis;                                               // Take our current millis value and subtract our beginning startMillis from it to get how long we've actually been recording.

    dataFile.print(rawMillis/1000, 3);                                              // Store data in a Comma-Seperated-Value format. The '3' after rawMillis/1000 says print out to 3 decimal places.
    dataFile.print(", ");                                                           // I just use a txt file since GNUplot can plot from that value, but a CSV library could probably be used here.
    dataFile.print(X);                                                              // Excel doesn't allow plots beyond 255 datapoints for god knows why. So GNUplot is basically a necessity to plot these accurately to timestamp.
    dataFile.print(", ");
    dataFile.print(Y);
    dataFile.print(", ");
    dataFile.print(Z);
    dataFile.println();
    }
    dataFile.flush();
    dataFile.close();
    }
   else {
    delay(500);
    Serial.println("error opening datalog.txt");
    }
  } else {
        digitalWrite(recordingLed, LOW);
    }
}

Thanks so much for the comments/advice everyone. It's really appreciated. The final recording frequency for this is ~170Hz, which is good enough for me.


text:
Arduino Multiplexer Input voltage per pin not decoupled
I am very new to electronics (software engineer background).
I want to send an analog signal (5V) to one/many input wires. The input wires are connected to a 16 channel mutiplexer.
My arduino then reads all of the 16 channels.
Right now the issue is: If I connect only one pin to the 5V output of the arduino many other of the multiplexer input pins also read high voltage values even tho only one pin is actually connected.
I am pretty sure this issue is a duplicate - please point me to the right direction.
I have read about decoupling (if that is the case - please explain it for newbies without background).

It is not clear at all what you are doing. Please show a schematic of exactly what you have connected on the multiplexer (including power, ground, selectors), and what/where you are measuring.

Please show a schematic or a picture of your setup. What multiplexer are you using? Also understand that an unconnected input has an undefined value and might read high or low or even oscillate between them. It’s much better to connect an unused input to either ground or Vcc to give it a defined value and not have it pick up noise.

As I understand it you have a multiplexer with one of the inputs connected to 5 volts and the rest are open. What you are reading is leakage in the IC and associated wiring. There are many reasons they tell us not to leave inputs open, you just found one. This is especially problematic with CMOS devices because of there extremely high impedance. The first thing the TI publication
SCBA004D–July 1994–Revised September 2016 tells you is power consumption is
becoming a major issue in today’s market. However, when designing systems using CMOS and BiCMOS devices, one must understand the characteristics of these families and the way inputs and outputs behave in systems. It is very important for the designer to follow all rules and restrictions that the manufacturer requires, as well as to design within the data-sheet specifications. Because data sheets do not cover the input behavior of a device in detail, this application report explains the input characteristics of CMOS and BiCMOS families in general. It also explains ways to deal with issues when designing with families in which floating inputs are a concern. Understanding the behavior of these inputs results in more robust
designs and better reliability.


text:
Error: " stray '##' in program in
I am trying to use #define in Arduino IDE as I used to do in Atmel Studio like:
#define PROGRAM(N) void PROG_##N(void)

However I am getting a stray error because of the hashes, is there a way to implement this better?
Aim: PROGRAM(5){} becomes void PROG_5(void){} and so on.

It compiler in my Arduino IDE. Code:  (using \n as newlines):
#define PROGRAM(N) void PROG_##N(void) \n
PROGRAM(5){}\n
void setup(){}\n
void loop(){}

What version of the IDE are you using? You're not a Linux user that used apt-get to install it are you?

It is working now, the mistake was actually in a different file but Arduino IDE 1.8.8 kept saying it is here which was confusing. Thanks.


text:
please tell me how do I fix this code down here(please tell in my easy English)
 LiquidCrystal 1cd(12, 11, 5, 4, 3, 2);

 void setup() {
   1cd.begin(16, 2);
   1cd.print"abbu, kya, chalrelaye!");
 }

 void loop() {

 }

What is the question?

Variable names MUST NOT start with a digit. Only '_' and a-z are allowed!
1cd really should be lcd with an 'ell' instead of a one (1).

what did we learn here about Arduino? upvoters, how is this useful for you?

The compiler for Arduino is just working the way as any other C/C++ compiler. ;)

I down-vote Answers to a Question originating in an typographical error, because this kind of question has no value and without answer it would be deleted.

I suggest you modify the LiquidCrystal "Hello World" sketch:

Here is the example code:
// include the library code:
#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis() / 1000);
}

Good luck!


text:
Initializing an array within a class
I'm making a game of snake on the adafruit Neopixel shield and have run in to a problem. How do you fill out an array (in this case a 5*8 array) with values once the class has been called.
This is my code so far
H file
#include <Arduino.h>
#include <Adafruit_NeoMatrix.h>
#include <streaming.h>

class Snake : public Adafruit_NeoMatrix
{
    public:
    Snake();
    void drawSnake();

    private:
    int snakeBoard[5][8];
};

CPP file
#include "Snake.h"

Snake::Snake() : Adafruit_NeoMatrix(8, 5, D6,
  NEO_MATRIX_TOP        + NEO_MATRIX_LEFT +
  NEO_MATRIX_ROWS       + NEO_MATRIX_PROGRESSIVE,
  NEO_GRB               + NEO_KHZ800)
{
  begin(); // start the matrix
  show();

  int snakeBoard[5][8] = {{1,1,0,0,0,0,0,0},
                        {0,0,1,0,0,0,0,0},
                        {0,0,1,0,1,1,-1,0},
                        {0,0,1,1,1,0,0,0},
                        {0,0,0,0,0,0,0,0}};
}

void Snake::drawSnake()
{
  for(int y = 0; y < 5; y ++)
  {
    for(int x = 0; x < 8; x ++)
    {
      Serial << "X: " << x << " Y: " << y << " Value" << snakeBoard[x][y] << endl;
      delay(100);
    }
  }
  drawPixel(5,5,Color(0,0,255));
  show();
}

When I run the program random garbage is printed in the serial monitor.

When initializing an array you need to use an =

And in your constructor you declare a new array named snakeBoard which is deleted automatically once you leave the constructor. This array covers up the array declared in the class definition

As already mentioned by @chrisl, you are creating a new local variable which overshadows your class member.
An easy way to get what you want is to memcpy your initial values into the array:
Snake::Snake() : Adafruit_NeoMatrix(8, 5, D6,
  NEO_MATRIX_TOP        + NEO_MATRIX_LEFT +
  NEO_MATRIX_ROWS       + NEO_MATRIX_PROGRESSIVE,
  NEO_GRB               + NEO_KHZ800)
{
  begin(); // start the matrix
  show();

  int initialSnakeBoard[5][8] {{1,1,0,0,0,0,0,0},
                        {0,0,1,0,0,0,0,0},
                        {0,0,1,0,1,1,-1,0},
                        {0,0,1,1,1,0,0,0},
                        {0,0,0,0,0,0,0,0}};
  memcpy(snakeBoard, initialSnakeBoard, sizeof(initialSnakeBoard));
}

You can achieve the same thing by utilizing C++11 constructor lists to initialize your members (see here):
Snake::Snake() : Adafruit_NeoMatrix(8, 5, D6,
  NEO_MATRIX_TOP        + NEO_MATRIX_LEFT +
  NEO_MATRIX_ROWS       + NEO_MATRIX_PROGRESSIVE,
  NEO_GRB               + NEO_KHZ800),
  snakeBoard {{1,1,0,0,0,0,0,0},
                        {0,0,1,0,0,0,0,0},
                        {0,0,1,0,1,1,-1,0},
                        {0,0,1,1,1,0,0,0},
                        {0,0,0,0,0,0,0,0}}
{
  begin(); // start the matrix
  show();
}

You also have an error in your drawSnake routine: You confused the order of the indexes. With snakeBoard[5][8] you declare 2-dimensional integer array with 5 rows containing 8 elements each. Then, snakeBoard[0] will be a pointer to the first row (which has 8 elements). So the first index is y and must only range from 0 to 4 inclusive. The function must be:
void Snake::drawSnake() {
    for(int y = 0; y < 5; y ++)
    {
        for(int x = 0; x < 8; x ++)
        {
            Serial.println("X: " + String(x) + " Y: " + String(y) + " Value " + String(snakeBoard[y][x]));
            delay(100);
        }
    }
}

This then prints all the expected array elements to the the Serial port, as tested on my Arduino Nano.

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


text:
typedef function pointer array declaration problem
Thanks for all your feedback. It helped.
I rewrote this yet another time and this time it works perfectly. I included three variations: a simple example using an array of function pointers, a Lambda version and a complex version like what I started with.
#define TASK_COUNT          3

typedef void ( *taskPointer ) ( );

//  Simple Version:
void taskS1 () { Serial.println ( ( char* )"SIMPLE TASK 1" ); }
void taskS2 () { Serial.println ( ( char* )"SIMPLE TASK 2" ); }
void taskS3 () { Serial.println ( ( char* )"SIMPLE TASK 3" ); }

//  Array of pointers to tasks
taskPointer callSimpleTask [ ] = {
taskS1,
taskS2,
taskS3,
};

//  Run the simple test
void showSimpleVersion () {
    Serial.println ( F ( "\nSimple Version:" ) );
    for (uint8_t i = 0; i < TASK_COUNT; i++) {
        callSimpleTask [ i ] ();
    }

}

//  Lambda Version: No separate task definitoins
void ( *callLambdaTask [ ] ) ( ) = {
    [ ] {Serial.println ( ( char* )"LAMBDA TASK 1" ); },
    [ ] {Serial.println ( ( char* )"LAMBDA TASK 2" ); },
    [ ] {Serial.println ( ( char* )"LAMBDA TASK 3" ); },
};

//  Run the Lambda test
void showLambdaVersion () {
    Serial.println ( F ( "\nLambda Version:" ) );
    for (uint8_t i = 0; i < TASK_COUNT; i++) {
        callLambdaTask [ i ] ();
    }

}

//  Complex Version: Each array element is a struct containing a
//  pointer to the corresponding task and related properties
struct complexTaskDefinition {
    taskPointer task;
    bool repeat;                //  Repeat flashing after delay
    int32_t iterations;         //  # times to repeat... -1 = forever
    uint32_t delay;             //  MS to wait before execution
};

//  Create a pointer to a task definition
complexTaskDefinition *task;

//  Prove that called function can call other functions:
void taskC1 () { showTaskC1(); }
void taskC2 () { showTaskC1 (); }
void taskC3 () { showTaskC1 (); }

void showTaskC1 () {
    Serial.println ( ( char* )"COMPLEX TASK 1" );
}
void showTaskC2 () {
    Serial.println ( ( char* )"COMPLEX TASK 2" );
}
void showTaskC3 () {
    Serial.println ( ( char* )"COMPLEX TASK 3" );
}

complexTaskDefinition tasks [ ] [4] = {
    {taskC1, true, -1, 1000 },  //  taskC1 repeats forever every second
    {taskC2, true, 10, 2000 },  //  taskC2 runs 10 times pausing for 2 seconds between iterations
    {taskC3, false, 3, 3000 },  //  taskC3 runs 3 times with 3 second delays between each, then dies
};

void showComplexTaskList () {
    Serial.println ( F ( "\nComplex Task List:" ) );
    for (uint8_t i = 0; i < TASK_COUNT; i++) {
        task = tasks [ i ];
        Serial.print ( '[' );
        Serial.print ( i );
        Serial.print ( F ( "] REPEAT:" ));
        Serial.print ( ( task->repeat ) ? "YES" : "NO" );
        Serial.print ( F ( ", DELAY:" ) );
        Serial.print ( task->delay );
        Serial.print ( F ( ", ITERATIONS:" ) );
        Serial.print ( task->iterations );
        Serial.println ();
    }
}

void showComplexVersion () {
    Serial.println ( F ( "\nComplex Version:" ) );
    for (uint8_t i = 0; i < TASK_COUNT; i++) {
        task = tasks [ i ];
        task->task ();
//      (( *tasks ) [ i ]).task ();
    }
}

void setup () {
    Serial.begin ( 115200 );
    while (!Serial.availableForWrite ()) {}

    showSimpleVersion ();

    showLambdaVersion ();

    showComplexVersion ();

    showComplexTaskList ();
}

void loop () {
}

Here is the output:
Simple Version:
SIMPLE TASK 1
SIMPLE TASK 2
SIMPLE TASK 3

Lambda Version:
LAMBDA TASK 1
LAMBDA TASK 2
LAMBDA TASK 3

Complex Version:
COMPLEX TASK 1
COMPLEX TASK 1
COMPLEX TASK 1

Complex Task List:
[0] REPEAT:YES, DELAY:1000, ITERATIONS:-1
[1] REPEAT:YES, DELAY:2000, ITERATIONS:10
[2] REPEAT:NO, DELAY:3000, ITERATIONS:3

I want to run one more experiment, this time with the complex version as a class.

loop() and setup()?

What compiler error do you get?

Board? Arduino IDE version? It can be compiled wihout any warning/error for AVR based board.  Btw: &task1, &task2, &task3 is more correct.

@KIIV As from C99 the & is entirely optional for function pointers. Neither is "more correct" than the other, they are both completely correct.

@majenko in C yes. In C++ there are also cases where it's required (like member function pointers). More correct was meant like "yes, i want function pointer, I didn't forget ()" - showing clear intention

I don't understand why did you ask the question without the error message and the part of the sketch where the error occurs and only added them later

Try replacing
taskDefinition _tasks [ ] [4] = {

by
taskDefinition _tasks [ ] = {

In short, you have defined _tasks as a 2D array of objects (an array
of arrays of objects) while you intend to use it as a 1D array.

Note that the error message is quite explicit if you take the time to
parse it:

request for member 'task' in '_tasks[((int)i)]',

You are requesting _tasks[i].task,

which is of non-class type

but _tasks[i] is not an object.

type 'taskDefinition [4]'

It is instead an array of four taskDefinition objects.

Edit: Fixing the answer to match the latest version of the question.
Your code works, but not quite as you expect it to work. You wrote:
complexTaskDefinition tasks [ ] [4] = ...;

Here you are defining a 2D array of objects, while your intention was to
define a one-dimensional array (why do I feel like I am repeating
myself?).
complexTaskDefinition tasks [ ] [4] = {
    {taskC1, true, -1, 1000 },
    {taskC2, true, 10, 2000 },
    {taskC3, false, 3, 3000 },
};

This definition, although syntactically correct, is awfully wacky. You
are defining tasks as an array of 3 items. Each item is itself an
array of 4 objects, where the first object of the array is explicitly
initialized, and the three others are implicitly initialized to
all-bits-zero. So basically your definition is equivalent to this
explicit version:
complexTaskDefinition tasks [3] [4] = {
    {{taskC1, true, -1, 1000 }, {nullptr, false, 0, 0},
     {nullptr, false, 0, 0},    {nullptr, false, 0, 0}},
    {{taskC2, true, 10, 2000 }, {nullptr, false, 0, 0},
     {nullptr, false, 0, 0},    {nullptr, false, 0, 0}},
    {{taskC3, false, 3, 3000 }, {nullptr, false, 0, 0},
     {nullptr, false, 0, 0},    {nullptr, false, 0, 0}}
};

Then you wrote:
task = tasks [ i ];

Here, tasks[i] is a row of the 2D array, i.e. a 1D array of 4 objects,
whereas task is a pointer to object. The assignment is legit because
here, like in most contexts, the array “decays” to a pointer to its
first element. The above line is equivalent to the explicit version:
task = &tasks[i][0];

Quite fortunately, this happens to point to one of the elements of the
array that has been explicitly initialized!
As an illustration of the above, here is a modified version of
showComplexTaskList() that loops over all the tasks in the array:
void showComplexTaskList () {
    Serial.println ( F ( "\nComplex Task List:" ) );
    Serial.print(F("number of tasks: "));
    Serial.println(sizeof tasks / sizeof(complexTaskDefinition));
    for (uint8_t i = 0; i < TASK_COUNT; i++) {
        for (uint8_t j = 0; j < 4; j++) {
            task = &tasks[i][j];
            Serial.print ( '[' );
            Serial.print ( i );
            Serial.print ( F ("]["));
            Serial.print ( j );
            Serial.print ( F ( "] REPEAT:" ));
            Serial.print ( ( task->repeat ) ? "YES" : "NO" );
            Serial.print ( F ( ", DELAY:" ) );
            Serial.print ( task->delay );
            Serial.print ( F ( ", ITERATIONS:" ) );
            Serial.print ( task->iterations );
            Serial.println ();
        }
    }
}

Its output is:
Complex Task List:
number of tasks: 12
[0][0] REPEAT:YES, DELAY:1000, ITERATIONS:-1
[0][1] REPEAT:NO, DELAY:0, ITERATIONS:0
[0][2] REPEAT:NO, DELAY:0, ITERATIONS:0
[0][3] REPEAT:NO, DELAY:0, ITERATIONS:0
[1][0] REPEAT:YES, DELAY:2000, ITERATIONS:10
[1][1] REPEAT:NO, DELAY:0, ITERATIONS:0
[1][2] REPEAT:NO, DELAY:0, ITERATIONS:0
[1][3] REPEAT:NO, DELAY:0, ITERATIONS:0
[2][0] REPEAT:NO, DELAY:3000, ITERATIONS:3
[2][1] REPEAT:NO, DELAY:0, ITERATIONS:0
[2][2] REPEAT:NO, DELAY:0, ITERATIONS:0
[2][3] REPEAT:NO, DELAY:0, ITERATIONS:0

So your program works almost by chance: an error in the way you define
the array cancels an error in the way you use it. This kind of cancelled
error method is very bad programming practice. You are wasting memory in
unused complexTaskDefinition objects. More importantly, your code
doesn't express your intent, which makes the program way harder to
understand and to debug.
The fix is to declare a 1D array, as this has always been the intention:
complexTaskDefinition tasks [ ] = {
    {taskC1, true, -1, 1000 },
    {taskC2, true, 10, 2000 },
    {taskC3, false, 3, 3000 },
};

Now, you can check that this array does only have three tasks, as
reported by sizeof tasks / sizeof(complexTaskDefinition). To use the
array, you can use a pointer if you want:
task = &tasks[i];
// ...
Serial.print ( ( task->repeat ) ? "YES" : "NO" );

Or you can directly request a member of tasks[i], as in
void showComplexVersion () {
    Serial.println ( F ( "\nComplex Version:" ) );
    for (uint8_t i = 0; i < TASK_COUNT; i++) {
        tasks[i].task();
    }
}

Now I have a question for you. Since I already explained your 1D vs. 2D
array mistake in the first iteration of my answer, why did you persist
with this in your edited question? If you are going to blatantly ignore
the answers you get, at least say so in the question. This could save
time to those who might consider helping you.

I appreciate the hard work your did to explain this to me and I am learning a log. I did intend the array to be a 2D array, but my problem was with defining the task to be called within that array. I found a good post that showed me how to do that wit a callback and that worked... when the parent is the .INO file. See this post: https://arduino.stackexchange.com/questions/68299/parent-class-callback-from-child-class


text:
HTTPS GET request working on esp32 but not on esp8266
I'm trying to port my esp32 program to esp8266, and i've come across a problem where i can't get a response from a HTTPS GET request on esp8266, but on my esp32 the same code works fine.
The function i'm using looks like this:
void GetHTTP()
{
  if (WiFi.status() == WL_CONNECTED)
  {
    HTTPClient http;
    http.begin(requestURL);
    int httpCode = http.GET();
    if (httpCode > 0)
    {
      requestData = http.getString();
      GenerateTable();
      //GetDelimiterCount(requestData, delimiterStart);
    }
    http.end();
  }
}

I've also tried running my request with the esp8266 "BasicHttpsClient" and "BasicHttpClient", and in both cases the program returns the error: "connection failed" from https.errorToString(httpCode).s_str()
or http code "-1" without any API specific error codes.
I'm requesting from Trafiklab's realtime infromation v4 API And
the request looks somewhat like this:

https://api.sl.se/api2/realtimedeparturesV4.json?

I've omitted the API key and parameters i use from this URL. The response is also correct when requested by any browser.
Could this be something to do with SSL? I'm completely out of clues as to what the differences between esp32's and esp8266's http-client libraries might be. I'm also using the latest version of the ESP8266 Boards libraries (2.7.4).

see the examples of the ESP8266HttpClient library

I did. I mentioned that in my initial post.

look again. focus on the first parameter of http.begin in BasicHttpsClient

I ended up using

ESP8266WiFi.h

instead of

ESP8266WiFiMulti.h

This fixed both my original code and the basic HTTPS example. I still don't understand what difference it made though.