text:
How do arrays work?
It's been days now I'm trying to figure out how arrays work in Arduino IDE.
For better understanding, I assembled some pieces of code I found here and there to write this sketch:

#define arrayLength(x) (sizeof(x) / sizeof(int)) //array size

typedef struct {
  int note;
  int duration;
} BUZZER_NOTE ;

class Buzzer {

  public:

    BUZZER_NOTE notes[];  //-- Funny how the same declaration tried below DOES work if it's inside a class

};

void setup() {

  Serial.begin(9600);

//  BUZZER_NOTE notes[];  //-- Compilation error:

  int *bob;               //-- Declaring this way, shows no compilation errors, but prints out strange values
//  int bob[];            //-- Compilation error: "storage size of 'bob' isn't known"

  int bob1[] = {10, 20};
  int bob2[5] = {10, 20, 30, 40, 50};
  int bob3[] = {60, 70, 80};

  bob[0] = 10;
  bob[1] = 20;
  bob[2] = 30;
  bob[3] = 40;
  bob[4] = 50;
  bob[5] = 60;
  bob[6] = 70;   //-- No matter how many indexes I create, it will always show lenght of 2

  test(1);       //-- Calls the first function below, as expected
  test({1});     //-- Also calls the first function below, when the second one (with the array parameter) is expected

  test(bob);     //-- Length: 1 (expected 5); Size: 2 (?????) ; First Element: 163 (expected 10);
  test(bob1);    //-- Length: 1 (expected 2); Size: 2 (?????) ; First Element: 10  (ok);
  test(bob2);    //-- Length: 1 (expected 5); Size: 2 (?????) ; First Element: 10  (ok);
  test(bob3);    //-- Length: 1 (expected 3); Size: 2 (?????) ; First Element: 60  (ok);

}

void loop() {
}

void test(int a) {
  Serial.println("Called int function");
  Serial.println();
}

void test(int a[]) {
  Serial.println("Called array function");
  Serial.print("Length: ");
  Serial.println(arrayLength(a));
  Serial.print("Size: ");
  Serial.println(sizeof(a));
  Serial.print("First Element: ");
  Serial.println(a[0]);
  Serial.println();
}

The code above prints out these lines:
Called int function    // as expected

Called int function    // expected array function

Called array function  // as expected
Length: 1              // expected 5
Size: 2
First Element: 163     // expected 10

Called array function  // as expected
Length: 1              // expected 5
Size: 2
First Element: 10      // as expected

Called array function  // as expected
Length: 1              // expected 3
Size: 2
First Element: 10      // as expected

Called array function  // as expected
Length: 1              // expected 5
Size: 2
First Element: 60      // as expected

My goal for now is to achieve something like this:
int bob[]; // this gives a compiler error: "storage size of 'bob' isn't known"
bob = {10, 20, 30, 40};

test(bob);

void test(int arr[]) {
  for (int i = 0; i < FIND_ARR_LENGTH_SOMEHOW; i++) {
    Serial.print("Index i: ");
    Serial.println(arr[i]);
}

Question: How can I declare an array without mention its size, fill it up with as many indexes I want, then pass it to a function that will be able to process all the contents?
I know I could declare an array and keep its length to pass as a second parameter, but there must be a way to get an array length.
Thanks in advance.

https://majenko.co.uk/blog/arrays-pointers-what-c

#define arrayLength(x) (sizeof(x) / sizeof(int)) //array size is wrong! #define arrayLength(x) (sizeof(x) / sizeof(x[0])) might work if x is an array

@Majenko If I had found such an article before, it would have saved me several hours. Thanks a lot.

BUZZER_NOTE notes[];  //-- Funny how the same declaration tried below DOES work if it's inside a class

It doesn't really. C++ language prohibits that. It is just a non-standard quirk of GCC compiler used by Arduino IDE, which happens to support C-style flexible array members in C++ code.

//  BUZZER_NOTE notes[];  //-- Compilation error:

Of course. You are not allowed to use incomplete types in object definitions. And an array of unspecified size is an incomplete type. A widely used exception from this rule is an [] array declared with an initializer. In that case the array size is assumed to be implicitly specified by the initializer.

int *bob;               //-- Declaring this way, shows no compilation errors, but prints out strange values

Of course. This is not an array at all. It is a pointer. And it doesn't point anywhere. It is invalid. You are not allowed to even access such pointer.

//  int bob[];            //-- Compilation error: "storage size of 'bob' isn't known"

See above.

 int bob1[] = {10, 20};
 int bob2[5] = {10, 20, 30, 40, 50};
 int bob3[] = {60, 70, 80};

These are properly declared arrays. As I said above, the [] declaration is allowed since you are declaring your array with an initializer.

bob[6] = 70;   //-- No matter how many indexes I create, it will always show lenght of 2

This does not make any sense at all. You cannot "create indexes" in an array. Array size is fixed at the point of declaration. There's no way to shrink or expand it, there's no way to "create" or "remove" indexes.
But in this example bob is not even an array. It is a pointer. And since it is a garbage pointer that doesn't point anywhere, you are not allowed to access it with any indexes.
Once you make your bob to point to some valid block of memory, you will be able to access it as bob[3] and such, as long as you stay withing the bounds of that block of memory.

test({1});     //-- Also calls the first function below, when the second one (with the array parameter) is expected

Several mistakes here.
Firstly, you second function does not have "array parameter". In parameter declarations int a[] is equivalent to int *a. It is a pointer parameter, not an array parameter.
Secondly, since the beginning of times in C and C++ you could use a scalar value in {} to initialize a scalar object
int a = { 42 }; /* <- this has always been legal in C and C++ */

So, the first function is obviously a candidate in this case. The rules of C++ language dictate that {1} initializer can be used as an initializer for an int value or std::initializer_list<int> object, but for a pointer. Which is why the first function is called.
You can force it to produce a temporary array through array-type alias and functional-cast syntax
using ARR = int[];
test(ARR{1});

but in GCC you will run into a GCC bug preventing you from forming pointers and references to temporary arrays (Clang will accept it).

void test(int a[]) {
  ...
  Serial.print("Length: ");
  Serial.println(arrayLength(a));

This makes no sense. This "array length" trick
#define arrayLength(x) (sizeof(x) / sizeof(int))

only works with arrays. Your a inside test is not an array. It is a pointer. It is completely pointless to apply this sizeof trick to a pointer.

My goal for now is to achieve something like this:
int bob[]; // this gives a compiler error: "storage size of 'bob' isn't known"
bob = {10, 20, 30, 40};

Not possible. When defining an array, you always have to specify a fixed compile-time size. And arrays in C and C++ are not copyable, not assignable. If you want to copy data between arrays, you have to either do it manually, element by element, or use a library-provided routine that does the same.
{}- initializers can be used with arrays, but only at the point of declaration. Not later. You can do something like
using A = int[5];
A a;
std::memcpy(a, A{1, 2, 3, 4, 5}, sizeof(A));

but this will run into the same GCC bug I mentioned above.
On a related note: standard library provides std::array template - a thin wrapper for raw arrays. std::array objects are copyable and assignable through a pretty much the same syntax as you used
std::array<int, 5> a;
a = { 1, 2, 3, 4, 5 };

But they are still arrays of fixed compile-time size.

void test(int arr[]) {
  for (int i = 0; i < FIND_ARR_LENGTH_SOMEHOW; i++) {

Not possible. Your arr is a pointer. It is not possible to extract "array size" information for a pointer, since that information simply does not exist. If you want to "FIND_ARR_LENGTH_SOMEHOW" you have to either develop your own convention for finding that length or simply pass that length to the function through a separate parameter.

I apologize for the silly question. I'm not used with c / c++ programming and was just trying to write a library while I learn nothing. Never really had to deal with pointers with the languages I'm used to.
Anyways, your explanations are pretty enlightening. I will have to dig some more about pointers and memory stuff.
Thank you.

This is more of a general programming question, but since there are some special pitfalls for microcontrollers/Arduinos I will answer the question.

How can I declare an array without mention its size, fill it up with as many indexes I want, then pass it to a function that will be able to process all the contents?

Short answer: You cannot. An array has always a fixed size, that cannot be changed during the lifetime of the array.
Long answer: Though every array has it's fixed size, you can create new arrays with a size, that is not known at compilation time. For this you would need dynamic memory allocation like done with the new keyword:
BUZZER_NOTE *notes = new BUZZER_NOTE[x];

with the size of the new array x. notes is here a pointer to the array (actually a pointer to the first element of the array). If you don't know, how to deal correctly with pointers, you should google for a tutorial about it, there are plenty on the web. So, if your defined array is full and you want to add more elements, you have to define a new array with bigger size, copy the old content and delete the old one (actually that is what happens inside the String class).
To actually get the easy way of adding more elements, without copying the whole content, a C++ programmer would use a linked list. This defines an element class, that contains a variable for the content of the element and a pointer to the next element in the list. So to iterate through the linked list, you would start at the first element and follow the pointers through the list to the end. (Again you can read more about this concept on the web)
BUT: You should not use any of these things on an Arduino, especially not on the ones with very limited RAM (like Uno, Nano, ...). When you do dynamic memory allocation, memory fragmentation will happen. Take the example from above. You have a dynamically allocated array with your data. Now you want to store more data. You define a new and bigger array. For the simplicity of explanation, it will be allocated directly after the first array in the memory. You copy the content and delete the first array to free the memory. Now there is free space in your memory with the size of the first array. Now you want to again add more data, so you define a new and bigger array. This array cannot fit into the free space at the start, since the space to not big enough. This memory space is now dead, because it cannot be used for your data.
In real cases, you would allocate and delete variables with varying sizes throughout your sketch. This leads to the point, that you will get many holes in your memory, which are too small to fit your data in. On a PC this is not a big problem, since you have a lot of RAM and the OS can reorganize the data to fit better. But on the Arduino you have only very limited RAM and no OS, so you quickly run out of RAM. Your sketch will stop to work at that point, since there is no usable memory left on the device.
You instead should go the harder way and just use fixed arrays, that are big enough to hold the biggest amount of data, that you expect.

And since AnT didn't cover this completely:
bob[6] = 70;

This line cannot work correctly for 2 reasons: First you only declared bob as a pointer, but this pointer does not point to a valid memory address. You would have to create a corresponding array with the new keyword as shown above, or let it point to an existing array. Currently you try to write to an invalid or random memory address.
Secondly the compiler cannot know, how many items the array has, that bob should point to. This is just not an information, that the compiler has. So it will not prevent you from writing higher indices, than are in the array. But effectively the memory write either fails, because the address of the non-existent element is invalid, or you will overwrite data from some other variables --> Very dangerous! It is your responsibility to ensure, that you don't write data, where it does not belong.
And keep in mind, that microcontrollers don't have something like exceptions. Thus some things, that would through an exception on a PC will stop the microcontroller from working, or it will just do the crazy stuff, that you told him to do (where accessing memory outside of the array would through a runtime error on the PC).

Yeah, that makes a whole lot of sense. I'm trying to write a general purpose library for NodeMCU, which has a lot of memory (I guess) and that wouldn't be an issue.
But considering I could be using it in other projects for other Arduino models, your answer clarifies a lot of things.
Thanks.

Ok, after reading and reading the answers and links about my question, I ended up using a function as suggested. Something like:
void foo(char* myArray, int size) {}

But I ended up finding another solution to the problem, which is a little more complicated:
#define arrayLen(x) (sizeof(x) / sizeof(x[0]))

char myArray[64] = "my array test with a long value in it";

void setup() {

  Serial.begin(9600);
  while (!Serial);

  // IMHO, it would be nice if the compiler would accept these two sintaxes
//  myArray = "my array test with a long value in it";
//  "my array test with a long value in it".toCharArray(myArray, 64);

  Serial.print("Value before: ");
  Serial.println(myArray);
  Serial.print("Size before: ");
  Serial.println(arrayLen(myArray));

  String temp;
  temp = myArray;

  foo(temp);

  Serial.print("Value after: ");
  Serial.println(myArray);
  Serial.print("Size after: ");
  Serial.println(arrayLen(myArray));

}

void loop() {}

void foo(String str) {
  for (int i = 0; i < str.length(); i++) {
    Serial.print("Index ");
    Serial.print(i);
    Serial.print(": ");
    Serial.println(str.charAt(i));
  }
}

I know I have a bad habit to use Strings instead of array of chars (coming from other languages), but in this example, memory limitation issues won't be significant because the String will be freed from memory after execution of setup() and foo().
There is another thing I would like to share (not directly related to my previous question), that I believe could be useful for other people.
This little sketch shows how to use the same String technique to manipulate the contents of a char array, passed by reference to an external function. Here it goes:
#define arrayLen(x) (sizeof(x) / sizeof(x[0]))

char myArray[64] = "my array test with a long value in it";

void setup() {

  Serial.begin(9600);
  while (!Serial);

  Serial.print("Value before: ");
  Serial.println(myArray);
  Serial.print("Size before: ");
  Serial.println(arrayLen(myArray));

  String temp;
  temp = myArray;

  foo(temp);
  temp.toCharArray(myArray, 64);

  Serial.print("Value after: ");
  Serial.println(myArray);
  Serial.print("Size after: ");
  Serial.println(arrayLen(myArray));

}

void loop() {}

void foo(String &str) {
  str = "abcde";
}

Results (just as expected):
Value before: my array test with a long value in it
Size before: 64
Value after: abcde
Size after: 64

It may look awful to the eyes of a C++ programmer, but hey, it works!
Thanks again for all the answers/comments.

The C arrays are tricky and they're described in every C tutorial. The other answers adresses mistakes / questions in comments, but none of them shows how it can be done:

struct BuzzNote {
  int note;
  int duration;
};

const BuzzNote melody[] = {
  {10, 200}, { 45, 300}, {90, 200}, // ...
};

void test(BuzzNote const * arr, size_t len) {
  for (size_t i = 0; i < len; ++i) {
    Serial.print(i);
    Serial.print(". ");
    Serial.print(arr[i].note);
    Serial.print(' ');
    Serial.println(arr[i].duration);
  }
}

// using template for determining size of array
// (and as a bonus it won't work with plain pointers)
template<typename T, size_t size>
size_t GetArrLength(T(&)[size]){return size;}

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

void loop() {
  test(melody, GetArrLength(melody));
  delay(10000);
}

I'm using template version of getting array length (it won't compile with pointers, as pointer isn't array).
And this version stores data in RAM (and waste it). If you don't have spare space in ram, you'll have to dig into PROGMEM variables/arrays. But it's the quest for another day :D


text:
Weird sound when modulating the pulse width on Arduino
I'm trying to generate a pulse width modulated sound using Arduino Nano.
But it generates the weird sound unlike my expectation.
Here's my code:
class Phasor
{
public:
    Phasor(const float frequency)
    :frequency(frequency)
    ,phase(1.0f)
    ,lastTimeMicros(0){};
    virtual ~Phasor(){};
    void setFrequency(const float frequency)
    {
        this->frequency = frequency;
    }
    float process()
    {
        const unsigned long currentTimeMicros = micros();
        if (phase == 1.0f) lastTimeMicros = currentTimeMicros;
        const unsigned long elapsedTimeMicros = currentTimeMicros - lastTimeMicros;
        const unsigned long cycleDurationMicros = static_cast<unsigned long>(1000.0f / frequency) * 1000;
        if (elapsedTimeMicros < cycleDurationMicros)
            phase = static_cast<float>(elapsedTimeMicros) / static_cast<float>(cycleDurationMicros);
        else
            phase = 1.0f;
        return phase;
    }
private:
    float frequency;
    float phase;
    unsigned long lastTimeMicros;
};

class PulseOsc
{
public:
    PulseOsc(const float frequency, const float pulseWidth)
    :phasor(frequency)
    ,pulseWidth(pulseWidth){};
    virtual ~PulseOsc(){};
    void setFrequency(const float frequency)
    {
        this->phasor.setFrequency(frequency);
    }
    void setPulseWidth(const float pulseWidth)
    {
        this->pulseWidth = pulseWidth;
    }
    float process()
    {
        const float phase = phasor.process();
        if (phase <= pulseWidth)
            return 1.0f;
        else
            return -1.0f;
    }
private:
    Phasor phasor;
    float pulseWidth;
};

Phasor *phasorLFO;
PulseOsc *pulseOsc;

void setup()
{
    Serial.begin(9600);
    pinMode(9, OUTPUT);
    phasorLFO = new Phasor(0.1f);
    pulseOsc = new PulseOsc(440.0f, 0.5f);
}

void loop()
{
    pulseOsc->setPulseWidth(phasorLFO->process());
    int outVal = LOW;
    if (pulseOsc->process() > 0.0f) outVal = HIGH;
    digitalWrite(9, outVal);
}

The resulting sound is very weird and glitchy.
It works fine when I fix the pulse width value. (without LFO)
What is wrong with my code?
How do I fix this? I would appreciate any advice.

Probably the Nano isn't powerful enough to do all those floating point calculations in a timely manner.

I see two issues with this program. The first one has already been
pointed out by Majenko in a comment: you are doing too much floating
point calculations. The second has to do with the way your Phasor
manages the time.
If you take a look at the Blink Without Delay Arduino tutorial, you
will see something along these lines:
if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    toggle_the_LED();
}

In this code, interval is the minimum time between toggles. Whenever
the program gets a little bit late and currentMillis - previousMillis
is strictly larger than interval, this extra time is lost and the
program will be late for all the subsequent LED toggles. If instead of
the minimum you are interested in the average time between toggles,
then you should write:
if (currentMillis - previousMillis >= interval) {
    previousMillis += interval;  // <- advance by exactly one period
    toggle_the_LED();
}

Now, previousMillis is no more the time when the last toggle was
performed, it is the time when the last toggle was scheduled. With
this version you can still have some jitter, but at least the average
frequency should be right. If the program is so busy that it can get
late by a full period, then it would be better to replace the if by a
while, in order to catch up all the missed periods.
Your Phasor::process() method is a little bit more involved than the
tutorial above, yet the line
if (phase == 1.0f) lastTimeMicros = currentTimeMicros;

is going to get you out of schedule for exactly the same reason.
That being said, here is my take at your phasor idea, completely
untested:
class Phasor()
{
public:
    Phasor(float frequency_Hz)
    {
        period = round(1e6 / frequency_Hz);
        frequency = 0x10000 / period;
    }
    uint16_t process()
    {
        uint16_t now = micros();
        while (now - last_time >= period)
            last_time += period;
        return (now - last_time) * frequency;
    }
private:
    uint16_t period;     // unit = 1 us
    uint16_t frequency;  // unit = 1/(2^16 us) ~ 15.3 Hz
    uint16_t last_time = 0;
};

I changed a few things from your implementation:

removed the setFrequency() method because YAGNI
no floating point except in the constructor, for performance reasons
only 16-bit arithmetics, for the same reason
no division in process(), because division is expensive
the phase is not stored, because there is no use to storing it
the phase is an integer in units of 2−16 periods

Note that the unit chosen for the phase is the most natural one when
dealing with 16-bit arithmetics. Note also that storing microseconds in
16-bit variables only works for frequencies higher than 15.3 Hz. A
very low frequency phasor (your “LFO” for instance) would need 32-bit
arithmetics.

Seems like you are using the system clock micros() to  calculate elapsedTimeMicros, so probably the time spent on the process of calculation and sending signal to the pin may affect it, which may lead to inconsistent duty cycle.

source: Stack Exchange

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

sort: votes


text:
Strange cyclic errors in analogRead on Nano
I am trying to build an emergency shutdown of a gas valve based on the output of a smoke detector.
It basically measures the voltage on the buzzer of the smoke detector, and if high enough, changes the direction of the motordriver, which is  connected to an actuator (with automatic shutdown) that operates the gas valve.
A button is used to reset the alarm.
The actual setup is soldered on a prototype board, but below the layout as a breadboard.

The nano is powered by a step down converter connected to the 5V pin, that in turn is powered by the 12V power supply that also drives the actuator. Its output is 5.13V according to my multimeter, and seems stable when I measure it.
The problem I have is that the system continuusly enters alarm state.
After some experimenting I have found out that when I short the analog pin to ground, I always read 0, but when I use a resistor, as in the breadboard layout, I get a couple of 0 readings, then a sort of peak, that goes back to 0, and that behaviour in a cycle of approximately 10 sec.
The cyclic pattern is consistent, the values differ depending on how I power the system (external of from the USB of my PC), and whether I connect the smoke detector or use the resistor.
Below the code (I left out the utility functions for brevity), and the output when I use the 100k resistor between A2 and ground, with the board powered by the USB connection.
Can anyone explain what is going on here?
void setup() {
  bool storedAlarm;

  initOutput(activeLedPin);
  initOutput(alarmLedPin);
  initOutput(gasValveIn1Pin);
  initOutput(gasValveIn2Pin);

  EEPROM.get(0,storedAlarm);
  alarm = false;

  Serial.begin(9600);
  Serial.print("start with Alarm ");
  Serial.println( storedAlarm ? "ON" : "undetermined" );

  digitalWrite(activeLedPin, HIGH);
  blinkAlarmLed(500,333,3);

  if (storedAlarm) {
    switchAlarmOn();
  }
  // never switch off automatically
  // if the valve is open it will stay open
}
void loop() {
  int sensorValue = analogRead(sensorPin);
  bool reset = digitalRead(alarmResetPin);

  Serial.println(sensorValue);
  if ( sensorValue > 500 ) {
    switchAlarmOn();
    if (reset) {
      blinkAlarmLed(100,100,7); // show refusal
    }
  }
  else if ( reset ) switchAlarmOff();

  delay(800);
}

Output:
14:01:08.587 -> start with Alarm ON
14:01:11.061 -> alarm
14:01:11.367 -> 36
14:01:12.148 -> 35
14:01:12.963 -> 9
14:01:13.778 -> 0
14:01:14.559 -> 0
14:01:15.374 -> 0
14:01:16.155 -> 0
14:01:16.970 -> 0
14:01:17.784 -> 0
14:01:18.564 -> 0
14:01:19.380 -> 0
14:01:20.161 -> 0
14:01:20.974 -> 0
14:01:21.787 -> 17
14:01:22.568 -> 62
14:01:23.383 -> 65
14:01:24.162 -> 67
14:01:24.977 -> 54
14:01:25.791 -> 137
14:01:26.570 -> 104
14:01:27.385 -> 29
14:01:28.165 -> 17
14:01:28.980 -> 0
14:01:29.795 -> 0
14:01:30.575 -> 0
14:01:31.390 -> 0
14:01:32.171 -> 0
14:01:32.986 -> 0
14:01:33.801 -> 0
14:01:34.581 -> 0
14:01:35.397 -> 0
14:01:36.178 -> 0
14:01:36.993 -> 37
14:01:37.809 -> 64
14:01:38.589 -> 69
14:01:39.404 -> 64
14:01:40.184 -> 34
14:01:40.997 -> 136
14:01:41.811 -> 120
14:01:42.592 -> 46
14:01:43.406 -> 16
14:01:44.187 -> 8
14:01:45.003 -> 0
14:01:45.784 -> 0
14:01:46.600 -> 0
14:01:47.415 -> 0
14:01:48.196 -> 0
14:01:49.012 -> 0
14:01:49.793 -> 0
14:01:50.607 -> 0
14:01:51.422 -> 0
14:01:52.201 -> 0
14:01:53.016 -> 0
14:01:53.796 -> 0
14:01:54.611 -> 28
14:01:55.427 -> 53
14:01:56.208 -> 65
14:01:57.022 -> 72
14:01:57.803 -> 68
14:01:58.617 -> 73
14:01:59.432 -> 0
14:02:00.212 -> 140
14:02:01.027 -> 136
14:02:01.808 -> 101
14:02:02.622 -> 46
14:02:03.437 -> 22
14:02:04.218 -> 16
14:02:05.032 -> 8
14:02:05.812 -> 0
14:02:06.627 -> 0
14:02:07.409 -> 0
14:02:08.224 -> 0
14:02:09.038 -> 0
14:02:09.820 -> 0
14:02:10.633 -> 0
14:02:11.415 -> 0
14:02:12.231 -> 0
14:02:13.047 -> 0
14:02:13.828 -> 0
14:02:14.642 -> 0
14:02:15.422 -> 40
14:02:16.237 -> 73
14:02:17.050 -> 72
14:02:17.830 -> 65
14:02:18.644 -> 11
14:02:19.427 -> 131
14:02:20.240 -> 108
14:02:21.054 -> 61
14:02:21.834 -> 18
14:02:22.648 -> 14
14:02:23.428 -> 0
14:02:24.242 -> 0
14:02:25.058 -> 0
14:02:25.839 -> 0
14:02:26.654 -> 0

Please try to connect the resistor between A2 and Arduino ground as close as possible to GND pin.

Try it with a much lower value resistor. 100k is perhaps just too large

With a 20k resistor directly between the Pin and ground the cyclic behaviour is still there, although the max value is then 20.

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


text:
HX711 with NodeMcu
I am trying to make a scale that measuring weight. In internet i did some researches so i got some questions.
I have this module as a HX711
And square 3 wired loadcells( Red,White,Black Wired).
My mcu is Noedmcu V3. When i check from the Visual Studio Code, it says Adafruit Huzzah. This MCU's operation voltage is 3.3v and got ESP8266EX chip.
Some Hx711 modules (ex. sparkfun red board) got VDD pin for logic level. But my module has not. Can i operate this hx711 and loadcell with 3.3 volts?
If i cant, i can use 5volts for excitation voltages but communication will be on 5Volts. My mcu operating on 3.3volts. can i add voltage divider to  DT,SCK pins to regulate voltage around 3.3volts? Is it proper solution?
Or if you have any hint about that, can you share with me?

Vdd pin is for a power connection, not for a logic signal .. it can also be labeled as Vcc ... use the datasheet to determine the required power supply voltage

My hx 711 has no vdd. Only has vcc. In sparkfuns hook up guide  They said :
Note: VCC is the analog voltage to power the load cell. VDD is the digital supply voltage used to set the logic level. PRO TIP: In many cases, you can just short VCC and VDD together. If your microcontroller uses 3.3V logic however, you'll want to connect VCC to 5V and VDD to 3.3V.
But my question is I have 3.3volt mcu and hx 711 wants 5volt. Can i use voltage divider for DT and SCK lines to decrease voltage to 3.3 volts.

i have the same issue. tried modifying the board to separate VCC and VDD (they are connected by a copper trace hidden under the chip) but it did not work. It seems the chip does not care for VCC pin (pin 1 on datasheet) and only listens to VDD


text:
random characters
I am using arduino mega with LCD 4X20 character to measure weight by 40 kg load cell and pt 100 to measure the temp. I have 4 output to 4 relay module. all are powered from 12vdc /3 amp Power supply..
the problem is.. the display started normally showing every thing perfectly.. but when the output comes out and the loads runs.. random characters appear
is the power supply is not enough? or another problem..
Please advice.

Please show you circuit and your code

start with a simple sketch that displays 0123456789abcdefghij on every line ... then wiggle wires

Do you know what character generator ROM is built into that HD44780 4X20 display? What signals have you wired from your Arduino? Have you tied the R/W line to GND?

Please read How to ask a good question for Arduino Stack Exchange

@Ashraf Nassar There could be a number of reasons for this, from connection issues to bad libraries

Does this answer your question? Why does my LCD display random characters?

Random Characters can Happen in several ways.

Check the Wires for: Loosen Ends; Broken Wires and Wrong Pin Connections.
Check your Code.

I'd suspect that it is a software error. Did you check your circuit if it induces desync between the Arduino and the LCD, or did you just use the wrong drivers?


text:
Arduino 1.8.9 Won't Load
I recently upgraded my windows10 from version 1803 to 1903. I had to do a clean install to accomplish it though, but my question is, I downloaded Adriano IDE 1.8.9 and installed it but it won't launch. It starts, then the window closes and that's it. Does anybody have any thoughts on what's going on? Or better yet what's not going on?
Thanks, Dennis

Where did you download the IDE from?

Does 1.8.10 work? https://www.arduino.cc/en/Main/Software

Do you have a Java runtime installed? If so, what version?

I downloaded Arduino IDE 1.8.10 directly from Arduino.cc. I thought of the Java issue and downloaded the latest version for Windows10, 8.221(build 1.8.0_221-b11), and it's running. Oh, and I tried to load and run Arduino IDE version 1.8.9 that I'm running on my other machine, and it didn't run either. Seems like there is something in this new OS that Microsoft is not telling us about.


text:
I2C Communication with the ICM-20789
I am trying to interface with the ICM-20789 over I2C. DataSheet
I have been successfully able to get all three gyroscope readings and all three accelerometer readings. I am now trying to get the pressure readings from the device, since it has a built-in pressure sensor, but cannot seem to get it working.
In the datasheet, it says to enable Bypass Mode.

Bypass Mode: Set register INT_PIN_CFG (Address: 55 (Decimal); 37 (Hex)) bit 1 to value 1 and I2C_MST_EN bit is ‘0’
  (Address: 106 (Decimal); 6A (Hex). Pressure sensor data can then be accessed using the procedure described in Section 10

In the setup I use this code:
  Wire.beginTransmission(gyro_address);
  Wire.write(0x37);      //INT_PIN_CFG
  Wire.write(0x02);      //00000010
  Wire.endTransmission();

I am having trouble finding I2C_MST_EN in the datasheet as well, as I cannot find it in the 6A Address.
Once I have the bypass bit enabled, I try to request the pressure and temperature data from the sensor using this code:
Wire.beginTransmission(0x63);
Wire.write(0x7866);
Wire.endTransmission();
Wire.requestFrom(0x63, 16);

while (Wire.available() < 16);
pressure = Wire.read() << 16 | Wire.read() << 8 | Wire.read();
temp_2   = Wire.read() << 16 | Wire.read() << 8 | Wire.read();

Unfortunately, the device freezes when I try to run this code. I know I am obviously doing something wrong here, just don't know exactly what yet.

Wire.write(0x7866); will truncate your value to just 0x66. You can only write 8 bits at a time.

There are four things wrong with your code.

You are not sending the "start measurement" command properly. The Wire.write() function can only send 8 bits, but you are passing it a 16-bit value. Instead you should break it apart into 2 separate 8-bit values:
Wire.beginTransmission(0x63);
Wire.write(0x78);
Wire.write(0x66);
Wire.endTransmission();
The data returned is spread over 9 bytes, not 16.  According to the datasheet:

Temperature data is transmitted in two 8-bit words and pressure data is
  transmitted in four 8-bit words.

and:

Two bytes of data are always followed by one byte CRC checksum

That's 2 + 4 = 6 + (6/2) = 9

You aren't waiting for the conversion to complete. According to the datasheet, in "ultra low noise" mode (0x7866) it takes up to 94.5ms to perform the measurement.  So you should add a delay of slightly more than that to allow it to do what it needs to do.
The command you are sending responds with temperature first, not pressure, but you are reading pressure first (and reading the wrong bytes anyway).

In all, your code should look more like:
Wire.beginTransmission(0x63);
Wire.write(0x78);
Wire.write(0x66);
Wire.endTransmission();

delay(100);

Wire.requestFrom(0x63, 9);
uint8_t tmsb = Wire.read(); // Temperature highest byte
uint8_t tlsb = Wire.read(); // Temperature lowest byte
Wire.read();

uint8_t pmmsb = Wire.read(); // Highest pressure byte
uint8_t pmlsb = Wire.read(); // Next highest pressure byte
Wire.read(); // Discard checksum
uint8_t plmsb = Wire.read(); // Next lowest pressure byte
uint8_t pllsb = Wire.read(); // Lowest pressure byte
Wire.read(); // Discard checksum

pressure = (pmmsb << 24) | (pmlsb << 16) | (plmsb << 8) | pllsb;
temp_2   = (tmsb << 8) | (plsb << 8);

Thank you Majenko! That makes more sense. I have added that code to my loop. My code is still freezing though. It happens when I add this code in the setup to enter bypass mode: Wire.beginTransmission(0x63);
Wire.write(0x78);
Wire.write(0x66);
Wire.endTransmission();

That's not the code to enter bypass mode - that's the code to start a pressure conversion.

My apologies, I copied over the wrong code. When I have these lines of code on my setup, the code freezes.
Wire.beginTransmission(gyro_address);
Wire.write(0x37);      //INT_PIN_CFG
Wire.write(0x02);      //00000010
Wire.endTransmission();


text:
Copy one SD card to another
I want to copy an SD card to another.
What is the best way to attack this problem?
Should i get two sd card shields?
If yes, is it possible to stack two together, or will there be problems with the interface protocols (SPI/I2C)?

Why would you want to do this with an Arduino when you can do it on a PC so easily?

Because sometimes, a pc just isn't available.

Fair enough then.

It should be perfectly possible to do it. As long as the SD cards and shields play ball then there should be no problem from a hardware perspective.
From a hardware perspective you should be able to share the MOSI, MISO and SCK lines and just have separate CS pins per card.
However some SD card shields employ level translation that doesn't properly release the SPI bus when idle, and some cheap SD cards don't release the bus in a timely manner too.
From a software perspective though it may be a different matter. I am not sure how well you can run two instances of the SD classes at once on an Arduino.  You may be better off looking at FatFS instead which is far more flexible.
You have two strategies when copying cards, each of which has a different way of programming it.

Block copy the entire card: this involves reading a 512 byte block from one card and writing it to the other one.  This would be the most efficient from a resource perspective (you don't need to care about the contents of the card, so don't need any filesystem code), but if the card is not close to full it will be very inefficient from a runtime perspective. Also the two cards have to be the same size for it to work well.
File copy. For this you need much more complex code, but it you only copy each file from one card to the other. It's much better though if the cards don't have much data on them - also the cards can be different sizes.

The time it takes to block-copy a complete "small" 16 GB SD-card via SPI is probably longer than finding a PC around  :)

Maybe, if two arduinos - where each has an SD card shield, and they communicate somehow? Maybe this is a better choice?


text:
RtcUtility.h: No such file or directory
I have a problem with remaining headers. Can't seem to find the first header "RtcUtility.h". Anyone how to fix? I've provided a picture for you to see.

Error Messages:

Arduino: 1.8.10 (Windows 7), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Disabled, All SSL ciphers (most compatible), 4M (no SPIFFS), v2 Lower Memory, Disabled, None, Only Sketch, 115200"
sample_time:6:24: error: RtcUtility.h: No such file or directory
Multiple libraries were found for "ArduinoOTA.h"
   #include
Used: C:\Users\user\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ArduinoOTA
                          ^
Multiple libraries were found for "Wire.h"
  compilation terminated.
Used: C:\Users\user\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\Wire
  Multiple libraries were found for "ESP8266WiFi.h"
   Used: C:\Users\user\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266WiFi
  Multiple libraries were found for "ESP8266mDNS.h"
   Used: C:\Users\user\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266mDNS
  exit status 1
  RtcUtility.h: No such file or directory
This report would have more information with
  "Show verbose output during compilation"
  option enabled in File -> Preferences.

Please add the RTC library in the Arduino as below.
Open the Library Manager and search for "Rtc by Makuna" and install.
You can also checkout the Github page for that particular library at
https://github.com/Makuna/Rtc


text:
NodeMCU current consumption in all modes
I am using NodeMCU for my project.I wanted to know how much current it takes in its all modes like sleep mode,deep sleep mode and also in its wifi modes like station and access point mode.
Thanks in advance...

have you checked the datasheet?

count the consumption of the USB chip too


text:
Nodemcu is connected to 5v relay with logic converter but still not working
I am using a bi-directional 3.3-5V logic converter to control 5V relay with 3.3V D5 pin of nodemcu. link of logic  converter is here
However, I expected to control the relay but it didn't work. I don't think there is a problem with electrical connection or code since that is simple.
3.3V sides of nodemcu is connected to LV and 5V side of Relay is connected to HV.
Code:-
void setup() {
  // put your setup code here, to run once:
pinMode(D5, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
digitalWrite(D5, HIGH);
delay(2000);
digitalWrite(D5, LOW);
delay(2000);
}

My Observations:-
1) When relay is removed, multimeter shows 3.3V at the LV & HV side. (so logic converter is not working i guess)
2) When relay  is  connected, multimeter shows 2.5V on  both sides.
Everything is powered from nodemcu pins. Does  it means that i have to supply extenal power or something wrong with logic converter?[![enter image description here][2]][2]
What do you guys think?
PS  - I  soldered the pins another way around on logic converter. Does it change anything?
circuit image, nodemcu is powered by the laptop USB

Please show your actual wiring.

Are you trying to drive a pure relay, or do you have a relay module (which already includes the driver circuit). If the first, make sure, that the level converter can actually provide the needed current

The photograph you provide is not helpful. Instead, show us the schematic of your actual circuit and provide a link to the manufacturer's datasheet for the level converter and the relay.

Its the relay module that I am running. I provided  that above photo to check if I  soldered right side. Will the logic converter work if I soldered behind? will  add  the  circuit  also

can anybody draw wiring diagram for raspberry pi to relay connection?

You must supply a steady, regulated voltage to both 3.3v and 5v pins at all time (see Voltage Inputs on https://learn.sparkfun.com/tutorials/bi-directional-logic-level-converter-hookup-guide/all).
Logic level controller does NOT convert 3.3v to 5v for powering the relay, it just let you turn 3.3v signal to 5v so a relay can get activated. Relay's positive pin still needs to be supplied with a 5v from a PSU or other sources.

To make that work you'd need to connect the HV connection to the Vin of the NodeMCU (as well as to the relay board) which should be the 5 V coming form the USB port. You'd also need to connect the GND on the HV side to the GND of the NodeMCU.

Exactly. Although the GND sides are probably connected, the 5V needed for the relay and logic conversion needs to be supplied from somewhere. It will not be generated by the logic level converter.

The converter and/or the nodemcu can't provide enough current to drive the relay. So you should get a 5V psu.
For further details we need more information about the parts you use.

could be, I put arduino instead of nodemcu  since it has 5V pins and worked


text:
LED and MOTOR "ON" when A BLE DEVICE APPROACH ESP32 MICROCONTROLLER DFR0575
I have this code that is working perfectly but I want my device to start vibrating too (right now only the led is working)
On a Wemos Battery Module I have simply connected the vibration motor on the same PIN of the LED and it works perfectly.
Now I want to do the same on an Beetle ESP32 Microcontroller DFR0575. I used the same code But I can't make the module vibrating (The led light is working perfectly)
this is the code:
 #include <BLEAdvertisedDevice.h>
   #include <BLEDevice.h>
   #include <BLEScan.h>

   const int PIN = 2;
   const int CUTOFF = -50;

   void setup() {
     pinMode(PIN, OUTPUT);
     BLEDevice::init("tkr");
   }

   void loop() {
     BLEScan *scan = BLEDevice::getScan();
     scan->setActiveScan(true);
     BLEScanResults results = scan->start(1);
     int best = CUTOFF;
     for (int i = 0; i < results.getCount(); i++) {
       BLEAdvertisedDevice device = results.getDevice(i);
       int rssi = device.getRSSI();
       if (rssi > best) {
         best = rssi;
       }
     }
     digitalWrite(PIN, best > CUTOFF ? HIGH : LOW);
   }

Are you connecting the vibration motor directly to a digital output pin? Or are you using some kind of driver (for example a transistor)?

In Wemos Battery Module I connect the vibration in the digital output pin. But the same things does not work on the Beetle ESP32 Microcontroller DFR0575 I don't know why..

What type of Battery Module do you have? Can you provide a link? Googling, I found different battery shields for the Wemos. Please also say, to which pin you connected the vibration motor exactly on both boards.

Wemos Battery Module (https://www.amazon.com/gp/product/B07M9X7HS6/ref=ppx_yo_dt_b_asin_title_o08_s00?ie=UTF8&psc=1) connected on PIN 16 Working ---- Beetle ESP32 Microcontroller DFR0575 connected on PIN 2 NOT WORKING

why are you asking this question again? .... edit your original question with additional information instead of reposting ... https://arduino.stackexchange.com/questions/68964/vibration-and-led-light-on-ble-approach

It is generally very dangerous to drive any motor directly from a digital output pin. Motors often need way more current, than the digital pin can provide. Based on the answer to this question, an ESP8266 can provide 20mA or 12mA depending on current direction (may be a bit different for an ESP32, but not substantially). Drawing more current, than the pin can provide, can lead to the destruction of the output hardware of the pin. It is not easy to say, when this will happen, because it depends not only on the current draw, but also on time and fabrication variation.
Also a motor is an inductive load, which means, that fast changes (for example turning on and off) will induce a reverse voltage in the motor coils. These can easily be very high relative to the supply voltage and thus destroy you output pin or even the complete microcontroller.
I cannot give you a full reasoning, why it works with the first board, but not with the second. I think, it has to do with the above.
You should always do 2 things, when driving motors with a microcontroller:

Use a motor driver circuit: You can either buy a ready to use motor driver or you can build one yourself. If you only want to turn the motor in one direction (as with a vibration motor), all you need is a MOSFET, which will act as a switch between the motor and the power supply. This switch get's controlled by the Arduino's output pin (which only needs to supply a very low current for switching). You can google "MOSFET as a switch". Be sure to use a MOSFET, that can provide the needed current and that is good in saturation for the used gate voltage (the working voltage of the microcontroller).
Use a flyback diode: The reverse induction voltage can also hurt MOSFETs. You want to let these voltage spikes quickly plenish by letting the current flow to ground. You can do this with a flyback diode. That is a diode, that bridges drain and source of the MOSFET. It is oriented so that block for normal operation (the normal positive supply voltage). When the MOSFET get's turned off, a great negative voltage will build up in the motor, but since the diode is conducting in this way, the voltage will safely flow to ground, so that the induction voltage cannot hurt the other electronic parts.

Thank you very much i'll try. the only problem I have is that I found a lot of Mosfet on amazon but i don't know what to buy.

I need something very small...

You already have to categories, where the MOSFET has to fit in: You search a MOSFET which can conduct some hundred mA (depending on your motor, you may just measure the real value) without a headsink (which means the maximum current has to be clearly above this value). Also it's threshold voltage should be clearly less than 3.3V (which is the voltage of ESP boards). And it should be small, so a SMD part is the best fit. Just use one with these conditions.


text:
How can I connect 6 solenoid locks to an arduino
Im in college and our research is about a fingerprint based door lock system.  We really dont have any idea about arduino.  Now we bought arduino mega for our research but I dont know how to connect all 6 solenoid locks to an arduino.  Please help It would be very much appreciated if you answer and it will be very helpful to us. I know there are same research about this in the internet but  i cant find any of these.  If you have any website about this research it would be very helpful.  Thanks

You simply cannot connect a solenoid to an Arduino, because an Arduino only outputs control signals and no power lines. There are 8 channel relais boards to put in between, if you want to minimIze self built electronics.

How much current do the solenoids need to engerize their coils? Solution might be as simple as using a TPIC6A595 shift register to sink current. http://www.ti.com/lit/ds/symlink/tpic6a595.pdf  Available at Digikey.com If more than 350mA is needed, a discrete driver could also be used per solenoid, consisting of N-Channel MOSFET such as http://aosmd.com/res/data_sheets/AOI4286.pdf and a diode across the solenoid coil to dissipate coil generated current when the MOSFET turns off.

Supposing the lock you use is a simple solenoid that works with 12V, you should connect them to the output of a relay module, and then connect the Arduino to the module. Like this example here: link.
You will probably want to connect each solenoid to an individual relay, so you can activate each one of them individually. With that in mind you might want to use an 8-channel relay module like DataFiddler recommended. example
You will need a 12V power supply, and be sure to check the current drawn from your solenoids and see if the power supply can handle it.

To follow up on CrossRoads' suggestion of a power MOSFET circuit, there is more detail on how to do it in an answer over in the Electrical Engineering group. Digikey.com is a great source for components.
https://electronics.stackexchange.com/questions/29065/how-to-control-a-12v-solenoid-valve-with-a-mosfet

You aren't going anywhere without external drivers. The Arduino simply can't output that much current. 8 channel drivers are widely available. Remember to connect an external power source.


text:
Push Button to Drive Power to Servo
I am currently doing a project for a class which uses a few other components such as an LCD, a servo, and such. I want to use a button which acts as a circuit breaker on the Vin of the servo in which the servo will only be powered when the switch is pressed. I wanted to implement something like this because I wanted to minimize the power consumption and also acts as a mechanical counter-measure in case the servo keeps on spinning in unwanted situations, such as having the servo entangled by hair or something like that.
I know that I can just connect the button to the I/O pins but I wanted to rely on a hardware solution for power minimization and safety reason.
The servo draws 170mA when idle and can draw a maximum of 1.2A, but I believe it will only draw about 500-600mA with the intended load. It can run between 4.8-6V.
So my question is, would my circuit configuration work for my application? Would it be safe? Do I need any other additional components? Thanks for anyone that can help!

There is a chance that this arrangement could damage the servo and possibly the Arduino.  The problem is that, depending on the internals of the servo, it could try and draw power for the servo through the data pin when the button is not pressed.  This would both over-stress the internals of the servo and the internals of the Arduino's GPIO pin.
What you could do to mitigate that is to connect the servo's switched power to another GPIO pin of the Arduino, which is set as INPUT.  That will then tell the Arduino when the button is pressed and when it's not pressed. Then you use that information to attach and detach the servo in your code so it is only being actively driven when the button is pressed.

Yes, that should be safe, as long as the button can conduct the needed current. That depends on the type of button. You can simply test this. If the button get's hot, it is too small for this.
If it should happen, that the button cannot conduct the needed current, you have 2 ways to go:

Just use a bigger button. You can buy buttons, that are meant for mains supply, which will be able to conduct way enough. Every button, that you buy (at least at electronics shops, maybe not on aliexpress or ebay), should have some kind of data sheet, which states the absolute maximums for the electrical characteristics. A maximum current can be found there.
You can use a MOSFET (that is capable of providing the needed current) and control it with your button. That would be the way to go, if you really need or want to use this specific button.


text:
Is digitalWrite(pinnumber,LOW) different from ground pin
I am using Tinkercad simulator, but an unusual thing happened. When I connect one wire of dc motor to pin 9 with digitalWrite(9,HIGH) and other wire to ground, the motor runs with rpm of 5555.
void setup()
{
  pinMode(9, OUTPUT);
}

void loop()
{
  digitalWrite(9, 1);
}

But instead if I connect the other wire to pin 13(say) and set digitalWrite(13,LOW) the motor runs at an rpm of 3846.
void setup()
{
  pinMode(9, OUTPUT);
  pinMode(13, OUTPUT);
}

void loop()
{
  digitalWrite(9, 1);
  digitalWrite(13,0);
}

Can anyone explain this?

Tinkercad probably doesn't have an option to show smoke coming from your Arduino, which is what would happen if you tried to ground a motor through a pin set to LOW. DON'T DO THAT. As others have mentioned, It can't handle the current, and a motor is a "dirty" load that can push negative voltages into the pin through a process called "back EMF". (It is caused by the inductive coils in a motor. When you remove power from an inductor, the collapsing magnetic field causes a surge of current flowing backwards.)

Thank you, next time I'll use a motor driver

You can control a regular DC motor with a power MOSFET and a "flyback diode". A motor driver is overkill unless you have a servo or a stepper motor.

Yes, it is different.
First: Never run a motor directly from IO pins - you will damage your Arduino. Not only can a real Arduino not supply enough current, but motors generate a lot of back-EMF that will kill an Arduino.
Secondly a pin doesn't connect direct to GND or VCC - it is connected through a MOSFET that performs the switching.  That MOSFET has an ON resistance, which causes a voltage drop across it determined by the current being sourced or sunk through the pin.
You can read more about GPIO pins here.

Thank you, next time I'll use a motor driver

In the real world, either pin sinks current to Gnd via an onchip N-channel MOSFET. They will safely sink 20, 25mA. If your motor allows more than 40mA to flow, you risk damaging the pin and likely the whole chip.
Similarly, either pin can source the same current to a load, likely via P-channel MOSFET, with the same current limitations.
Using both together, you have one transistor sourcing current, one transistor sinking current, so you have twice the Rds (MOSFET on-resistance) limiting current to the load, hence the simulator might have the motor going slower due to less current being available.


text:
HC-SRO4 always returns zero no matter what I do?
Wondering if it's the sensor or the code?  can anyone help?
I've used the code here
/*
HC-SR04 Ultrasonic Sensor with LCD dispaly

HC-SR04 Ultrasonic Sensor
  VCC to Arduino 5V
  GND to Arduino GND
  Echo to Arduino pin 12
  Trig to Arduino pin 13

LCD Display (I used JHD162A)
  VSS to Arduino GND
  VCC to Arduino 5V
  VEE to Arduino GND
  RS to Arduino pin 11
  R/W to Arduino pin 10
  E to Arduino pin 9
  DB4 to Arduino pin 2
  DB5 to Arduino pin 3
  DB6 to Arduino pin 4
  DB7 to Arduino pin 5
  LED+ to Arduino 5V
  LED- to Arduino GND

Modified by Ahmed Djebali (June 1, 2015).
*/
#include <LiquidCrystal.h> //Load Liquid Crystal Library
LiquidCrystal LCD(11,10,9,2,3,4,5);  //Create Liquid Crystal Object called LCD

#define trigPin 13 //Sensor Echo pin connected to Arduino pin 13
#define echoPin 12 //Sensor Trip pin connected to Arduino pin 12

//Simple program just for testing the HC-SR04 Ultrasonic Sensor with LCD dispaly
//URL:

void setup()
{
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  LCD.begin(16,2); //Tell Arduino to start your 16 column 2 row LCD
  LCD.setCursor(0,0);  //Set LCD cursor to upper left corner, column 0, row 0
  LCD.print("Target Distance:");  //Print Message on First Row
}

void loop() {
  long duration, distance;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;

  LCD.setCursor(0,1);  //Set cursor to first column of second row
  LCD.print("                "); //Print blanks to clear the row
  LCD.setCursor(0,1);   //Set Cursor again to first column of second row
  LCD.print(distance); //Print measured distance
  LCD.print(" cm");  //Print your units.
  delay(250); //pause to let things settle
}

Is the LCD working correctly? Have you tried displaying the values over Serial? Also you can test with the examples, that comes with the NewPing library. If with the example it still not works, there is something wrong with the wiring or the sensor. Then you should show us the wiring. And you could test, if the sensor outputs anything.

I bet it's the sensor or the way you wired it. Add a Serial.println(duration); to eliminate any other overseen errors. Does that "0" appear every 0.25 sec or every 1.25 sec only? ( Which indicates a pulseIn timeout )

This is my first project and I am new to the arduino and programming stuff, and yes the LCD is working perfectly.When I try to display values on the Serial monitor nothing shows up but the LCD it displays- Target distance=0cm and when I remove the hcsr04 it displays values like 180,179,178 without the sensor.I've used the schematics from this site https://www.instructables.com/id/Arduino-LCD-Project-for-Measuring-Distance/.Or is there a problem with my code?

Where should I add Serial.println(duration); before the LCD.print(distance); or after the LCD.print("  cm"); ?

The position is not important, just after pulseIn. I don't see an obvious error with your code. The advises, that we can currently give you, are meant for debugging - finding the error.

I tried but there are no errors in the code.

Please dude,I am new to this type of stuff and Tbh I actually don't know what to do right now?I'm blank man.

Where do you think is the error in the code,or do I need to add something ? If please,let me know where to add the statements.

I've ordered a new HCSR-04 sensor,Thanks

Even the new hcsr04 detects 0 cm.Help?


text:
Connecting Logitech F310 gamepad to Arduino Uno and Arduino USB Shield
I am trying to connect Logitech F310 gamepad to Arduino Uno with ARDUINO USB HOST SHIELD https://store.arduino.cc/arduino-usb-host-shield using http://github.com/felis/USB_Host_Shield_2.0 library.
The closest is https://github.com/felis/USB_Host_Shield_2.0/tree/master/examples/HID/USBHIDJoystick example
After compiling there is no print output in serial window after "Start".
Tried keyboard sketch on same board - it worked.
There is "Mode" button on joystick - by pressing green led is switched ON and OFF.
Behind the joystick there is switch between "X" and "D" .
On "D" green led is working, on "X" - not.
Is this joystick even compatible with HID library? Is there other way how to configure it to USB shield?
Joystick is working on different other devices.

I found it here : https://github.com/AlanFord/Logitech_F310_and_Arduino
So there is a glitch in library and driver customization was necessary

It's OK to accept your own answer as the solution to the problem. I think you get 15 rep for it.


text:
Where is tcp.c?
This question is related to my other question, which I already answered.
I want to add modify tcp.c to include my own code. The problem is I can't find tcp.c. The first thing I tried was looking in the same directory as tcp.h (C:\Users\Me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip2\include\lwip\tcp.h) but there is no tcp.c file there. So then I tried every tcp.h file on my c: drive.
c:\>dir *tcp.c /s
c:\Program Files (x86)\Arduino\hardware\arduino\avr\firmwares\wifishield\wifiHD\src
c:\Program Files (x86)\Arduino\hardware\arduino\avr\firmwares\wifishield\wifiHD\src\SOFTWARE_FRAMEWORK\SERVICES\LWIP\lwip-1.3.2\src\core
c:\Program Files (x86)\Arduino\libraries\WiFi\extras\wifiHD\src
c:\Program Files (x86)\Arduino\libraries\WiFi\extras\wifiHD\src\SOFTWARE_FRAMEWORK\SERVICES\LWIP\lwip-1.3.2\src\core
c:\Users\Me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip\src\app
c:\Users\Me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip\src\core
c:\Users\Me\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\tools\sdk\lwip2\builder\glue-lwip

and it's none of those. I assume this because I deleted everything in those files and my program still runs and builds. Now I don't know what to do. Am I right in assuming the file would be called tcp.c? If so why doesn't it seem to be any of the tcp.c files on my computer?

most of the LWIP library versions in esp8266 package are provided as already compiled  .a (esp8266/hardware/esp8266/2.5.2/tools/sdk/lib/liblwip2-1460.a) and without source code. source code esp8266/2.5.2/tools/sdk/lwip/src

Thanks. How did you know that? What can I do if I want to modify and rebuild the source?

the lwip folders contain make files


text:
esp_partition_get_sha256() mismatches PHP's hash() function in HTTPUpdate
Disclaimer: It may be that this question belongs to a PHP forum instead of this one. However, this question is also very ESP32/Arduino related. Please correct me if this is the case.
The scenario:

Implementing self-update routines for my ESP32 project, using HTTPUpdate
Using a server-side PHP script to decide which binary image to serve to the device, or return HTTP 304 return code if no updates available.
Using the sketch's MD5 and SHA-256 hashes provided by the HTTPUpdate library as request headers, server-side, to check binary version.

The problem:

The MD5 hash contained in the request header "x-ESP32-sketch-md5" is the same as the MD5 hash calculated by a simple md5() call using the raw binary for the currently running version.
The SHA256 hash contained in the request header "x-ESP32-sketch-sha256" is not the same as the hash obtained by calling PHP's hash("sha256", $v) (where $v contains the same raw binary).

Example:

MD5 (HTTPUpdate): c93d814989b53a24a0164e561b6a8bf8
MD5 (PHP): c93d814989b53a24a0164e561b6a8bf8 (no difference)
SHA256 (HTTPUpdate): 5634674253E095600CD863A34287FCA742BCFCF9B5BF409870DD65AF0ADEF7A0
SHA256 (PHP): 1ECDDF3215520C79AAD13BBC1D116D9286910490DF316B9B203FCBFC89CBCCC2 (different)

Am I doing something wrong?
Note: The esp_partition_get_sha256() function is called internally by the update() method of the HTTPUpdate library.
PHP Code (for calculating the hashes):
<?php

$v = file_get_contents("fw.bin");

print("MD5: ". md5($v)."\r\n");
print("SHA256: ".hash("sha256", $v)."\r\n");

Arduino code (the relevant part):
// Called once or twice a day
void update_fw()
{
    Serial.println("Checking for updates...");

    t_httpUpdate_return ret = httpUpdate.update(client, "http://my_server/fw/check_fw.php");  // For now it only logs the headers and returns HTTP 304 code

    switch (ret)
    {
      case HTTP_UPDATE_FAILED:
        Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
        break;

      case HTTP_UPDATE_NO_UPDATES:
        Serial.println("HTTP_UPDATE_NO_UPDATES");
        break;

      case HTTP_UPDATE_OK:
        Serial.println("HTTP_UPDATE_OK");
        break;
    }
}

PHP code (logs headers and returns HTTP 304 code):
<?php

$headers = getallheaders();

if (!file_exists("log.txt"))
{
    file_put_contents("log.txt", print_r($headers, true));
}

http_response_code(304);            // No updates.

exit;

Thanks in advance.

Your problem stems from a misunderstanding of what the functions are doing.
Your MD5 hashes are the hash of the binary file itself. And so they match.
Your PHP SHA256 is the hash of the binary file (like the MD5), but the ESP's SHA256 is not.
The file itself contains an SHA256 hash of the content of the file, not the whole file.  The function esp_partition_get_sha256 merely returns that SHA256 hash.
According to the SDK documentation:

For apps with SHA-256 appended to the app image, the result is the appended SHA-256 value for the app image content. The hash is verified before returning, if app content is invalid then the function returns ESP_ERR_IMAGE_INVALID. For apps without SHA-256 appended to the image, the result is the SHA-256 of all bytes in the app image. For other partition types, the result is the SHA-256 of the entire partition.

If you were to take the binary file and somehow strip off the extra sha256 information and then perform a hash of the results you should (theoretically) get the same hash, which would be the same has as is contained within the file itself.

True. I reached the same conclusion via a completely different way. Following a hunch, I opened the file in a hex editor and at once recognized familiar bytes at the end. Not something very scientific, but alas, there they were. While my research could've been more thorough, I partly blame it on the lack of in-code comments and documentation, and quite poor (not findable) documentation for the Arduino-ESP32 project. Maybe it's time for me to contribute more? Oh, and thank you.

To "somehow strip the extra SHA256": $image = substr($old_image,0, -32);.


text:
I2C - Confusion
It's not often I ask a question. This one has me a little stumped though.
Scenario:
I have an 328PB (internal 8mhz), it speaks to a multiplexer on Wire1 (the PB's second IC2 - Minicore lib). The multiplexer speaks to many sensors. That is all working just fine.
I have a logic analyser hooked up to the key points so I can see what is going on.
I have a Nano (external 16mhz) hooked up to Wire (the PB's first I2C), it sends a master request.
The PB is master on Wire1 and slave on Wire.
For some reason the Nano's request on (address 8) is acknowledged by the PB but then the subsequent reads deliver a zero byte and an NACK.
I'm just asking for one byte to troubleshoot. Previous attempts at multiple bytes would deliver the expected bytes but all of them zero.
Strange thing I'm seeing on the logic analyser is that the PB to Multiplexer communication seems to be slower than the Nano to PB (much slower).
I've looked through the libraries and both Wire and Wire1 seem to calculate the speed down to 100khz. I'm using the standard Arduino Wire on the Nano. Given that the initial Address comms gets an ACK. I'm stumped why the subsequent read gets zero and a NACK.
Any help to restore my sanity is much appreciated.
Chances are I'm having a dumb moment. My suspicions are that the clock differences are to blame (but logically they shouldn't be).

Edit:
This is the analyser recording. The dodgy byte is highlighted in Blue.

The communication from the Atmega328pb to the multiplexer and then on to the temperature sensor is working fine. Not all of the multiplexer channels have sensors at the moment hence the NACKs but you can see success on channel 1 to the right of the screenshot. The Nano to Atmega328pb communication starts off good but I'm expecting to see 0X41 in the blue box not 0x00.
This is going to end up being something simple, I'm going to kick myself.
Nano code:
#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(9600);             // start serial for output.
}

void loop() {
  Wire.requestFrom(8, 1);         // request 1 byte from slave device #8
  char c = Wire.read();           // receive a byte as character
  Serial.print("The character: ");
  Serial.println(c);              // print the character
  delay(1000);
}

Atmega328pb requestEvent code:
void requestEvent() {
  Wire.write("A");
}

Edit:
There are other wires for programming etc, but they are disconnected during test.

Edit:
I commented out all the usage of Wire1 in the PB code. And the result was that the Nano got it's byte. I wove the usage of Wire1 back into the code. Right up until it was actually active i.e. communicating with the multiplexer. At that point the Nano started getting a zero byte again.
It seems to be when they are both active. Which suggests it is something in the Wire/Wire1 library by Minicore.
I suspect there is something in the registers but scanning the datasheet for the PB is not yielding any insights. Except for this:
26.1 - Device can Operate as Transmitter or Receiver
There is no elaboration in the document that I can see.
I've tried staggering the communication so that neither is active at the same time. Still the same result.
Still hoping that someone here has the answer ;-)

Can you draw a picture showing the structure? I've not yet grasped what boards are hooked up to what I2C bus and which role each board has on these busses. Also please show us the code in question

chrisl - thanks for your response, I will draw some diagrams. I'll also post the whole code for each MCU. Many thanks.

The 328 is a bare atmega, not an arduino, right? You have to clear the clock divison fuse, otherwise the effective mcu frecuency is 1MHz, not 8MHz.

@SimSon - Thanks for the pointer. I had the fuse set wrong  on the 328PB. Set it to 8Mhz and now the speeds are looking better. Still got my problem though.

We'll, a drawing would help us to understand your setup better.

@SimSon - One drawing coming up.

i've been having a similiar issue, not being able to operate as master on SDA0/SCL0 and as slave on SDA1/SCL1 (and vice versa). Different than in your fix above (calling begin() and end()) does not work for me. If i operate both i2c interfaces as master or both as slave the communications works fine. Could you give some insights how you configured your uC as slave and master on the two interfaces?
Would be very much appreciated!!

@Th3o - (Sorry for the late reply) I ditched the WIRE library for what I was doing. Just could not get a master and slave working on the same MCU with WIRE library. In Amtel studio I had to write a lot more code which took a lot more time but I got very fine control over the interfaces. The MCU is capable of doing it and at blistering speeds!

I  got it to work ... sort of. I had to move some lines from init to the loop.
I found that by delaying the Wire1 communication (pb to multiplexer) I could get Wire (Nano to pb) to work. Then as soon as the Wire1 communication had finished Wire no longer worked. Interestingly Wire continued to work while Wire1 was also active.
This has lead me to believe the end of the Wire1 communication is leaving something in a conflicted state (the events on Wire were not connected any longer). The blunt answer was to re-initialise on each loop. This seems to work but is not particularly elegant.
void loop()
{
    Wire1.begin();
    getTemperatures();
    Wire1.end();
    Wire.begin(8);                                               // Join i2c bus 0 with address #8
    Wire.onReceive(receiveEvent);                                // Register event.
    Wire.onRequest(requestEvent);                                // Register event.
}

I'm going to continue with this and see if it offers an appropriate degree of reliability. I'm still hunting for the root issue though.

I've been rebuilding using Atmel Studio. After a long time bringing my C++ skills up to scratch I've managed to get it to work very reliably. I like the greater level of control it brings. I suspect that I was trying to do something in Arduino IDE that cannot be done with the Wire library. I had to effectively rewrite the Atmel Start Slave driver  to get it to behave as I expected it to. I have no other experience of using I2C. So I cannot say whether it is the Atmega328pb that is different or not.
I'm going to stick to Atmel Studio for this project, thanks for all the responses.


text:
Arduino wont start up and it wasnt succesfully booted in any time it was downloaded
I know the title sounds stupid but I never found a question like mine so I wanted to be specific because I downloaded the Arduino IDE to start my first project and I never managed to boot it because nothing happens when I try and I also tried every kind of thing to make it work I could think of. I reinstalled it, downloaded from another link like the zip version and also tried the windows repairtool. I also tried to boot it as admin several times but nothing changed anything. I did all of that yesterday and today when I started the Pc and retried I atleast saw something of a bootingscreen of the app so I thought I just had to restart but then it just went off again and the pain from yesterday began once again.
´´
I own windows 7 64 bit
´´
and tried every download except the one for windows 8.1 and 10
I saw a question about Arduino IDE not starting but this person atleast got any response from the program and the tipp they suggested with the folder in
´´
AppData/Lokal where you delete broken data to reinstall doesnt work too because the arduino folder doesnt even excist in the whole appdata section.
´´
´´
Windows repair tool said the program is not compatible, only in Windows xp (service pack 2) version but in compatibility mode nothing changes
´´
Ok thew this question is really long but I gave my best to explain everything I could about my problem so I really hope somebody could help me on my problem so I didnt waste my 45 Euro and time on tech stuff that I cant use
one thing to meantion I have left is that i bought my stuff from a teacher (Erik Verbene) on the internet
but that doesnt matter because it is your program that is not working so
yeah
hope somebody can help me out on this dilemma

run arduino_debug.exe in installation folder

there only starts up a black box that instantly closes again....

start it from command line

The Arduino IDE is written in Java. It's 100% platform independent, so the version that you download makes no real difference.
The most likely culprit is the version of Java that is installed in your computer.  I am not sure off hand what versions of Java the Arduino IDE works with, but for certain version 8 will be your best bet.  Make sure that you have the latest version of Java 8 installed.  If you have any older version installed you should uninstall it and replace it with Java 8.  I'm not sure how the IDE works with newer versions than 8, but removing anything newer than 8 and installing Java 8 may be a good idea.

Arduino IDE has Java bundled in installation

I already own the newest version of java and I also checked if java itself is running and it does so that isnt the problem it seems


text:
Concern myself with current draw from digital pins used as INPUT with internal pullups?
My project is using a genuine Arduino Mega 2560, probably 3-4 yrs old since purchased (I don't see any revision numbers on the PCB).  It's being used to read a lot of switches, buttons and drive some LED's and displays.
When using a digital pin as INPUT with the internal 10k pullup enabled, do I need to consider the draw with respect to the 200mA total through all pins?  Is it simply the 10k ohm resistor with 5V so 0.5mA?  Can I just ignore it? (there's only so many pins I suspect I can ignore it)
I've seen several posts/pages about driving LED's using transistor arrays powered by an external source and those spec sheets describe the transistor input currents so I can estimate the draws for those elements, but not sure if I need to concern myself with the Arduino pins used as INPUT.

The pull-up resistors of the I/O pins are specified as 20 to 50 kΩ, so they are not going to source more than 250 µA at 5 V. The “Typical characteristics” section of the data sheet shows a current of the order of 140 µA.

I found them to be about 34kΩ - 37kΩ: Read how I found that here: https://majenko.co.uk/blog/measuring-arduino-internal-pull-resistors

In case of a button, the 0.15mA of current only flows while the button is pressed. Zero current flows when the button isn't pressed, which is probably most of the time. I think it's pretty safe to ignore these currents.

I think Gerben is right. The pull-up resistors connect +5V to the solid state capacitors on the CMOS inputs, which have virtually infinite resistance to DC current. The pull-ups will only draw current when the pin is grounded, and shortly afterwords.

You are right. The current through digital inputs is so low, that you can normally ignore it.
And the 0.5mA, that you calculated don't flow all the time, just, when the corresponding button is pressed and thus shorted to ground, because only then a current will flow through the pullup resistor. The current into the actual input hardware is even smaller. So, as long as not all buttons are pressed at once, the current will be even lower as calculated.
Buttons are somewhat voltage devices. They don't need a specific amount of current, just of voltage. So the actual value of pullup/pulldown resistors are not critical. LEDs in contrast are current devices. They need a specific current to light up, which is often higher, than the maximum output current of a digital pin. Thus they are often driven with an additional transistor.


text:
Connecting 2-pin JST PH connector to Arduino Mega
I’m want to connect 50 LDR to my Mega, I wondering if I use a 2-female pin JST PH connector to connect the LDR, how can I link 2-pin male JST PH connector board to the Mega and does this board exist?

Design your own.

There exists 2.00 to 2.54mm adapters, like in this link.
They look like below (example of 1.27, 2 and 2.54mm):


text:
Audio Recording using Arduino BT module
I want to take audio signal through mic connected to Arduino and then transfer it to PC using BT module. I want to do it with BT (HC05) and Arduino Mega. I need audio packages at 44 KHz and 24-32 bits per sample.
Can I use AudioInI2S library to receive audio samples? Does HC05 support this type of communication?
I want to save and analyze the audio samples later on. I have worked on Arduino before but I am totally new to audio streaming and I am not sure where to begin from. Any guidance would be appreciated.

In short: No and no.

Can I use AudioInI2S library to receive audio samples?

No.  The library is not for the Mega:

This library provides simple way to play and analyze audio data using Arduino on SAMD21 based boards (i.e Arduino or Genuino Zero, MKRZero or MKR1000 Board) using the I2S bus.

Does HC05 support this type of communication?

No.  The HC05 is a serial module. It works at baud rates that are far to low to transfer the data in a timely fashion, and can't send data in a form the PC sees as audio (so you'd need to write your own translation software to convert serial data into an audio file).

Any guidance would be appreciated.

Just buy a cheap bluetooth headset.

Thank you for your reply. Can you suggest any other Bluetooth module that can support my frequency range?

Bluetooth headset is not an option as it is a part of some project that I am working on.


text:
Is there a library for non-SAMD Arduinos to use the DMP on MPU9250
I would like to use the DMP of the MPU9250 with my BTLE Feather board but the docu of the official library says that only SAMP-Processors are supported.
Is the a different library I can use?

it uses the Wire library. I don't see anything SAMD specific. Try it

I did have a look at the MPU9250 DMP library provided by Sparkfun and it seems that it is specifically built for their own board which has an M0 chip on the board. However looking at the library, there seems to be no reasons why it would not work with any other board. The main reason why it might not work with something like the 32u4 board would be because the end firmware is too large or the program need too much RAM that what the 32u4 has.
There is a fix provided on the github issues page for using it with a Nano, which might help you get it work with the 32u4 here and there is another library here that you might be able to use or build up on.
However the best way might be to use a M0 chip itself if you really want to use the same IMU since getting the library to work can turn out tricky. Adafruit does sell a M0 with a Bluetooth board here that you might be able to use.

Thanks for finding the M0-feather. It's just a bit too late, but I think I'll buy one and see if the values change. I can run the examples without problem on the 32u4, but I just wonder if the drift comes from some timing problems or subtlety that is not obvious.


text:
Receiving i2c bytes on an attiny85
I've been trying to write a small i2c lib in C over the past week. I managed to get writing to slaves working (for example I can write to an ssd1306 oled) but reading (for example date/time from an ds3231) never works as my slaves don't seem to set SDA high when I request bytes.
uint8_t
i2c_read(uint8_t ack)
{
    uint8_t i, val;

    val = 0;
    cbi(SCL);
    DDRB &= ~(1 << SDA); /* Use SDA for input. */
    cbi(SDA); /* We need to pull down SDA to receive input. */

    /* Read 8bit from the slave. */
    _delay_us(DELAY);
    for (i = 0; i < 8; ++i) {
        sbi(SCL); /* Request one more bit. */
        _delay_us(DELAY); /* Wait a little so the slave can send his answer. */
        if (PORTB & (1 << SDA)) { /* Here the slave should have set SDA to 1 but it never does. */
            PORTB |= (1 << PB4);
            val = (val << 1) | 1;
        } else {
            val = (val << 1);
        }
        cbi(SCL);
        _delay_us(DELAY);
    }

    /* Send back an ACK or NAK. */
    DDRB |= 1 << SDA; /* Use SDA for writing. */
    if (ack)
        cbi(SDA); /* Set SDA to 0 to send ACK. */
    else
        sbi(SDA); /* Set SDA to 1 to send NAK. */

    sbi(SCL);
    _delay_us(DELAY);
    cbi(SCL);
    cbi(SDA);

    return val;
}

I set PB4 with to 1 when a slave actually sends a 1. Apparently that never happens.
I also had a look at how the various other libs out there do it but I didn't spot anything that would make a difference.
Any clues on what I migth be missing? Before reading my program sends the slave address to the bus. Also: please don't tell me to use other libraries since this is a learning project.

Hi and welcome to the Arduino.SE community. Thanks for your question.Please add more detail in your question on how this relates to Arduino. Cheers.

Does the clock line really get high? A slave can pull down the clock to pause the communciation until it is ready. Can you show us an output of an oscilloscope or a logic analyzer? So that we can see, what exactly happens on the lines?

Not sure, if this is the only problem, but you are reading from the wrong register.
There are 3 registers associated with a digital output pin: DDR, PORT and PIN. To read a pin, you need to read from the PIN register. Currently you are reading the PORT register, which will only ever have the value, that you set it to (zero in this case, because you cleared the bit beforehand with cbi(SDA);). When you configure the pin as input with the DDR register, the PORT register determines, if the internal pullup resistor is activated or not, so it cannot reflect the actual state of the pin. For this you need the PIN register.

Besides that, you might want to look into another thing, that might or might not be a problem in your case: I2C is an open drain bus, meaning, that it is driven actively low and passively high (through pullup resistors). I guess you already have external pullup resistors on your lines, so that you really can deactivate the internal pullup without breaking the communication. But imagine the following situation: The slave get's a request, but cannot clock it out that fast (for whatever reason). It can pull the clock to LOW, until it is ready to push out the data bit, slowing down the clock speed. (This can be done for every bit, unless you are in highspeed mode, then only before the start of a new byte). (This behavior is called clock stretching - Thanks to Edgar for the information) You don't monitor the line, so it can happen, that you drive the clock line actively to high, before the slave has released it. This results in a significant current between master and slave, since the master drives actively high and slave actively low.
There are implementations of I2C communication, that are just doing that and are working fine in most situations. I just wanted to give you this information. And if you at some point want to implement bus arbitration (to allow a multi-master setup), you definitely need this open drain behaviour.

Re. the slave pulling SCL low: I would add that this is called “clock stretching”, just to provide a search keyword.

You are correct, I totally forgot to mention it, though I thought I had done this. I will add this information to the answer

Thanks for the info! I didn't know that theres another register for reading input pins. But it makes sense since PORT is used for pullup/down in input mode. I have pull up resistors in my cirquit. They are integrated on the i2l slave ICs afaik. I am also waiting for the slave to stop pulling down SCL now (clock streching). Now I have the same problem but the slave does't pull down SDA (I guess) thus my SDA is always high (im reading from PINB). This is quite confusing. Have you got any ideas on what I might be doing wrong?

Edit: I have two i2c slaves that both have internal pull up resistort. Is it possible that they interfere in some way? I don't know a lot about electronics.


text:
How does this MPU6050 Example Code Work?
I'm trying to understand the logic for one of the example Arduino programs for the MPU6050 IMU module. The entire program can be found here.  There is an if() statement inside a while() loop inside the normal Arduiono sketch loop() function, and I'm having real trouble figuring out the logic.  The ISR and relevant code section is shown below:
volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady()
{
    mpuInterrupt = true;

}

    void loop()
    {
        // if programming failed, don't try to do anything
        if (!dmpReady) return;

        // wait for MPU interrupt or extra packet(s) available
        while (!mpuInterrupt && fifoCount < packetSize)
        {
            if (mpuInterrupt && fifoCount < packetSize)
            {
                // try to get out of the infinite loop
                fifoCount = mpu.getFIFOCount();

                //pulse the pin
                digitalWrite(Loop_While_Section_Pin, HIGH);
                delay(1);
                digitalWrite(Loop_While_Section_Pin, LOW);
            }
            // other program behavior stuff here
        }

        // reset interrupt flag and get INT_STATUS byte
        mpuInterrupt = false;
        mpuIntStatus = mpu.getIntStatus();

        // get current FIFO count
        fifoCount = mpu.getFIFOCount();
        if (fifoCount < packetSize)
        {
            //Lets go back and wait for another interrupt. We shouldn't be here, we got an interrupt from another event
            // This is blocking so don't do it   while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
        }
        // check for overflow (this should never happen unless our code is too inefficient)
        else if ((mpuIntStatus & _BV(MPU6050_INTERRUPT_FIFO_OFLOW_BIT)) || fifoCount >= 1024) {
            // reset so we can continue cleanly
            mpu.resetFIFO();
            //  fifoCount = mpu.getFIFOCount();  // will be zero after reset no need to ask
            Serial.println(F("FIFO overflow!"));

            // otherwise, check for DMP data ready interrupt (this should happen frequently)
        }
        else if (mpuIntStatus & _BV(MPU6050_INTERRUPT_DMP_INT_BIT))
        {
            // read all available packets from FIFO
            while (fifoCount >= packetSize) // Lets catch up to NOW, in case someone is using the dreaded delay()!
            {
                mpu.getFIFOBytes(fifoBuffer, packetSize);
                // track FIFO count here in case there is > 1 packet available
                // (this lets us immediately read more without waiting for an interrupt)
                fifoCount -= packetSize;
                //digitalWrite(Loop_ReadBytesSection_Pin, !digitalRead(Loop_ReadBytesSection_Pin)); //toggle the pin

                //pulse the pin
                digitalWrite(Loop_ReadBytesSection_Pin, HIGH);
                delay(10);
                digitalWrite(Loop_ReadBytesSection_Pin, LOW);
            }

    #ifdef OUTPUT_READABLE_YAWPITCHROLL
            // display Euler angles in degrees
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
            Serial.print("ypr\t");
            Serial.print(ypr[0] * 180 / M_PI);
            Serial.print("\t");
            Serial.print(ypr[1] * 180 / M_PI);
            Serial.print("\t");
            Serial.println(ypr[2] * 180 / M_PI);
    #endif

    // blink LED to indicate activity
            blinkState = !blinkState;
            digitalWrite(LED_PIN, blinkState);
        }
    }

It appears that the only way the 'if()' condition can be met is if the 'mpuInterrupt' variable managed by the ISR changes from FALSE to TRUE between the 'while()' condition evaluation and the 'if()' condition evaluation, which doesn't make a whole lot of sense to me.  In addition, the 'fifoCount' variable is only incremented inside the 'if()' section, which makes the second half of both the 'while()' and 'if()' conditions a little strange too.
I do want to note that this example program DOES WORK, and if I instrument the 'if()' section to pulse a hardware pin whenever it executes, I do see pulses following many (but not all) hardware interrupt occurrences.  So I know for sure the 'if()' statement DOES execute - but this seems a very 'Rube Goldbergian' way to go about it.
Any illumination would be appreciated ;-).

at first glance, it looks like the first while statement has a misplaced closing brace ... i think that the closing brace should be placed right after the opening brace

@jsotola That does not make sense either, because fifoCount will also be read shortly after that. I would say, this is simply wrong code and that the case "extra packets available" is not actually covered here. I guess this does not happen often either.


text:
Is there a way to add external RAM (let's say 100 MB or 200 MB) in this audio buffer mixing context?
I'm coding a music sampler device: for fast playback / minimal latency (only a few milliseconds), it's better to have all audio .wav samples we want to use in RAM, so that when some of them are  played, the data arrays are immediately accessible. That's what I did for a Raspberry Pi project called SamplerBox. It was possible because RPi had 1 GB RAM.
Note: When using SDcard reading, and playing many notes at the same time (imagine a pianist playing a big chord), it's usually not good in terms of latency.
Now I'm thinking about porting this project to Arduino: in which extent can we add external RAM to an ATmega? Or if not "RAM", some volatile memory (let's call it "RAM2") that would be 10 times faster than reading an SD card.
What I'd like to achieve:

load 200 MB of audio samples into the "RAM2"
Max polyphony allowed = 100, so at a given time, all audio buffers that have to be mixed can be copied from "RAM2" to the "real" RAM of the microcontroller, and the mixing will be done with the (maximum 100 of them) buffers in the real RAM

I would think you'd want 100 Arduinos, each playing one sound indendently, each with it's on SRAM buffer that was very quickly played back via SPI bus and DAC, and then  mix all the outputs in analog domain (vs digital). Latency from trigger to DAC output will be next to nothing. Could load each from an SD card before playing - have one 'controller' to read the SD card and send the file to each arduino to store in its locally controlled SRAM.

There are SRAM ICs / boards, however, don't expect 100 MB, more like 1 MB (with the pin numbers and connectivity / protocols that an Arduino offers).
With Flash you can get much further, but it can only be written a number of times; not sure if that suits your requirements.
Beyond that, I'm afraid the real problem is in the processing speed. Mixing 100 samples with 48 KHz stero would mean (48000 * 2) = 96 KSamples/s. Since the Arduino is only 16 MHz you have just 16e6/96e3 = 166 clock cycles to mix all those 100 samples. Probably way too less.
Update
Winbond is a brand that is supported by Arduino libraries and the biggest supported IC is e.g. W25Q128FVSSIG, which is 128 Mbit, thus 8 MB. For 200 MB you need 25 of them which is quite a lot, and not sure if there will be issues using so many (let alone the cost). For this you do not need a file system, however you need to write it per page (if you want to do it efficiently). Which should be ok, since the SD card also is read per page (maybe not the same page size though).
However, you still have to copy the Flash memory into SRAM to be able to process it, so it's not the same as SRAM. Getting 200 MB SRAM will be very costly.

Thank you for your answer. Can we add a 200MB flash to an arduino? Can we use it as a RAM (just load arrays from a SD card to a memory buffer) or do we have to use a filesystem like a disk (then it's not really useful for audio buffers)

@Basj I updated my answer with your additional questions.

I'd also suggest looking into different microprocessors. The Teensy models often have an SD card socket, and the Teensy 4 (especially if they release one with a built-in SD socket) is extremely fast and capable (600MHZ, dual instructions/cycle). That would be far better suited than an Arduino, though you'll still have RAM limits. (Nowhere near 200 megs, but you'd have slightly less of an issue than with the Arduino's mere 2-8K of RAM. These have a few hundred K up to maybe a couple MB (note that I'm not sure if it actually goes that high))
There's also the RPI Zero, Zero W, and Compute Module to try using. Those are the Raspberry Pi system you are used to using at a low-ish cost or easily-integrated form factor.
In short, to do audio processing, you also need a better processor than a stock Arduino probably has. Lots of RAM is the easy-to-see issue, but having the computing power to do something with it is also important.
Do note that the Winbond chips mentioned in the other answer ARE a flash memory, so they may go bad on you if they see a lot of writes.


text:
Trouble GETing over HTTPS on the ESP32
I am having some trouble doing a GET request over HTTPS on the ESP32. I am using the BasicHttpsClinet example from the ArduenoIDE. Here is the code.
/**
   BasicHTTPSClient.ino

Created on: 14.10.2018

*/

#include <Arduino.h>

#include <WiFi.h>
#include <WiFiMulti.h>

#include <HTTPClient.h>

#include <WiFiClientSecure.h>

const char* rootCACertificate = \
"-----BEGIN CERTIFICATE-----\n"\
"super_secret certificate"\
"-----END CERTIFICATE-----";

// Not sure if WiFiClientSecure checks the validity date of the certificate.
// Setting clock just to be sure...
void setClock() {
  configTime(0, 0,"cn.pool.ntp.org", "pool.ntp.org", "time.nist.gov");

  Serial.print(F("Waiting for NTP time sync: "));
  time_t nowSecs = time(nullptr);
  while (nowSecs < 8 * 3600 * 2) {
    delay(500);
    Serial.print(F("."));
    yield();
    nowSecs = time(nullptr);
  }

  Serial.println();
  struct tm timeinfo;
  gmtime_r(&nowSecs, &timeinfo);
  Serial.print(F("Current time: "));
  Serial.print(asctime(&timeinfo));
}

WiFiMulti WiFiMulti;

void setup() {

  Serial.begin(115200);
  // Serial.setDebugOutput(true);

  Serial.println();
  Serial.println();
  Serial.println();

  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP("Master_2.4G", "wittyercheese551");

  // wait for WiFi connection
  Serial.print("Waiting for WiFi to connect...");
  while ((WiFiMulti.run() != WL_CONNECTED)) {
    Serial.print(".");
  }
  Serial.println(" connected");

  setClock();
}

void loop() {
  WiFiClientSecure *client = new WiFiClientSecure;
  if(client) {
    client -> setCACert(rootCACertificate);

    {
      // Add a scoping block for HTTPClient https to make sure it is destroyed before WiFiClientSecure *client is
  HTTPClient https;

  Serial.print("[HTTPS] begin...\n");
  if (https.begin(*client, "https://my_end_point.com/something_or_other")) {  // HTTPS
    Serial.print("[HTTPS] GET...\n");
    // start connection and send HTTP header
    int httpCode = https.GET();

    // httpCode will be negative on error
    if (httpCode > 0) {
      // HTTP header has been send and Server response header has been handled
      Serial.printf("[HTTPS] GET... code: %d\n", httpCode);

      // file found at server
      if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
        String payload = https.getString();
        Serial.println(payload);
      }
    } else {
      Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
    }

    https.end();
  } else {
    Serial.printf("[HTTPS] Unable to connect\n");
  }

  // End extra scoping block
}

delete client;
  } else {
    Serial.println("Unable to create client");
  }

  Serial.println();
  Serial.println("Waiting 10s before the next round...");
  delay(10000);
}

I am getting the following when I run the sketch
[HTTPS] GET... failed, error: send header failed

Guessing this is related to the issue reported here: https://github.com/espressif/arduino-esp32/issues/2670
I tried updating my esp-arduino libraries( to get the latest code with the fix mentioned in the Github issue) by redoing the steps from here: https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/mac.md#installation-instructions-for-mac-os
But I still get the same issue error.
I have double-checked my server, I know that the esp32 has not managed to make it to the endpoint yet.
I have tested the GET endpoint in my browser and it works fine. I have compared the certificate to the one hardcoded in the sketch file. They match.
How do I update my arduino-esp32 libraries to get the fix mentioned in the GitHub issue?


text:
ESP32 HCI command for setting BLE TX Power
Does anyone know if there's an HCI command for setting the TX and the advertising power for BLE on an ESP32?
I have a Nano 33 IoT and a MKR 1010, and it has its power set annoyingly low for advertising and transmission.  The library that I'm using is ArduinoBLE, which uses HCI to communicate with the ESP32.
I believe that espressiv allows the power level to be set using their dev kit, and I know that other vendors (e.g., TexasInstruments) provide extensions to HCI for setting power levels, but I haven't been able to find an HCI command for ESP32 anywhere.
Any ideas on other ways that I could do this other than HCI would be welcome too (e.g., other libraries for BLE that would work with the MKR and Nano series of boards, but would allow setting the power level for advertising and transmission.

Nano 33 BLE doesn't use ESP32. it has a nRF52. do you have Nano 33 IoT?

No, you're right!  I've got a bunch of these things sitting around... I have an IoT and also a MKR1010.  I'll update the post.

on Nano 33 IoT and MKR 1010 the esp32 is controlled by the firmware so if the firmware doesn't have the setting in API, then it is not available

So you're telling me the AndroidBLE library that I'm using, which uses HCI commands to control and interact with BLE subsystem is NOT talking directly to the ESP32?

it is/ the firmware does the setup() with esp_bt_controller SDK functions, but then the esp32 SDK listens for HCI commands on UART.

OK, so that's the point of my question.  I don't think that setting power level is a one time operation (at setup only). For example, their SDK allows you to set transmission power for each connection.  I just need to know the HCI command to set the advertising power level, and I can call it myself as an HCI command through the UART.  Maybe there isn't an HCI command for setting power levels.  I just can't find info on the list of HCI commands supported by the chip anywhere!