text:
Unexpected Behaviour w/ Arduino Uno Calculation
I have a really simple snippet of code wherein the same calculation outputs different values depending on how I do the calculation. The platform that I am running this code on is an Arduino Uno - with an Atmel MEGA328P microcontroller chip. Here's the code:
void setup() {

  Serial.begin(9600);
  unsigned long num = 100927;
  Serial.println(1000*60);
  Serial.println(num/(1000*60));
  Serial.println(num/(60000));
}

void loop() {}

This code prints the following on the console:
-> -5536
-> 0
-> 1

I don't understand why num/(1000*60) and num/(60000) evaluate to different values? Also, 1000*60 evaluates to a garbage value which looks like it somehow set the data type to int and resulted in overflowing the "int" range.
My programming background is heavy in Python. I figure I'm used to python dynamically interpreting variable data types for me which is why the arduino language confuses me a bit here. Any help is appreciated!

This is a pure C++ programming issue, which I cover on my web site.
However, since link-only answers are not allowed here, I reproduce that post below:

On the Arduino (Uno) platform, what do you think will be printed here?
void setup ()
  {
  Serial.begin (115200);
  Serial.println ();

  Serial.println (30000 + 30000); // twice 30000
  Serial.println (60 * 60 * 24);  // seconds in a day
  Serial.println (50 / 100 * 1000); // half of 1000
  }  // end of setup

void loop () { }

Did you guess:
60000
86400
500

Nope!
It prints:
-5536
20864
0

This is because of integer arithmetic. If the compiler can, it treats an numeric literal (like 60) as an int type, which means it has the range -32768 to +32767. This may be unexpected for users of modern compilers because nowadays an int is usually 32 bits. However on the 8-bit Arduino processors such as the Atmega328P the compiler treats an int as 16 bits wide. The C++ standard permits an int size of at least 16 bits, but you are not guaranteed that it will be larger.
And, arithmetic is done using the type of the largest argument, which means the arithmetic in each case is done as 16-bit arithmetic, and thus it overflows once it reaches 32767.
For example, 30000 + 30000 = 60000 which is 0xEA60 in hex. Unfortunately, 0xEA60 is exactly how -5536 is stored in an int type, which is why it prints -5536.
Meanwhile, 60 * 60 * 24 = 86400 which is 0x15180 in hex. As that doesn't fit in 16 bits, it is truncated to 0x5180 which is 20864 in decimal (as printed).
Finally, in integer arithmetic 50/100 is zero, multiply zero by 1000 and you still get zero, which is why the final result is zero.

So, can we "help" the compiler by telling it the sort of result we want, like this?
void setup ()
  {
  Serial.begin (115200);
  Serial.println ();

  long a = 30000 + 30000;
  long b = 60 * 60 * 24;
  float c = 50 / 100 * 1000;

  Serial.println (a);
  Serial.println (b);
  Serial.println (c);
  }  // end of setup

void loop () { }

That prints:
-5536
20864
0.00

So no, that hasn't helped.

Solution
First, you can add a suffix to numeric literals (eg. L for long, or UL for unsigned long), and add a decimal place to floats, like this:
void setup ()
  {
  Serial.begin (115200);
  Serial.println ();

  Serial.println (30000L + 30000); // twice 30000
  Serial.println (60L * 60 * 24);  // seconds in a day
  Serial.println (50.0 / 100 * 1000); // half of 1000
  }  // end of setup

void loop () { }

Now we get:
60000
86400
500.00

You only need to help out with the first literal, once the compiler knows we are using longs (or floats) it sticks with them for the expression. *
Or we can "cast" them:
void setup ()
  {
  Serial.begin (115200);
  Serial.println ();

  long a =  (long) 30000 + 30000;
  long b =  (long) 60 * 60 * 24;
  float c = (float) 50 / 100 * 1000;

  Serial.println (a);
  Serial.println (b);
  Serial.println (c);
  }  // end of setup

void loop () { }

Results:
60000
86400
500.00

Casting is useful for variables, because you can't just add "L" to the end of a variable name.
An alternative syntax is to use a constructor like this:
void setup ()
  {
  Serial.begin (115200);
  Serial.println ();

  long a =  long (30000) + 30000;
  long b =  long (60) * 60 * 24;
  float c = float (50) / 100 * 1000;

  Serial.println (a);
  Serial.println (b);
  Serial.println (c);
  }  // end of setup

void loop () { }

(Same results).

* It's actually somewhat more complex than that as this link explains: Understand integer conversion rules
The compiler "promotes" a value in an expression to match another "higher-ranked" type, under certain circumstances. For example, adding an int and a long will result in the int being promoted to a long (regardless of whether it appears first in the expression or not). However if an int is being added to another int, it will not promote them to a long, even though the result may not fit into an int.

More explanations
I was asked in the comments why 1000 * 60 is not the same as 60000 from the compiler's point of view.
The answer is that a compiler will treat an integer literal as an int (if possible) and an int on this platform is 16 bits.
Thus 1000 (an int) * 60 (another int) are multiplied using 16-bit arithmetic, giving a result that overflows.
However the literal, 60000, cannot be stored as an int and thus the compiler promotes it to long (aka "long int"). Since it has been promoted to a long it is correctly stored, and further operations on 60000 will be done with long arithmetic.
I have seen people code 60000 as 60000L however that is unnecessary. The compiler is not silly enough to make 60000 be stored as -5536, as that is clearly not the intent of the programmer.

I think the most important point is that sizeof(int) is 2 on the AVR platform, which is different from about every other current platform I know

Good point. Modern compilers make an int as 32 bits or even 64 bits. However because of space considerations on a microprocessor they chose to make the int be 16 bits wide. See int - Arduino reference

@PMF You seem to be young. I was socialized with CP/M and DOS, even Atari's TOS, and ints had 16 bits for ages. :-D With the dawn of 32 bit system, I found it irritating that an int became as large as a long. Lesson learned by me: Never assume a size, use the types of "stdint.h" or "cstdint" if I need a certain size.

@thebusybee That was mostly before my time, yes. But I also have started to use int32_t and it's siblings just to avoid pitfalls. Luckily, for modern languages such as C# and Java, the size of int is fixed in the specification.

Though this doesn't explain why (1000*60) is different from 60000. Now, I'm guessing the latter is taken as unsigned, so actually 60000, while the former overflows the range of a signed int and gives, um, -5536? (Plus that signed overflow is actually undefined.) The solution of explicitly casting the values to long of course works, but the explanation could be more to the point asked about

@ilkkachu Yeah it does. 1000*60 is evaluated in the domain of int. However 60000 must necessarily be promoted to a long. It would be ridiculous of the compiler to assume that every numeric literal was an int. It assumes they are the least type that will hold the literal (starting at int, not char).

Unfortunately the link I gave has gone link-dead, I'll try to find another.

Here it is - I'll amend my post.

@NickGammon, yes, that's exactly the explanation that appears to be missing from the answer itself.

@ilkkachu You said  Now, I'm guessing the latter is taken as unsigned, so actually 60000 - I'm not sure about the "unsigned" part. See the link I gave above which says in point 4 of "Usual arithmetic conversions":  If the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, the operand with unsigned integer type is converted to the type of the operand with signed integer type.  -- So it may instead be considered (signed) long.

@NickGammon, yeah, I had a vague recollection that there might be an intermediate step of unsigned somewhere. The list here seems to say it's only so for non-decimal bases though: https://en.cppreference.com/w/c/language/integer_constant so indeed it seems to be long in the case here, as you say

@ilkkachu That page seems strangely silent about a leading minus sign (which doesn't apply in this case) however it seems that for decimal literals they are generally considered signed.

Maybe a leading sign is considered a unary operator after the literal has been evaluated. Pages like the above are lengthy enough and still don't completely specify this sort of situation.

@NickGammon, yes, it's a constant+unary minus. It looks to be mentioned there under "Notes": "There are no negative integer constants. Expressions such as -1 apply the unary minus operator to the value represented by the constant."

That makes sense. :)


text:
MacOS Ventura freezes/crashes when i plug in my Arduino Nano Clone
I'm using a MacBook Pro 2013 Late with OpenCore Patcher. Currently Ventura 13.3.1 is installed. Before this version was installed, I had no problem using arduino on my MacOS computer. But right now, when I plug in my Arduino Nano Clone, the computer suddenly freezes and does not respond to any interaction. I have to press and hold the power button to restart the computer.
I tried to plug in another board called NodeMCU which has CH340 chip likewise I did with the arduino, same trouble happened again. So at that point I was guessing it was a CH340 driver problem or something about it. To test my theory, I plugged in my Raspberry Pi Pico and it worked perfectly. So it's probably CH340 chip problem but I could not find any solution in web. May there is a system integrity problem with OpenCore which the version is not compatible with the current operation system version.
If anyone can help me with this issue I'd be really appreciated, since I have a project which must be completed within 3 weeks.

Have a look at this: https://github.com/adrianmihalko/ch340g-ch34g-ch34x-mac-os-x-driver , and this: https://learn.sparkfun.com/tutorials/how-to-install-ch340-drivers/all#mac-osx

Clone Arduino has a history of doing that. Check here:
https://forum.arduino.cc/t/macbook-keeps-crashing-when-i-plug-in-ch340-arduino/440584

source: Stack Exchange

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

sort: votes


text:
Is it possible to get the RSSI value of the connected client or phone in esp8266 if it is set as an access point
Is it possible to obtain the RSSI value of the connected device to the esp8266 similar to obtaining MAC address?

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


text:
is it possible for a client esp8266 to control the esp8266 that set as an access point?
Im creating a project where i need to set one of my esp as a hotspot or access point but i would like to put a function where i could control the connected esp8266 client using the esp8266 that set as access point. I wonder if could use the acces point as a remote to control the client. Thank you in advance.

on the TCP/IP level they are peers


text:
How do I find out the maximum current through VIN on a NodeMCU board?
I read this answer https://arduino.stackexchange.com/a/51878 to a different, but related question. It seems like VIN on the NodeMCU is directly or via diode connected to the USB connector.

Image source: https://arduino.stackexchange.com/a/76119
I'm going to run my NodeMCU with a 5 V power supply connected to the USB connector. And I also need approximately 5 V for another part. So I was thinking of connecting it to VIN of the NodeMCU. So I don't want to power the NodeMCU from VIN, but I want to draw power from VIN for another part.
Is that a bad move or perfectly fine? And if it's okay, how do I find out the maximum current? Because I think the line from USB connector to VIN has some limits, so to not damage the board?

There is some unknown quantities here. NodeMCU made a couple of versions of the ESP8266 development board we all know and love. That was well documented and schematics are available. Then the Chinese took it and cloned it changing the schematic in the process, and called it the V3.  But no one has published official schematics of it, and no one really knows how the diodes are actually connected on that board. I have just ordered one of them from Amazon to do a bit of reverse engineering on it to finally get a definitive answer.

I'll post an answer on this thread, and possibly also write a blog post on my site about it with more detail if I think it's worth it.

You cannot power items from the VIN pin of the NodeMCU V3.
The power circuit is like this:

simulate this circuit – Schematic created using CircuitLab
As you can see no current can flow out of the VIN pin because of diode D2.
You could, though, draw current out of the VU pin, though (situated at the top left of the board when the text is normally oriented) which is directly connected to the USB port's 5V pin.  How much current can you draw? Well, there's nothing in the circuit to limit it, so whatever the USB port that the board is connected to will provide (less enough to run the ESP8266 module).
If you want to draw 1A through the VU pin and the power supply is rated for 2A there should be no problem. The traces for the VU pin are reasonably chunky.
A better solution though would be to power the NodeMCU board and your external components through separate power feeds from the power supply - that way there can be no interference from the board.

Huh... First of all: thanks for looking into it. However, second of all, I don't understand how this is possible. https://i.sstatic.net/6NKYn.png This is exactly how my board looks like. Maybe there are different NodeMCU v3? In your schematic, shouldn't I measure 0 V on VIN because it's against the diode direction? But when I connect USB and measure from VIN to GND pins, I read 5 V. (I get 5 V as well from VU to GND, by the way.) Again, thanks for you help :)

The only way you can get power out of VIN is if the diode is faulty or installed backwards. That board is identical to the one I've torn down. I am half way through a full reverse engineering of the circuit at the moment.

Hmm, no idea what to tell you. The board is basically new, I haven't done anything with it so far. I also read 2 to 3 ohm resistance between VIN and VU in both directions. I think if there would be a diode installed like in your schematic, that also shouldn't be the case. I cannot explain my readings. Is there anything I can do? Which part would be the diode in question? Maybe I can test something there? My equipment is very limited though. :(

@rattlesnake If you have a DMM it should have a diode test mode. It should tell you the forward voltage of the diode. In one orientation it should give you abou 0.25V. In the other it should read open circuit. The diode in question is the one closest to the pins.  If you're interested the copper traces can be viewed here: https://cloud.majenko.co.uk/index.php/s/ewCn6JmYdWWglRj The two diodes are in the bottom left - you can just make out the pads in silver above the bottom left mounting hole. You can see both the diodes connecting the power to the 5V rail - the lower one going right to left...

...from the USB power, the upper going left to right from the VIN pin. From there the 5V goes to the input of the LM1117 voltage regulator.

Well, this is interesting. I do have a digital multimeter. However, it is a very cheap one. It does have a diode test program though. I have never used that before. Can I used it while the diodes are soldered onto the board? On the diode closer to VIN I read 233 in one direction and 1. in the other direction. (Not 1, but 1. which mean infinite for the resistor test program.) For the other diode closer to the edge, I measure 002 or 003 in both directions. So... no idea what that means, but it doesn't make any sense to me.

With the diode near VIN which way round are the probes when you read 233? It should be red towards the outside and black towards the inside of the board. The other diode sounds broken or short circuited. 233 sounds correct though - 233mV is about the same as I measured and is typical for a small schottky diode. If you peer closely at the diodes you should see a stripe at one end, which is the cathode (where the black probe goes for it to read right).

Yes, I can see the stripe with a magnifying lens: https://i.sstatic.net/5Adnr.jpg I hope the photo is good enough. I measure 233 with red left side (towards the outside) and black right side (towards the inside of the board). Isn't that what you said?

@rattlesnake Yep, that's correct. That diode is working fine. You may be measuring 5V on VIN because there's no load and it's just floating. Maybe try powering something small from it and see if it works. The other diode, though, is short circuited. Either because the diode is dead (they usually fail short) or there is a defect in the PCB.

I'm sorry to say but it seems like VIN does indeed work as an output: I connected a 10 kΩ resistor (to limit current to a minimum) and a white LED in series between VIN/VU to GND on the NodeMCU. With both VIN, as well as VU, the LED is on. The NodeMCU is powered by USB from my laptop.

@rattlesnake Maybe these diodes are dodgy pieces of spit then, as the circuit says that shouldn't work, if the diodes were behaving as they should.

Yes, I think I'm not going to look further into it at this point. :) Everything works so far. Thank you very much for your help

Oh, and by the way, reminder if you want to add your findings for the v3 NodeMCU to your previous answer that I found: https://arduino.stackexchange.com/a/51878 (I couldn't comment there because my reputation is too low.)

Just found at least a partial answer in this answer https://arduino.stackexchange.com/a/61030 to a different question:

The component that blew up is a diode. It is designed to protect the USB from voltage being injected into the board. That diode can handle an absolute maximum of 1A. (...) the ESP8266 itself can take more than half that 1A power budget when communicating.

That sounds to me that beginning at about 500 mA, I will risk damaging the NodeMCU if I use VIN as a power supply. So to play it safe, I should probably stay below 250 mA...? Just a guess though. Not a perfect answer yet.

this is what i was going to post. mind the diode; the drop and the heat. sometimes diodes burn up closed, in which case power handling goes up. Replacing or Chernobyl-ing the diode with solder will also multiply the current capabilities at the cost of usb backfeed protection.


text:
Why does the send pin influence the receive pin with Arduino Capacitive Sensing Library
I'm trying to figure out how the Arduino Capacitive Sensing Library https://playground.arduino.cc/Main/CapacitiveSensor/ works. It says:

When the send pin changes state, it will eventually change the state of the receive pin.

However, when I look at the following schematic, I don't understand why this is the case. It seems like the send pin is set to OUTPUT and HIGH and the receive pin to INPUT with deactivated pull-up. I think it's okay to ignore the capacitance at first, yes? Doesn't all the voltage drop over the resistor R and the receive pin will just be floating and showing LOW or HIGH randomly?

Source: https://playground.arduino.cc/Main/CapacitiveSensor/

If we ignore the capacitance of the input pin, then it would instantly follow the voltage of the send pin. A voltage drop over the resistor only happens if a current is flowing though it, which cannot happen without any capacitance the receive side. Without current a resistor is just a wire.
A floating pin doesn't directly have its state randomly changes between LOW and HIGH. That can only be the result as the voltage on that pin is changes by the noise. We need the noise to not be directly in the logic voltage range, so that the state of the digital input pin is not totally dictated by noise. That often the case. Also the additional capacitance added by the sensing foil helps with filtering the noise.
The actual measurement works as follows: We set the send pin to a known state and wait a bit (to fully load or unload the capacitance on the pin). Then we change the send pin to the other state and count the time until we see that change on the receive pin. That is when the capacitance of the pin is loaded. Then we are doing that procedure many times, averaging the measured time. What the receive pin does outside of the measurements is not important. During the meausrement its state is mainly dictated by us setting the send pin. Though the library might use some optimization to get a better reading. You could read the libraries code to learn more about that.

Huh okay. Thank you for the answer! I think I'm learning a lot new stuff here. So you're saying when I simply connect two GPIO pins with a resistor, one is set to output, one is set to input - then no current is flowing at all and therefore the resistor is like a wire? If no current is flowing, how does the input pin "know" the output pin's state?

I wanted to say, that there actually is a bit of current flowing, because you simply cannot leave out the capacitance of the pin in this case. Also the digital input pin is basically a Schmitt trigger, which only has very very low input current. And why shouldn't the input pin "know" the state? It senses voltage, not current. I'm not sure, where the confusion is here.

I'm sorry for the confusion. Yes, it measures voltage. So I thought all the voltage has already dropped over the resistor, so nothing is left to measure at the input pin. But that's the point, right? There is current flowing as long as the "capacitor" (sensor plate + human) isn't charged, so the voltage drops over the resistor. The input pin is low. When it's charged, no more current flows and the resistor becomes a wire, the input pin is now high. Is that correct?

Yes, thats correct

Ahh, thank you. I think I'm beginning to get a grip on it. Sorry, another follow-up question: so the "capacitor" gets fully charged/discharged for every measuring cycle? (I would have thought that's quite a lot of electric charge?)

Yes, it gets "fully" (dis)charges on every measurement (fully to a certain extend, since the voltage will approach the slower when it gets near the supplied voltage, refer to the charging curve of a capacitor). If thats a lot depends on your definition of a lot. In relation to other commonly with Arduino used compnents: No, not a lot. The capacitance will greatly depend on your foil layout/position, but it will be rather small in relation to other normally used capacitors (like the ones in the uF range used for filtering)

Perfect, thanks a lot! :)

Next step is that I just have to figure out why my board keeps showing me erroneous readings for the sense pin haha. (When I set send pin to 1 and keep reading the receive pin, I sometimes get 0, sometimes 1.) If you're interested: https://forum.micropython.org/viewtopic.php?f=2&t=11237


text:
How to save sensor value in EEPROM? (ESP8266)?
I would like to save the height of a tank in case of power outage with EEPROM and every time I reboot the board. However, I could not do so after using EEPROM.commit() , EEPROM.get and EEPROM.put as the reading of the height tank changes every time I tried to reboot it . Am I using it wrongly?
I used EEPROM.get , EEPROM.put , EEPROM.commit in the void setup section so that it will save the data during boot up. However, the tank height just change whenever I changed to a different tank with different height after boot up.
How could I recalibrate the height of the tank if I would like to change to another tank one day, can I just click the RST button on the ESP8266 board?
Thank you
#include <LiquidCrystal_I2C.h>  //1602 LCD library
#include <Wire.h>
#include <EEPROM.h>
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>  //NodeMCU ESP8266 library
#include <BlynkSimpleEsp8266.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

WidgetLED led1(V2);

char auth[] = ""; //Enter your Auth token
char ssid[] = ""; //Enter your WIFI name
char pass[] = ""; //Enter your WIFI password

BlynkTimer timer;
bool pinValue = 1;

long duration;
int distance;
int percentage;
int addr=0;
float tankheight, val;

#define trig D7
#define echo D8
#define relay D5

void setup() {
  Serial.begin(9600);
  EEPROM.begin(512);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  pinMode(relay, OUTPUT);
  Wire.begin(D2, D1);
  lcd.init();
  lcd.backlight();
  Blynk.begin(auth, ssid, pass);
  digitalWrite(trig, LOW);
  delayMicroseconds(4);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  tankheight = duration * 0.034 / 2;
  Serial.print("Tank height");
  Serial.print(tankheight);
  EEPROM.put(addr, tankheight);
  EEPROM.commit();
  val=EEPROM.get(addr, tankheight);
  Serial.print("Addr");
  Serial.print(val);
  timer.setInterval(1L, Wlevel);
  digitalWrite(relay, HIGH);
}

BLYNK_CONNECTED(){
  Blynk.syncAll();

  }

BLYNK_WRITE(V0) {
  pinValue = param.asInt();

}

void loop() {
  Blynk.run();
  timer.run();
  WiFi.setSleepMode(WIFI_NONE_SLEEP);

}

void Wlevel(){  // Initialize detecting water level and relay)
  {
  digitalWrite(trig, LOW);
  delayMicroseconds(4);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  distance = duration * 0.034 / 2;
  percentage= map(distance,val,10 ,0, 100);

  Blynk.virtualWrite(V1, percentage);

  if(percentage<0)
  {
    percentage = 0;
  }
  else if(percentage>100)
  {
    percentage = 100;
  }

 }

 if (pinValue == 1)
    {
       if (percentage < 100)
       {
          digitalWrite(relay, LOW);
          Serial.print("Water level:");
          Serial.print(percentage);
          Serial.print("%");
          Serial.println(" Pump is ON");
          led1.on();
          lcd.setCursor(0,0);
          lcd.print("Water Lvl:");
          lcd.print(percentage);
          lcd.print("%  ");
          lcd.setCursor(0,1);
          lcd.print("Pump: ON  (AUTO)");

       }

       else
       {
          digitalWrite(relay, HIGH);
          Serial.println("Water level is 100%   Pump is OFF");
          led1.off();
          lcd.setCursor(0, 0);
          lcd.print("Water Lvl:");
          lcd.print(percentage);
          lcd.print("%  ");
          lcd.setCursor(0,1);
          lcd.print("Pump: OFF (AUTO)");

       }
    }
   else
    {
      digitalWrite(relay, HIGH);
      Serial.print("Water level:");
      Serial.print(percentage);
      Serial.print("%");
      Serial.println("System is OFF, Check Blynk");
      lcd.setCursor(0,0);
      lcd.print("Water Lvl:");
      lcd.print(percentage);
      lcd.print("%  ");
      lcd.setCursor(0,1);
      lcd.print("System is OFF   ");
      led1.off();

    }

   }

have you actually examined your own program? ... what's the point of using the EEPROM when first thing you do is to wipe out the stored value ?

@jsotola I am a beginner to programming and I am trying very hard. Which part of the code that will wipe out the stored value? I thought I put the EEPROM command in the void setup so that the tank height will be put inside the EEPROM? Am I doing it wrongly?

take a look at all program lines that start with EEPROM ... see what each one does

why do you want to save the water level?

@jsotola
I would like to save the tank height at the start so that whenever there is a power outage, the tank height will not erase on itself after reboot.
From the code, I first put the tank height into addr using EEPROM.put and then save it using EEPROM.commit. After that, I read it again and put into "val".
Down below I also wrote "percentage= map(distance,val,10 ,0, 100);" , the val should be the saved tank height and the 10 is the distance from the ultrasonic sensor to maximum water height.

and you do not see a problem with first saving the water level after reboot? ... think about it ... this really has nothing to do with programming

Use a different button - you may have to wire something up...
In the loop, read the button and only if it is pressed should you re-calibrate and set the value to eeprom.  You can do it in setup too but then you would have to reboot with the button pressed to trigger re-calibration.
You can also read a serial command in the loop.  Anything external that can be triggered with a separate intent to re-calibrate would work.  A power outage resembles the normal reset too much.  To execute different behavior in two different scenarios, you must be able to detect which scenario you are in.

How about if I add an virtual button in the Blynk apps so that I can calibrate it using the Blynk app instead a physical button? Regarding the calibration and EEPROM, am I supposed to create another loop in another function or inside the void setup function is enough ? Thank you

virtual button could work.  if there is some gui in the Blynk apps, then your call to write eeprom belongs in something called by Blynk.run() (which your loop function calls) not setup.


text:
SPI problem with Bitcraze PMW3901 sensors and Arduino NANO
I am currently trying to connect four Bitcraze PMW3901 sensors to an Arduino NANO, but I seem to have issues with the SPI. When I connect two sensors using the code below, it works perfectly: I am able to retrieve the X and Y data from the serial port for both sensors.
include "Bitcraze_PMW3901.h"

 Bitcraze_PMW3901 flow(10);
 Bitcraze_PMW3901 flow2(9);

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

  if (!flow.begin()) {
    Serial.println("Initialization of the flow sensor 1 failed");
    while(1) { }
  }

  if (!flow2.begin()) {
    Serial.println("Initialization of the flow sensor 2 failed");
    while(1) { }
  }

}

int i =0;
int16_t deltaX,deltaY;
int16_t deltaX2,deltaY2;

void loop() {
  if ((i % 2) == 0) {
    digitalWrite(10, LOW); // sets the digital pin 10 on
    flow.readMotionCount(&deltaX, &deltaY);
    digitalWrite(10, HIGH);  // sets the digital pin 9 off
  }

  if ((i % 2) == 1) {
    digitalWrite(9, LOW); // sets the digital pin 10 on
    flow2.readMotionCount(&deltaX2, &deltaY2);
    digitalWrite(9, HIGH);  // sets the digital pin 9 off
  }

    i = i + 1;
    Serial.print("X1:");
    Serial.print(deltaX);
    Serial.print("\t");
    Serial.print("Y1:");
    Serial.print(deltaY);
    Serial.print("\t");
    Serial.print("X2: ");
    Serial.print(deltaX2);
    Serial.print("\t");
    Serial.print("Y2:");
    Serial.print(deltaY2);
    Serial.print("\n");

}

However, when I try to add a third Bitcraze PMW3901 sensor I cannot seem to be able to initilize it. Still, I declare a separete SS as

Bitcraze_PMW3901 flow3(6);

and add the initialization code in the setup() function as follows

if (!flow3.begin()) {
Serial.println("Initialization of the flow sensor 3 failed");
while(1) { }
}

What I get is the sentence "Initialization of the flow sensor 3 failed" or "Initialization of the flow sensor 1 failed" (it depends and I don't really understand why, since the code is always the same) printed on the serial port window.
I have already checked my sensors: they all work separetely and two-by-two. Do you have any suggestions? I hope I have managed to explain the problem clearly, otherwise please let me know if I can add or specify something more. Thank you in advance for your help!

powering issue? how do you power the sensors?

Do your sensors incorporate a tri-state buffer on the MISO line for each device?

Hi Juraj! I power the sensors directly through the Arduino Nano. I have already tried to use an external battery, but the result didn't change so I don't think that is the issue.

Hi sempaiscuba! I actually don't know and I can't seem to find this information on the sensors' datasheet. Could you please explain what would be the problem or the advantage of that? Thanks in advance!

Most SPI chips will be at tri-state on their MISO pin when their chip select signal is HIGH. Tri-stage means that it is neither HIGH nor LOW (i.e. floated) and effectively disconnect. However, it is not always the case. A SPI device without tri-state MISO could caused potential problem on a SPI bus where multiple SPI devices are connected. If the MISO is unable to be at tri-state, it will be either HIGH or LOW, this will affect other devices connected on the same bus in receiving data. see this for more explanation and solution.

It seems that the library is set to running the SPI at 4MHz, this might be a problem when running with multiple slaves, you might want to try to change the library manually to say 1MHz and see if it works?

Hi, I am facing the same issue with the pmw3901 sensors when connected to teensy 4.0
@wolly94 were you able to solve your problem? If yes, please could you mention the changes you made?


text:
I2C and logic shifter troubleshooting
I'm attempting to use a SparkFun bidirectional level shifter  (Link here) to connect up a 3.3v wii nunchuk to a 5v Arduino Uno circuit. For now all I'm trying to do is write the position of the joystick and buttons into the monitor. When I include the shifter in the circuit, the code returns values that are way off what they should be, into the thousands or sometimes minuses. However, when I connect the controller without the shifter (at risk of burning out my controller), the code runs as normal, returning back the x and y axis of the joystick at around 130. Both push buttons have a similar issue, where they read as pressed at random intervals when not even touched. What could be causing the data to be off? I've tried rewiring several times, and am following the SparkFun general use page as a guide, and so hopefully miswiring shouldn't be the issue.
Here is the code:
#include <Wire.h>
#include <ArduinoNunchuk.h>

#define BAUDRATE 19200

ArduinoNunchuk nunchuk = ArduinoNunchuk();

void setup()
{
  Serial.begin(BAUDRATE);
  nunchuk.init();
}

void loop()
{
  nunchuk.update();
  Serial.print(nunchuk.analogX, DEC);
  Serial.print(' ');
  Serial.print(nunchuk.analogY, DEC);
  Serial.print(' ');
  Serial.print(nunchuk.zButton, DEC);
  Serial.print(' ');
  Serial.println(nunchuk.cButton, DEC);
  Serial.print(' ');
  delay(250);
}

Library source :http://www.gabrielbianconi.com/projects/arduinonunchuk/

Please show a picture of your wiring. A fresh pair of eyes may spot something you missed.

print the values in hexadecimal ... add a listing of the values to your post ... include a description of what you were expecting to see


text:
ESP32 Wipe Sensitive Key Data
Is it possible to ensure that keys (e.g. ssid, ssl certs) are wiped from the memory of a esp32?
I'm new to the esp32, coming from a IoT device security perspective.
Say a person was testing an esp32 application that utilized WIFI, in which sensitive keys are embedded in the firmware. They then overwrote the esp32 with a small led blink firmware in an attempt to clear said keys.
I would like to know if flashing a small "blink" program will be sufficient to remove the keys, so the esp32 could be repurposed without worry that a firmware dump would reveal past firmware information.
This question is specifically targeting scenarios where the esp32 is for development purposes (fuse bits are never burnt - mind I think there is a security flaw where chip can be dumped anyhow).

You can use esptool.py to run an erase_flash operation.

Erase Flash: erase_flash & erase_region
To erase the entire flash chip (all data replaced with 0xFF bytes):
esptool erase_flash

To erase a region of the flash, starting at address 0x20000 with length 0x4000 bytes (16KB):
esptool erase_region 0x20000 0x4000
The address and length must both be multiples of the SPI flash erase sector size. This is 0x1000 (4096) bytes for supported flash chips.
-- esptool basic commands

As far as copy protection goes you can encrypt the flash contents so even if the chip is read directly without the decryption key they won't be able to make any sense of the data.

Thanks for the information Majenko! I was wondering if in addition to your answer, if flashing blink firmware (or any other small custom firmware) will be sufficient in overwriting all existing firmware data? If true, then perhaps erase_flash will not be required.

@PathToLife I'm not sure if doing a normal code upload wipes all the flash or not. You could try doing a big upload followed by a small upload then read all the flash with esptool and see what remains of the big upload...

@RDragonrydr You could manually encrypt the data you store in the NVS using your own software in your sketch. Without the keys (which are in the sketch, so would be overwritten by new code) decrypting the data would be nigh on impossible.,


text:
Can't read through I2C from RTC
I'm using an ESP32 which I connected to a MAX31329 RTC through I2C.
Unfortunately I can't read any register from the RTC. After modifying the MAX31328 library didn't work, I tried reading single registers directly. Here is the code:
#include "Wire.h"

int seconds = 0;
int ret = 0;

void setup() {

Serial.begin(115200);
delay(500);

Wire.begin(33,32,100000);

delay(500);
Wire.beginTransmission(0x68);
  Wire.write(0x06);
  Wire.write(13);
  ret = Wire.endTransmission();
  if(ret != 0)
    Serial.println("i2c Setup failed");

  delay(500);
}

void loop() {

  Wire.beginTransmission(0x68);
  Wire.write(0x06);

  Wire.requestFrom(0x68,1);
  seconds = Wire.read();
  ret = Wire.endTransmission();
  if(ret != 0)
    Serial.println("Read failed");

  Serial.println(seconds);

delay(1000);
}

The register always returns 0.
Do you see the error in my code?
The datasheet of the MAX31329 can be found here.
I'm trying for days now and have no clue what the problem is.
Thanks a lot for your support in advance.
Best regards,
Martin

To read the max31329 you do need to do the following as Nick Said
Wire.beginTransmission(0x68);
Wire.write(0x06);
ret = Wire.endTransmission(false); //No Stop, so the request is a restart

Wire.requestFrom(0x68,1);
seconds = Wire.read();

But it needs to be a repeated restart following the write to register 0x06, hence the false in Wire.endTransmission(false). It took me ages to figure out as the DS3231 and MAX31328 don't required this, I actually found this writen in the data sheet for the MAX31343 which has a similar set of registers with seconds starting at 0x06 unlike the previous clocks that start at 0x00. Interestingly with these ones, reading the status register 0x00 will return to you any flags for interupts and automatically reset them after reading the register, which I think is new and better.

You are doing things in the wrong order.

 Wire.beginTransmission(0x68);
 Wire.write(0x06);
 Wire.requestFrom(0x68,1);
 seconds = Wire.read();
 ret = Wire.endTransmission();

The request is sent on the endTransmission call, so you need to do that before trying to get a response. In other words:
  Wire.beginTransmission(0x68);
  Wire.write(0x06);
  ret = Wire.endTransmission();

  Wire.requestFrom(0x68,1);
  seconds = Wire.read();

I have been using the ESP32 for about 10 years now and it can be finicky
I2C is an Open Collector interface requiring Pull-up resistors to work.
If you are using a board module it likely has the pull-ups if not make sure you have them (around 1.5K OHMS) from SDA and SCL to 3.3 Vcc.
I suggest starting with Arduino's i2cdetect.ino and debug if it is being seen.
If not you have a wiring issue.
while both other answers are fairly good, you show no schematic or mention if you are using a RTC board.


text:
Help with Arduino sleep and watchdog timer interrupt
I want to use Arduino's sleep and wakeup functionality but have hit a roadblock and can't seem to get past it. As I am just prototyping for a final system, I cannot use the LowPower library to implement the functionality so I am doing it barebones. I am able to put the Arduino to sleep just fine, the main problem is with the watchdog timer. I have or I think I have configured it for a 8 sec interrupt to wake the Arduino back up from sleep but Arduino comes out of the sleep just as it enters it without any delay.
The code is
#include <Arduino.h>
#include <avr/sleep.h>

void goToSleep();
void setupWDT();
void stopWDT();

ISR(WDT_vect) {
  sleep_disable(); // wake up the Arduino
}

void setup() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  stopWDT();

  pinMode(LED_BUILTIN, OUTPUT);

  Serial.begin(9600);
  Serial.println("Uno is in setup funtion.");

  bool ledState = 0;
  while(millis()<3000){
    digitalWrite(LED_BUILTIN, ledState);
    ledState = !ledState;
    delay(500);
  }
}

void loop() {
  Serial.println("Uno is awake.");
  digitalWrite(LED_BUILTIN, HIGH);
  delay(2000);
  Serial.println("Going to sleep...");
  digitalWrite(LED_BUILTIN, LOW);
  delay(100);

  setupWDT();
  goToSleep();
  stopWDT();
  delay(100);
  digitalWrite(LED_BUILTIN, HIGH);
}

void goToSleep() {
  ADCSRA &= ~(1<<ADEN); // disable ADC
  sleep_mode(); // put the Arduino to sleep
}

void setupWDT() {
  cli();
  WDTCSR |= (1 << WDCE);
  WDTCSR &= ~(1 << WDE);
  WDTCSR |= (1 << WDCE) | (1 << WDIE) | (1 << WDP3) | (1 << WDP0); // configured for 8 sec delay interrupt
  sei();
}

void stopWDT() {
  cli();
  MCUSR &= ~(1 << WDRF); // clear reset flag
  WDTCSR |= (1 << WDCE);
  WDTCSR &= ~(1<<WDE);
  WDTCSR = 0x00; // stop WDT
  sei();
}

Try changing this:
void setupWDT() {
  cli();
  WDTCSR |= (1 << WDCE);
  WDTCSR &= ~(1 << WDE);
  WDTCSR |= (1 << WDCE) | (1 << WDIE) | (1 << WDP3) | (1 << WDP0); // configured for 8 sec delay interrupt
  sei();
}

to:
void setupWDT() {
  cli();
  WDTCSR = (1 << WDCE) | (1 << WDE) ;
  WDTCSR = (1 << WDCE) | (1 << WDIE) | (1 << WDP3) | (1 << WDP0); // configured for 8 sec delay interrupt
  sei();
}

It appears that your construct violates the 4 clock cycle window that the WDCE Watchdog Change Enable bit allows for updates to the WDE bit.


text:
Is it possible to use flash encryption in esp32 in Arduino ide
Just already finished writing the program in arduino ide, but were just thinking if i could use flash encryption in esp32 using arduino ide for commercial use? Cause i am still new to this esp-idf stuffs and wondering if i could set some security config using arduino ide.


text:
are 4AA batteries (6V) power my arduino
I'm actually new to using arduino , and trying to make a simple car, using two dc motors, a l298n and an arduino, the problem is that a 9v battery doesn't seem enough to just power the l298n and one dc motor , but in the internet some people use an 4AA battery which is 6v and power the arduino 4 dc motors and the l298n so how ?

Have you seen any of these Q+As? https://arduino.stackexchange.com/search?q=l298n

I understand you situation completely as I had also previously experienced the same problem. 9 V batteries are not enough to get the job done.
Therefore, I suggest you to use two 3.7 V Batteries. These batteries are a great alternative and had solved my problem. I hope it will do the same to you.

The name Arduino refers to dozens if not hundreds of different board and processor designs. Since a specific board / processor was not asked about we can only talk in generic terms.
Almost all Arduinos run at either 5 Volts or 3.3 Volts and contain a regulator to convert a wide range of Voltages to this value. That said, these regulators need a minimal drop between the input voltage and the desired regulated voltage in order to operate.  Some require less and are referred to as LDO or Low Drop Out regulators.
As a worse case, consider if this Arduino does not use an LDO regulator and operates at 5 Volts. The difference between the 6 Volt input and Arduino operating Voltage is only 1 Volt. Further, consider if the batteries were not fresh and were only supplying, say, 5.5 Volts. Finally, consider if one or both motors started drawing heavy current from the batteries causing a further drop in Voltage. Any of these cases could cause the Arduino to reset / behave unexpectedly.
Consider trying to use the 9 Volt battery to power the Arduino and the 6 Volt battery to power the motors.

To properly answer your question instead of taking a SWAG as I did would Be for you to post links giving technical information on each of the hardware devices and which Arduino you are using.
Nine Volt (smoke alarm) batteries do not have enough power to properly power an Arduino. Use some larger cells. There are so many places that show this improper configuration, it just will not last if it even works for a short while. Great for the battery manufacturers.
You can also purchase a SEPIC converter for a few bucks, this is a combination Buck/Boost converter. You set the output voltage you want and it will maintain it as long as you're getting the minimum voltage from the battery, even if the battery is at 3.5V and the output is at 5V. The input will range from about 3V to 30V and it will maintain its setpoint. This range is dependent on the device you pick.
The L298N is about the worce choice you can make for the motor driver. It has darlington bipolar outputs, that drop about 1.4 volts per lead or 2.8 - 3.2 volts to the motor depending on the load. That voltage drop is burnt up as heat and is doing nothing useful. Purchase an H-Bridge that is large enough to drive the motor that has MOSFET outputs, you will be much happier with that.
For batteries use whatever is convenient, the SEPIC converter solves that problem. Best to pick them to power the motor and use the SEPIC to power the Arduino Vin pin at about 7.5V. Doing it via the Vin is not as efficient as doing a 5V direct but you get the additional filtering on that input circuit. A lot depends on which Arduino we are talking about. Since you did not mention one I am assuming either a UNO or Nano.


text:
Analogue input spikes
i have a project where i read two analogue inputs from two sensors and a pro Mini. I have some spikes in my readings that are present when i'm powering the system using a powerbank step-up module. When i use a 7805 and a 9V battery, the results seem clear. The spikes appear every 600-650ms.
Is there any way to filter them out on a hardware level without using code?
The frequency of the spikes is about 1.5HZ, too slow for a typical ripple of a "dirty" dc converter i think.
My first though was that the module was checking for sufficient load to stay powered on. I added a dummy load but nothing changed. The project is a datalogger and unfortunately i don't really want the code to do the filtering, as it's gonna cost me some speed.

Re “i don't really want the code to do the filtering, as it's gonna cost me some speed”: A 3-point median is a very cheap filter speed-wise, and should be quite effective against this kind of spikes.

Are you charging a battery while you are running the program?

No, i'm using a fully charged 18650 battery, not plugged in into an external charger.

@stelPet to me, my initial thought process points to an inductive spike. I'm wondering if putting a snubber diode across the inductor will help with them; if not, you would have to resort to implementing a hardware filter as described below. Two more things to consider - how are you checking the voltage? If you are using a scope with an isolated ground, then you'd have to make sure that the ground are bonded together with the module and the scope - there was a thread on AllAboutCircuits - when I'll find it I'll link it. You could ask in EE SE.

@stelPet also, commercial dataloggers often use digital filters for filtering out 50/60 Hz and stuff like that. What is the application for your datalogger? Unless it's a high-speed acquisition FPGA-based datalogger, I doubt you'd have too much impact on your processing if you do minor digital filtering - it might be just easier to use Edgar's advice rather than fiddle around with soldering stuff to the module (at that point, you should be making your own module, I'm sure there are good charge regulator ICs out there).

On a hardware level, without a substantial delay, you could use active filters, such as active low-pass or band-pass filters, that can provide better control and customization over the filtering process.


text:
What's is the best way to convert std::string to String?
Pardon me, I am a novice programmer. I was trying to use the toInt() function for a std::string but I noticed that toInt() only works for the String class. So, I have an std::string sliderValue and wanted to convert it to the String class so I could use the toInt() function. Here, I found a way that seemed to pacify Intellisense, vMicro, and building. I did:
String convertValue = strcpy(new char[sliderValue.length() + 1], sliderValue.c_str());

so I could do:
ledcWrite(ledChannel, convertValue.toInt()  * (10.24));

Is there a better way to do this or am I on point? Also, I'd love to get insight in what I'm doing, if possible. Thanks folks!
P.S. I looked up this here at arduino stackexchange, and it didn't seem to provide a solution specific to my question.

If you have std::string, chances are you also have std::stoi

There is absolutely no need to use String (for anything, generally...). Instead you can either (if you have it) use std::stoi() or use strtol() on the c_str of the string.
ledcWrite(ledChannel, std::stoi(sliderValue)  * (10.24));

Or
ledcWrite(ledChannel, strtol(sliderValue.c_str(), NULL, 10)  * (10.24));

The former just converts into the latter anyway.


text:
String operations printing random character on Serial Monitor
I want to extract the file name MyFile.txt out of a path which is stored in a string "C:\\MyDirectory\\MyFile.txt";
I found a simple c code which does the job.
string filename = "C:\\MyDirectory\\MyFile.bat";

// Remove directory if present.
// Do this before extension removal incase directory has a period character.
const size_t last_slash_idx = filename.find_last_of("\\/");
if (std::string::npos != last_slash_idx)
{
    filename.erase(0, last_slash_idx + 1);
}

// Remove extension if present.
const size_t period_idx = filename.rfind('.');
if (std::string::npos != period_idx)
{
    filename.erase(period_idx);
}

I had to alter few things for arduino code
example replace find_last_of with lastIndexOf, erase with remove and rfind with lastIndexOf
Here the ino file
#include<string>
void setup() {
  Serial.begin(9600);

}

void loop() {
   String filename = "C:\MyDirectory\MyFile.bat";

// Remove directory if present.
// Do this before extension removal incase directory has a period character.
const size_t last_slash_idx = filename.lastIndexOf("\\");
if (std::string::npos != last_slash_idx)
{
    filename.remove(0, last_slash_idx + 1);
}

// Remove extension if present.
const size_t period_idx = filename.lastIndexOf('.');
if (std::string::npos != period_idx)
{
    filename.remove(period_idx);
}
Serial.println(filename);
delay(1000);
}

Expected output MyFile
When I look into Serial Monitor I get
c$$⸮'<;⸮⸮/<⸮⸮$⸮''⸮;,#$$⸮'<;⸮⸮'<⸮⸮$⸮''⸮:$#$$⸮'<;⸮⸮'<⸮⸮$⸮''⸮;$#$$⸮'

What am I doing wrong?

Did you choose 9600 baud in the serial monitor?

Yes this was on 9600

#include<string>

Remove this. Arduino uses its own String class, different from the STL
string.

String filename = "C:\MyDirectory\MyFile.bat";

There is no '\M' escape sequence in C++ strings. You probably mean
"C:\\MyDirectory\\MyFile.bat".

const size_t last_slash_idx = filename.lastIndexOf("\\");

String::lastIndexOf() returns an int, not size_t.

if (std::string::npos != last_slash_idx)

No std::string here. String::lastIndexOf() returns -1 to signify
that the character was not found.
With all these fixes, your sketch should work as intended.


text:
RTClib.h problem
In Library Manager RTClib and DS3231 work somehow with older versions. RTC time can picked only once and then it give bullshit. Using newest versions screen is empty.
In picture first time is right, others no.
Problem occurs, when loading new driver versions.Earlier code  have been working for years. Sure driver problem ....?

so, what is your question?

More likely a bug in an earlier RTCLib version masked a bug in your code. The two kind of cancelled out. Now the bug (or "feature") has been fixed it's exposed the bug in your code.

Putting last version 1.14.0 of RTClib do not help. Simple call " DateTime now = rtc.now();  " works only one time; thats my question.

Thanks for kind help, problem nearly solved: IR remote and DS3231 clock don't live well in nano board, maybe still a bug in drivers.

@PetriHietala Putting last version 1.14.0 of RTClib do not help. Simple call " DateTime now = rtc.now(); " works only one time; is not a question ... it is a description of the observed behavior .... a question is something like how can I debug the problem? or where can I get the source code for the library? or what is the color of grass?


text:
stop motor instantaneous with hall sensor problem
I have a problem with stopping motor at same spot when magnet pass.. I tried to add interrupt and to make code as clean as possible but no joy so far. Any suggestions? sw will add later, just ignore..
byte outPin = 12;        // the number of the output pin
byte inPin = 2;          // the number of the input pin

byte hallPin = 3;        // hall sensor

byte sw;
byte previous;
int state = LOW;         // the current state of the output pin
int reading;             // the current reading from the input pin

void setup()
{
  pinMode(inPin, INPUT_PULLUP);
  pinMode(outPin, OUTPUT);

  pinMode(hallPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(hallPin), stop, FALLING);   //hall read low when magnet pass
}

void loop()
{
  sw=0;

  reading = digitalRead(inPin);       //read(LOW when press!)
  if (reading == HIGH) previous=0;

  if (previous == 1 && sw == 0) state=LOW;
  else if (reading == HIGH) state=LOW;
  else state=HIGH;

  digitalWrite(outPin, state);
}

void stop() {
  if (sw == 0 && reading == LOW) {
    state=LOW;
    previous=1;
  }
}

What is the problem you are facing exactly?

well code works, but I'm having delays, and motor does not stop instantly... any way to enhance code further?

You can enhance it by switching changing state's declaration to volatile bool state ...

motor does not stop instantly ... can you stop a car instantly?

@timemage will try that, thanks

@jsotola well true that, but I meant at least on approximately same spot at least...

stopping instantly and stopping at a chosen spot are two different things ... think about stopping a car at a stop sign ... how is that done? ... the motor behaves the same way as the car

I didn't notice before, but same with sw and previous regard to volatile. If these aren't factoring into the problem, you could update the code to include them so that they're not there anymore as a distraction from whatever the actual issue is.

@milos, what board are you using?

@Coder9390 arduino Micro

You can stop a BDC faster if you short-circuit it. This is possible with an H-Bridge and the appropriate components.
It would be easier to use a L293D, which already provides this mode.
If you want to try it with this component, of course you can also build the h-bridge yourself, pay attention to the D on the component. With the D-version the protection diodes are already built in. You can power two motors from 4.5V to 36V with a maximum current of 600mA.
For up to 2A you can use a L298N.

He may be able to stop it still faster by powering it in reverse for a very short time. The current draw can be very large though.

@Georg Thanks for recommendation, will consider if no code give acceptable result

The motor can't stop instantly because it has inertia, plus the inertia of whatever stuff the motor is moving.
So if you want it to stop at a set position, you have to slow it down before it reaches the desired position, so it will come to a stop where you want. It's not possible to do that with only one sensor.
A complicated solution would be to use a position encoder, like a rotary encoder, to know the position at all times, so you could use a control algo like PID on the motor. This offers the most features, as you can then set the desired stop position in software, without needing to move the sensor.
If the stop position never moves then a simpler solution is to use multiple sensors. That's often how it's done with elevators: there is a sensor to accurately align the elevator with the floor it has to stop on, but there are also several others slightly before that on the track to tell the controller that it's time to start slowing down, then slow down to a crawl, then stop.
To keep it simple you can use just two sensors: when it goes past the first, slow down the motor to a crawl. When it activates the second sensor, since it is going slow, it will stop quickly and end up where you want.


text:
Encoder giving value between steps
I'm trying to interface an encoder and a 1602 i2c display. My encoder seems to be giving an output between steps.
I have tried to make my code as simple as possible and am outputting whether the encoder rotated clockwise or counter clockwise to serial. When I rotate the knob one physical step clockwise, '++' (separated by a new line) outputs to the serial monitor when I am expecting just '+'.  The same occurs when rotating counter clockwise, except with '--' instead of '++'.
Parts:

ESP32 Dev Board
Rotary Encoder

Code:
#define enc1 32
#define enc2 33
#define button 25
#define led 2;

int oldPos1;
int newPos1;
int newPos2;

void setup() {
  pinMode(enc1, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(enc1),encRead,CHANGE);
  pinMode(enc2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(enc2),encRead,CHANGE);
  Serial.begin(115200);

  oldPos1 = digitalRead(enc1);
}

void encRead(){
  newPos1 = digitalRead(enc1);
  newPos2 = digitalRead(enc2);
  if(oldPos1 != newPos1){
    if (newPos1 == newPos2){
      Serial.println("+");
    }
    else{
      Serial.println("-");
    }
  }
  oldPos1 = newPos1;
}

void loop() {
  delay(10);
}

remove the enc2 attachInterrupt

This is the kind of thing that can happen when you buy cheap parts that
come with no documentation whatsoever: you don't know how they are
supposed to work! Many rotary encoders have two detents per pulse: if
you rotate them by a single detent, you get a single transition on each
pin. If using such an encoder, you would indeed expect a single + or
- printed per detent. But what about the encoder you bought? You can't
tell, since there is no documentation!
Quite fortunately, a helpful individual left a useful review on the
product page you linked to. It can serve as an ersatz of datasheet:

Each movement of the spindle from one detent to the next results in
the encoder1 and encoder2 pins going through multiple transitions, not
a single one (as you might expect).
Assuming that you have tied the encoder pins to (say) 5V with a
resistor, a rotation between detents, will produce a set of encoder
transitions. For example: 11 10 00 01 11 (clockwise) or 11 01 00 10 11
(anti-clockwise).

This explains the behavior you are experiencing.
Side note: as jsotola writes in a comment, you should
remove the enc2 attachInterrupt(). As your interrupt handler
explicitly ignores transitions in enc2 (it does nothing unless enc1
changed), there is no point in interrupting the processor for those
ignored transitions.

Unfortunately you did not provide a link to the data sheet of the encoder.
One physical step at the knob can generate changes on both pins. And since you have assigned the interrupt service routine to both pins, it is called two times for each physical step.
Another possible reason is "bouncing" of the mechanical contacts in this encoder. That means, that multiple pulses are generated on the change between open and closed. Therefore, change or edge interrupts are only a correct solution, if you take bouncing into account.
To investigate the issue, you can insert port pin toggles to your interrupt service routine. For example, set a pin on entry and reset it on exit. Then connect an oscilloscope or logic analyzer and compare the input signals and this output.
Oh, and it is never a good idea to put serial output in an interrupt service routine. Depending on the amount of sent data and the chosen baudrate, this output will block the routine for several milliseconds. During this time, the same interrupt is not serviced, and can be skipped in case of multiple triggers.


text:
Confusing language on arduino docs about powering via 3V3/5V pins
I'm reading about powering alternatives for the arduino board, and I have run across two confusing sentences in Section 5, powering via 3V3/5V pin. First, it says:

3V3 and 5V pins can also be used as power inputs if no regulated power supply is connected through the other power inputs (USB port, barrel jack connector or VIN pin).

But then right afterwards, it says:

Although 3V3 and 5V pins can be used as power inputs, it is not recommended if no power supply is connected through the USB port, the barrel jack connector, or the VIN pin.

(emphasis mine)
Which is correct? When powering via the 3V3 or 5V pin, should I have a different power supply connected elsewhere, or not?

they are both correct ... one says you can do this ... the second one says but it is not recommended that you do this ... similar to  you can run across the street ... but it is not recommended that you run across the street .... they are basically saying don't use the arduino as a power supply if you can avoid it

The issue appears to be backfeeding the voltage regulator which is connected to the 3.3v or 5v pins. Some voltage regulators don't like it (see https://electronics.stackexchange.com/questions/110314/how-can-i-tell-if-my-power-supply-regulator-will-accept-backfed-current).


text:
Arduino IDE doesn't find header file
I'm trying to start with the SainSmart 4x20 serial LCD, and copied the library to the Arduino library:

So LiquidCrystal_I2C.h is included. But when I try to compile an example sketch it says

Arduino: 1.7.0 (Windows 7), Board: "Arduino Uno"
HelloWorld_i2c.pde:2:31: fatal error: LiquidCrystal_I2C.h: No such file or directory
compilation terminated.
Error compiling.

Any ideas how to fix this?

There is no such thing as Arduino 1.7.0. At the time of writing, the latest Arduino IDE is 1.6.3 http://arduino.cc/en/Main/Software

It may be the 'Arduino.org' ripoff version. Test the same sketch in the Official Arduino IDE, the one linked by @FedericoFissore

I copied the SainSmart library to the IDE's library folder, not noticing that there was already a folder named "LiquidCrystal". Apparently the files added to the existing folder are being ignored.
Renaming the SainSmart library before adding it solves the problem.

There is not enough info to give a specific answer so I will give some troubleshooting tips:

First make sure at the top of your code you have: #include <LiquidCrystal_I2C.h> - with angle brackets
You may also need the Wire header file: #include <Wire.h>  - with angle brackets
Make sure you Include Serial
Make sure there are no extra folders in the library for example there should be a folder called liquidcrystal inside the liquidcrystal folder
If all fails copy the code from the header file make a new file in the IDE paste it in there and call it LiquidCrystal_I2C.h

Hope one of those solves your problem.

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


text:
What does the .ino file extension mean
What does the .ino file extension mean?
We have .cpp meaning C++, .py meaning Python, .exe meaning executable and so-on.They're obvious. The .pde file type that sketches previously used, I think, comes from processing development environment (the arduino IDE being based* on / inspired by processing).  But what does .ino mean?
There's plenty that explains what such files are, but nothing explains what those three letters mean, if anything.
* source wikipedia

The last 3 letters of Arduino?

Arduino

That's all there is to say about that really.

As commented in the source code

The file extension for sketches has changed from .pde to .ino, to avoid
conflicts with the Processing software ("ino" are the last three letters
in "Arduino").

A citation, if anyone cares to have one.

@timemage Very good! Thanks for the citation.

Nice one @timemage I've added that to the answer.

And .ard was probably already taken https://fileinfo.com/amp/extension/ard

"Arduino" is an Italian word, and "ino" is the suffix which lends itself well to a filename extension.
From Google Translate of Italian ino:

ino

Suffisso alterativo di aggettivi e sostantivi; nei primi ha valore diminutivo-vezzeggiativo, talvolta con sfumatura ironica ( biondino, carino ), oppure significa appartenenza etnica ( alessandrino, cadorino ), collegamento con materie ( argentino, salino ); nei secondi, oltre ad avere valore diminutivo-vezzeggiativo ( gattino, pensierino ), indica pure un mestiere ( ciabattino, tamburino ), uno strumento o arnese o apparecchio ( cerino, lavandino ); in alcuni casi è applicato a verbi ( imbianchino, accendino ).
In chimica organica, suffisso che nella nomenclatura ufficiale indica gli idrocarburi acetilenici, cioè gli alchini ( etino ).

Alterative suffix of adjectives and nouns; in the former it has a diminutive-pet name, sometimes with an ironic tinge (blond, cute), or it means ethnic affiliation (Alexandrian, Cadore), connection with materials (Argentine, saline); in the latter, in addition to having a diminutive-pet name (kitten, little thought), it also indicates a trade (cobbler, drummer), an instrument or tool or apparatus (match, sink); in some cases it is applied to verbs (painter, lighter).
In organic chemistry, suffix that in the official nomenclature indicates acetylenic hydrocarbons, i.e. alkynes (ethin).


text:
Is it possible to connect 2 PLC which have Ethernet interfaces using Ethernet shield, arduino Nano and SX1278?
I need to connect 2 PLC which have Ethernet interfaces over 1 km and i was thinking of connecting via SPI an ethernet shield and an SX1278 module to a arduino nano (UNO) board.
Do i need logical converter between Nano and SX ? (I saw a lot of videos showing people doing it without the logical converter)
Is it Nano capable of handling the information passing from Ethernet to SX ?
If possible,  where can i find an example of such setup ?

The simple fact you are asking this question means you don't have the skills or knowledge to comprehend what it is you are asking (I don't mean this in a nasty way, just that in having to ask it shows you lack some of the basic knowledge you will first need to accomplish the task).
Firstly you need to understand what Ethernet is.  The cable itself is just one layer (the "Physical" or lowest layer) of the 7-layer OSI model.
On top of that are 6 more layers at increasing levels of abstratcion.
You will need to understand what is being communicated between the two PLCs and at what layer of the OSI model it makes the most sense to create your bridge.
Do you do it at the application level, where you receive the data that is sent by a PLC and interpret it, then send that interpretation over the bridge to be reconstructed at the other and? Or do you do it at the socket layer where you capture the raw information and send that, or at the transport layer where you take the network data and forward that, or at the data layer where you take the ethernet electrical signals and pass that logical data to the other end to be replicated?
But then of course there is the other question: Is it actually Ethernet? Or is it some other protocol that just happens to use CAT5 (or similar) cables to transfer the data? If that is the case you first need to what that protocol is before you can even consider connecting anything to the wire.
Only once you have answered those questions can you go on to ask more about implementing your setup.  Things like:

What hardware do I need to connect to the PLC
What protocol do I need to implement
What high level facilities would the Arduino need to provide for the connection to function

Etc. Lots of questions.
So:

Is it actually Ethernet or some other protocol carried by CAT5 cables, such as RS-485 / RS-422
Given the actual protocol, what interface do you need to get?
If it is Ethernet, does it use IP or something else (IPX?)
If it is IP does it use TCP or UDP for communication? Or both?
If it is IP what controls the IP addresses? Will you need to implement a DHCP server, or hijack the IP address of the "remote" end of the bridge?
Once you understand the protocols, is timing critical in your system? Does PLC A expect a response from PLC B within a finite defined time frame?
Given how unreliable a wireless connection is, how will you handle dropped or corrupted packets?
Does your chosen connection technology have enough bandwidth to transmit the data fast enough to prevent a backlog of data and lost information?

As you can see there is a huge amount of things to consider when designing this kind of thing.
If you have a list of 20 steps to go through to implement this, you are trying to start at maybe step 15 or 16. You need to rewind right back to step 1 and look at the absolute basics of what it is you are trying to do and what it is you are trying to do it to.

Thank you for your quick answer, the purpose of this system is acting as a relay, because these PLC's are in fact SENECA Z-GPRS3 GSM Loggers, but one of them is placed in an very bad GSM signal area, so the normal GSM operation is out of the question. The PLC have Ethernet RJ45 interface, protocol is TCP - application level - Web server on port 80 and IP's are fixed like 192.168.1.100 for PLC -A and 192.168.1.101 for PLC -B. Timing is not critical, given the fact that their modems are 2G-GPRS transmission speed cannot exceed 20-50kbps, and regarding the packets ... loss-retransmit.

In that case, your best bet is to have one Arduino pretend to be the remote PLC at each end of the link and capture raw bytes from whatever TCP socket the local PLC is sending to.


text:
ESP8266 SDCard initialization bug
I have an ESP8266 wich is connected to an SDCard module, an SHT21 sensor and an BMP280. The idea is that I want to log data from the sensors to the SD Card, but if I initialize the SD Card with SD.begin(chipSelect), all the data from sensors become NaN or random values. If I initialize it, it is logging only NaN on the sd card, so the card is working, and if I dont initialize it, I get good and normal values into the serial monitor.
The Card Module is connected to D5,D6,D7,D8, and the two sensors are connected to D1 and D2, and all powered from 3v.
Any idea?
This is the code:
#include <Wire.h>
#include <SPI.h>
#include <Sodaq_SHT2x.h>
#include <Adafruit_BMP280.h>
Adafruit_BMP280 bmp;
#include <SD.h>
File myFile;
float pressure;
float temperature;
float altimeter;
float humidity;
float dewPoint;
float temperature2;
float humidity2;
float dewPoint2;
int chipSelect = 5;
float QNH = 1015;
const int BMP_address = 0x76;

int ledB = D4;
int ledG = D3;
int ledR = D0;

void setup()
{

  Serial.println("initialization done.");
  Wire.begin();
  Serial.begin(9600);
  bmp.begin(BMP_address);
  Serial.println("PTHBox Logger");
    //Checking if SDCard is alive
    if (SD.begin(5)){
    Serial.println("SD card is alive");
  }else{
    Serial.println("SD card is ded");
    while(1); //halt program
  }

//Checking the logfiles from the SDCard and deleting them
  if (SD.exists("/csv.txt"))
  {
    Serial.println("Removing csv.txt");
    SD.remove("/csv.txt");
    Serial.println("csv.txt is fresh and ready to log");
  }

//  Writing headers to csv.txt
   myFile = SD.open("/csv.txt", FILE_WRITE);
   if (myFile) // it opened OK
    {
    Serial.println("Writing headers to csv.txt");
    myFile.println("Altitude,Pressure,Temperature,Humidity,DewPoint");
    myFile.close();
    Serial.println("Headers written");
    }else {
    Serial.println("Error opening csv.txt");
  }
//  Setting pinModes for the LED
  pinMode(D0, OUTPUT);
  pinMode(D3, OUTPUT);
  pinMode(D4, OUTPUT);
  //Set PWM frequency 500, default is 1000
  //Set range 0~100, default is 0~1023
  analogWriteFreq(500);
  analogWriteRange(100);

}

void loop()
{
  // Testing the led
  analogWrite(ledR, 100);
  analogWrite(ledG, 0);
  analogWrite(ledB, 60);

  Serial.print("Humidity(%RH): ");
  Serial.print(SHT2x.GetHumidity());
  Serial.print("     Temperature(C): ");
  Serial.print(SHT2x.GetTemperature());
  Serial.print("     Dewpoint(C): ");
  Serial.print(SHT2x.GetDewPoint());
  pressure = bmp.readPressure()/100;  //and conv Pa to hPa
  Serial.print("     BMP PRESSURE");
  Serial.print(pressure);
  Serial.print("     BMP ALT");
  Serial.println(bmp.readAltitude (QNH));
  Serial.print("     BMP TEMP");
  Serial.print(bmp.readTemperature());

//  Assigning values to variables

 pressure = bmp.readPressure()/100;  //and conv Pa to hPa
 temperature = (bmp.readTemperature()); //temperature from bmp
 altimeter = bmp.readAltitude (QNH); //QNH is local sea lev pressure
 humidity = (SHT2x.GetHumidity());
 dewPoint = (SHT2x.GetDewPoint());
 temperature2 = (SHT2x.GetTemperature());

//  Writing the values to SDCARD
myFile = SD.open("/csv.txt", FILE_WRITE);
    // if the file opened okay, write to it:
    if (myFile)
    {
      Serial.println("Writing to csv.txt");
      myFile.print(altimeter);
      myFile.print(pressure);
      myFile.print(temperature);
      myFile.print(humidity);
      myFile.println(dewPoint);
      myFile.close();
    }
    else
    {
      Serial.println("error opening csv.txt");
    }
  delay(1000);
}

is it a Wenos D1 mini or a NodeMcu? don't mix numbers and D labels for pins in one sketch.  https://arduino.stackexchange.com/questions/75704/what-are-the-best-gpio-pins-to-use-for-my-project/75706#75706

It is a NodeMcu

io 5 is D1. it is a good choice for the CS pin, but then you have to wire the SD card's CS pin there, not elsewhere. but D1 and D2 are default pins for I2C (Wire) so I guess you have a sensor wired to D1/D2.

You're calling
if (SD.begin(5)){

GPIO5 is not necessarily D5. Use the D5 constant; it will evaluate to whatever GPIO number D5 actually is. So,
if (SD.begin(D5)){

Although you don't appear to be using the variable, you also have:
int chipSelect = 5;

which should be
int chipSelect = D5;

The difference between GPIO numbers and pin labels leads to problems for a lot of people. GPIOx is specific to the ESP8266 - it corresponds to a pin number and function on the actual chip; Dx is specific to the particular breakout board and is not always the same GPIO number (or the same between breakout boards).

It is doing the exact same thing. Like I said, the file is getting written onto the SD Card, but if the sd card is getting initialized, the sensors stop working.

Are you sure you selected the correct board?

GPIO5 is SCL on the ESP8266, so using GPIO5 for chip select would definitely break I2C communications. Try adding Serial.print("D5 is "); Serial.println(D5); to find out what D5 is defined as.

if it is a Wenos D1 or a NodeMcu it doesn't make sense to use D5 as CS, because D5 is SPI CLK pin.

I did that, it says dhat D5 is 14. (BTW It is a NodeMcu)

Nevermind, I figured it out. I used D8 instead of 5, and now it is working. I got tricked because the SD Card was working and D5 too, and I thought that wasn't the problem. Thank you, guys! Cheers!

Glad you got it working!

@Mereics, io 15 (D8) has to be LOW at boot. the use as CS pins can interfere


text:
Why is the Adafruit splashscreen logo not displayed properly?
I'm working with a 128x64 Oled display. I have just installed the Adafruit library and I'm running some sample codes. I have not modified the sample code in anyway yet just testing if the oled display is working but I've noticed that the splashscreen logo only shows the top half of the image.
How can I fix this?

What sample code are you running? That looks like the sample code supposes a different display height

I'm running the ssd1306_128x64_i2c

Can you provide a link to it?

https://codebender.cc/example/Adafruit_SSD1306/ssd1306_128x64_i2c#ssd1306_128x64_i2c.ino

I added #define SSD1306_LCDHEIGHT 64 before line #53 to remove the compilation error

It looks like you're displaying only 50% of the lines with a blank between each one...

I'm unable to test this now, but here goes:
Turns out I did have the ability to test it (found an extra display module) and this does indeed explain the problem. The only other change I needed to make to your code in order to replicate the problem was change the display's I2C address to 0x3C. Adafruit GFX Library v1.10.13 and Adafruit SSD1306 version v2.5.1.

From comments on the question:

I added #define SSD1306_LCDHEIGHT 64 before line #53 to remove the
compilation error

Yeah, you can't do that. Under the old method of defining the screen dimensions, you are intended to modify the header itself:
// ONE of the following three lines must be #defined:
//#define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen
#define SSD1306_128_32 ///< DEPRECATED: old way to specify 128x32 screen
//#define SSD1306_96_16  ///< DEPRECATED: old way to specify 96x16 screen
// This establishes the screen dimensions in old Adafruit_SSD1306 sketches
// (NEW CODE SHOULD IGNORE THIS, USE THE CONSTRUCTORS THAT ACCEPT WIDTH
// AND HEIGHT ARGUMENTS).

You can see by default it is using a screen with dimensions 128x32. Later in the header this is used to set SSD1306_LCDHEIGHT to 32 in the header.
#if defined SSD1306_128_32
#define SSD1306_LCDWIDTH 128 ///< DEPRECATED: width w/SSD1306_128_32 defined
#define SSD1306_LCDHEIGHT 32 ///< DEPRECATED: height w/SSD1306_128_32 defined
#endif

What you have done in your code is redefine SSD1306_LCDHEIGHT to 64 from the point where you issued the #define downward, which only affects the code compiled in your sketch.
Meanwhile, over in Adafruit_SSD1306.cpp, SSD1306_LCDHEIGHT is still 32, because this file is compiled independently of your .ino and is unaware of your own re#define.  In other words, part of the code you've put into your Arduino thinks it has 32 lines and part of it thinks it has 64 lines.

So, the solution would be get rid of the #define that you inserted into the sketch and to modify header to read:
#define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen
//#define SSD1306_128_32 ///< DEPRECATED: old way to specify 128x32 screen
//#define SSD1306_96_16  ///< DEPRECATED: old way to specify 96x16 screen

Or to use the new method of supplying the dimensions by way of the constructor as is done in newer examples:
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
/// ...
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

The Adafruit SSD1306 version v2.5.1's ssd1306_128x64_i2c.ino example that uses this newer method of passing screen dimensions into the Adafruit_SSD1306 constructor and compiled and ran without modification in testing here.

I have edited the header file and it fixes the problem, thank you. One question though, do I need to use 0x3D as the address for the oled? I used 0x3C because it does not turn on when I use 0x3D. I just want to know why that happened

In short, if it's working you have chosen the correct address. The SSD1306 controller chip has a pile of different pins and transfer modes. In I2C mode one of those pins can be used to configure to chip to respond to either 0x3C or 0x3D, such that two of those displays could coexist on the same I2C bus with no other changes. For your display, the choice of I2C interface and 0x3C address has been made for you by the PCB design.  I believe the 0x3C/0x3D hard configuration tends to follow the x32/x64 display type, but that nothing guarantees that.


text:
Weird Arduino math result
I have a simple code, part of which contains the calculation 800/1000, which seems to return a value of zero for some reason (even though I store it in a float variable). When I replace the calculation with the expected result (0.8) the code works as expected, I just wonder why the calculation doesn't produce the same result.

The expression is first evaluated as an int, hence 0, before converting it to float. If you want the expression computed as a float, then at least one argument must be a flost, e.g. 800.0 / 1000.

Both 800.0/1000 or ((float)800)/1000 will work.
The former works only with hardcoded constants, while the latter works also with variables:
int a = 800;
int b = 1000;
float c = ((float)a) / b;

A whole numbers like 800 or 1000 are integers, while a number like 800.4 is considered fractional and is treated as a float. Two integers divided gives an whole integer result, in your case 0. If one number in the division is an integer, and one is a float, the result is a float.

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


text:
Delaying pushbutton input to microcontroller while it's busy processing I/O
I am trying to create my own home automation using Arduino. I am using shift register for reading input(via push buttons) and writing output to led's. I am using SPI interface to communicate with shift registers.
Apart from SPI Arduino also deals with I2C devices. When push button is clicked Arduino ISR is invoked via pin 2, which then checks exact button that was pushed and takes action accordingly. The functionality currently works well with one small problem.
Sometimes when push button is clicked Arduino ignores the button press. After debugging for some time I observed that it happens when Arduino is busy with I2C communication with other devices.
I would like to know if it is possible to temporarily delay the push button input while Arduino busy with I2C communication? or is it possible to prioratize interrupt handling over I2C communication?
Below is the simplified code
#include <SPI.h>
#include <Wire.h>
byte Input=1;
volatile byte Check=1;
volatile byte Output=1;

int j;
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 13;
////Pin connected to DS of 74HC595
int dataPin = 11;

int interruptPin=2;

int espPin=7;

char arduinoStatus[100]="\0";

 void pin_read(){

    for(j=0; j<50; j++)
    delayMicroseconds(1000);

    Check=1;
    for(j=0; j<8; j++){
      digitalWrite(latchPin, LOW);
      delayMicroseconds(500);

     SPI.transfer(Check);
     SPI.transfer(Output);

     digitalWrite(latchPin, HIGH);

     delayMicroseconds(500);
    if(digitalRead(interruptPin)==HIGH){
      //Serial.println(Check);

      if(bitRead(Output, j)==1)
      bitWrite(Output, j, 0);
      else
      bitWrite(Output, j, 1);
    }//dig check

    Check = Check<<1;

    }

    digitalWrite(latchPin, LOW);
    delayMicroseconds(500);
    SPI.transfer(255); //to push buttons
    SPI.transfer(Output); //to LEDs

    digitalWrite(latchPin, HIGH);
    delayMicroseconds(500);

}//pin_read

void setup() {
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(espPin, OUTPUT);
  pinMode(interruptPin, INPUT);//Input from buttons

  delay(1000);
  // the LEDs don't change while you're sending in bits:
    digitalWrite(latchPin, LOW);
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPI.begin();
  SPI.transfer(255);
  SPI.transfer(255);
   //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);

    Serial.begin(115200);
    attachInterrupt(0, pin_read, RISING);

    Wire.begin(8);                // join i2c bus with address #8
  Wire.onRequest(requestEvent); // register event
  Wire.onReceive(receiveEvent);

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

void loop() {
  Serial.println("Interrupting...");
 digitalWrite(espPin, HIGH);

 while(digitalRead(interruptPin)==HIGH){}
  delayMicroseconds(500);
 digitalWrite(espPin, LOW);
 delayMicroseconds(500);
 Serial.println("Done...");
Serial.print("Output:");
Serial.println(Output);
delay(3000);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
  int i=0;
  Serial.println("received::");
  while (Wire.available()) { // loop through all
    char c = Wire.read(); // receive byte as a character
    arduinoStatus[i++]=c;

    Serial.print(c);         // print the character

  }
  arduinoStatus[i]='\0';
  Serial.println("###");
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
  Serial.println("Sending...");
  Wire.write("hello"); // respond with message of 6 bytes
  Wire.write(Output);
  Serial.println("Sent");
  // as expected by master
}

Sounds like you need to re-organize your software, in particular you probably need to use non-blocking I2C routines, at least if you have any peripherals that do clock-stretching.  Most likely you could get away with only servicing the user inputs between i2c words, but if clock-stretching is possible, they could take longer.

Are you using delay() functions in your code?

A question like this really needs to include your code.

@ChrisStratton,@Transistor: have tried to search for non blocking I2C library for Arduino, but it looks like many people are looking for the same and not finding., I have posted the simplified code I am using.

attachInterrupt(0, pin_read, RISING);, pin_read function is right up the code.

Without looking any further than the first delaymicroseconds() command I would say that that's where the trouble lies. The delay() functions are very handy for getting the beginner's first LED to blink and are a big problem after that. The problem is that the CPU is completely tied up during the delay and can't do anything else other than interrupts and you only have a limited supply of those. Your button press is missed.
You need to develop your own timers in the code and keep the main loop running constantly checking on each pass to see if the delay is complete.

What about polling the buttons periodically instead of using an interrupt?  If you check them every 10 ms or so, you should still be able to detect a button press reliably.  Connecting buttons to interrupt inputs is not necessarily the best idea due to contact bounce - this can cause a number of back-to-back interrupts.  My guess is that interrupts are being disabled during some part of your code and when the interrupt pin level changes during that period, it gets ignored.

Close. I would use the interrupt to set a flag. Then,  in the main loop, you process the button press whenever the loop comes back around.

That won't solve the problem if the interrupt is getting missed while interrupts are disabled.

True. I didn't notice anything disabling the interrupts though.


text:
Attiny88 as SPI slave
I have programmed Attiny88 with Arduino IDE 1.6.5 using https://github.com/SpenceKonde/ATTinyCore . I chose Attiny88 because it's the cheapest Attiny (as low as $0.5) and at the same time has 28 pins with dedicated SPI.  I wrote a code for arduino to work as SPI master, and a code for Attiny88 as SPI slave but I get only 0 as answer from Attiny.
SPI master code for ARduino UNO
#include <SPI.h>

// set up the speed, data order and data mode
SPISettings settingsA(2000000, MSBFIRST, SPI_MODE0);
const int slaveAPin = 10;

void setup() {
  // set the Slave Select Pins as outputs:
  Serial.begin(9600);
  Serial.println("SPI ON");
  pinMode (slaveAPin, OUTPUT);
  SPI.begin();
}

uint8_t stat, val1, result;

void loop() {
   // read two bytes from device A
   SPI.beginTransaction(settingsA);
   digitalWrite (slaveAPin, LOW);
   // reading only, so data sent does not matter
  stat = SPI.transfer(0);
  val1 = SPI.transfer(0);
  digitalWrite (slaveAPin, HIGH);
  SPI.endTransaction();
  Serial.println("data");
  Serial.println(stat);
  Serial.println(val1);
  Serial.println("end");
  SPI.endTransaction();
  delay(300);
}

SPI slave code for Attiny88:
#include <SPI.h>

// set up the speed, data order and data mode
SPISettings settingsA(2000000, MSBFIRST, SPI_MODE0);
const int slavePin = 14;
const int ledPin = 9;

uint8_t stat, val1, val2, result;

void setup() {
  // set the Slave Select Pins as outputs:
  pinMode (slavePin, INPUT);
  pinMode (ledPin, OUTPUT);
  // initialize SPI:
  digitalWrite(ledPin, HIGH);
  delay(1000);
  SPI.begin();
  stat =128;
  val1= 1;
}

void loop() {

  if (slavePin==LOW) {
    SPI.beginTransaction(settingsA);
    SPI.transfer(stat);
    SPI.transfer(val1);
    result = SPI.transfer(0);
    digitalWrite(ledPin, result);
    SPI.endTransaction();
  }

}

You do not appear to be configuring the slave as an SPI slave. Merely changing the pin modes won't achieve this. Example code at SPI - Serial Peripheral Interface - for Arduino - however that does not specifically mention the Attiny88.
In my example in reply #1 on that page I have this code:
  // turn on SPI in slave mode
  SPCR |= bit (SPE);

  // have to send on master in, *slave out*
  pinMode(MISO, OUTPUT);

This sets SPCR bit MSTR to zero (by not mentioning it). If you call SPI.begin() it will be activated in master mode.
It looks like the Attiny88 has the same register.
So in my opinion your code merely has two SPI masters.
Also, you seem to be doing 3 transfers in the master, but only 2 transfers in the slave.


text:
Is it possible to use FrSky D8R-II Plus 8ch 2.4Ghz ACCST Receiver with an arduino Uno?
I'm in the process of buying a receiver and transmitter for my quad copter project. Would it be possible to use this receiver or a similar one to control the quad. I'm trying to read the signals using Pulse in. I'm inexperienced in RC and I only found one tutorial on how to do this.
I know that the receiver will have to be wired up to the analog pins on the arduino however, the receiver has an operating voltage of 3.5V-10V and an operating current of 100mA which exceeds the 40mA of the arduino board. I have seen videos of people using silar 2.4Ghz receivers on arduino Nanos without problems. Has anyone on this board done something similar and if so, can thou guide me?

I've used plenty of receivers like this with arduino.
The operating current is not really an issue; It is drawing power off of the 5v line, not the digital pins, which is capable of 100mA. In any case they usually have an extra "bat" line that you could plug in to a BEC from one of your speed controllers, and then just connect signal and ground lines to the arduino.
pulseIn works, but not ideally (especially for quadcopters). reading with pulseIn tends to have quite a bit of noise, and runs slow. Those receivers pulse around 50-60Hz, so reading those signals with pulseIn (which has to wait for the signal to finish) will take too long. I say "too long" because in all the open source quad copter programs I've looked at the sensor-read/stabilize update loop needs to run at 100 Hz or more.
What you need to use is the interrupt functionality of the AVR. That way you can detect the time between changes in state of the input pulse without causing the rest of the program to stop. This can get somewhat complicated so I'm not going to write a tutorial here. I recommend you research it yourself and ask new, specific questions here if you have any.
It doesn't magically fix everything for you though; the Uno only has 2 external interrupts. I think most arduino based quads use arduino megas or Leonardos, which have more. I know the APM 2 board has a separate chip converting those 8 single channel PPM signals into a single 8 channel PPM signal that goes into the main controller, despite the fact that it is a mega.
You can look into Aeroquad and Multiwii for inspiration. ArduPilot is open source as well but their code is messier, which makes reading it much more difficult. I don't think it is impossible to use an Uno, but it will be difficult.

Thank you. I have a mega 2560 too. I guess I'll be using that one.


text:
5V FTDI cable for Arduimu V3
I just recently bought an Arduimu v3. Rather annoyingly they did not supply an FTDI cable. I'm going for an FTDI cable where the I/O pins are configured to operate at 5v. I assume this is the right but I don't want to fry this board. Is this cable OK?

The board is a 5v one, so a 5v FTDI would be fine.

A 5V cable would be fine, or for about the same price, I would recommend an Adafruit FTDI Friend which is configurable between 5V and 3.3V.

Yes, as long as the board is 5V


text:
Can stackable Arduino headers be automatically soldered?
I want to design an Arduino shield with stackable headers, so it will allow other shields to be mounted on top of it.

I was wondering if these could be soldered automatically. Neither wave nor reflow soldering seems to be an option. Wave soldering would leave solder on the pins so they won't fit in sockets, and for reflow (pin-in-paste) the long pins will completely pull the paste from the holes.
Is hand-soldering the only way (making the board more expensive), or is there still another way? Would it be a good idea to supply the shield with the headers not mounted to save cost?
Or shouldn't I assume the average Arduino user has a soldering iron?

Depends on where you have them manufactured. Chineese labor isn't as expensive. A lot of boards have a a few parts that go in manually. There are, by the way, robotic soldering machines, though you'd probably still have to manually insert the headers, and have some way to fixture the headers while the board is upside down. I've seen a few shield for sale, that don't have the headers inserted. Note that this also makes shipping easier. No real clear answer.

@Gerben: good point about shipping. Thanks for your comment.

I would suggest using SMD headers on one side and through hole on the other side. One side with this: http://www.tracepartsonline.net/(S(30y0dp21y1rd0u3erv1mrrbw))/partdetails.aspx?Class=ASSMANN&ClsID=/F_ASSMANN/ASSMANN.010/ASSMANN.010.170/&PartID=10-18062010-079808
and one side with this: http://www.tracepartsonline.net/(S(30y0dp21y1rd0u3erv1mrrbw))/PartDetails.aspx?Class=ASSMANN&clsid=/F_ASSMANN/ASSMANN.010/ASSMANN.010.170/&ManID=ASSMANN&PartFamilyID=10-23062010-067691&PartID=10-23062010-067691&SrchRsltId=1&SrchRsltType=0
You will shift upper side a few mm from bottom side, and use glue to have upper side set in place and then reflow for soldering on both sides.

I'm not a production engineer, but would SMD both sides work and not need the offset?

I would work but may need special equipment as these are tall SMD that may be difficult to maintain while you manipulate the board. In this case you will probably want to work with two solder pastes that have different fusion temperatures.

The proper way to work with SMT on both sides is to glue the parts if they're too heavy to stay in the solder paste capilarilly.

An SMD header this tall could be extremely prone to breaking off and quite possibly peeling tracks with it.  The idea is workable for unique lower profile board- board stacking headers, but probably not for the Arduino's high stacking height tradition.

You might look at getting a solder stencil.  It is still hand soldering, but significantly faster than doing it completely by hand.  Another option would be a pick and place machine; there would be a significant upfront cost but it would be more automatic.

Like I said in my question neither wave nor reflow soldering seems to be an option. For both automatic pick and place exist. And how does a stencil help here? It's used for reflow anyway.


text:
Arduino around the Xmega?
I came across a dev board around the Atmel Xmega controller. This an AVR like used on Arduino, but with a lot of extras.

I was surprised to see that the board is hardly more expensive than an Arduino, despite:

384kB of Flash (versus 32kB for Arduino)
DMA
Xmega can run at 32 MHz (16 MHz for Arduino)
on-board OLED display
on-board light and temperature sensors
on-board microSD socket

For all these on-board features you'd need a shield or breakout board for Arduino. I seems to me that for a lower price than Arduino you could build a much more powerful system, which is Arduino-compatible.
How hard would it be to port Arduino to the Xmega?
see also http://www.element14.com/community/docs/DOC-71436

Eleventy-seven.

@Ignacio: thanks for that link. Not sure what eleventy-seven means, though. Is it slang for something?

It is a fictional arbitrary number.

There's an attempt to get the Atmel XMEGA boards working in Arduino IDE.
https://github.com/akafugu/Xmegaduino
It's not fully featured yet but appears to have to features to allow you to start hacking with this board.


text:
ESP32-S3 - HttpClient only returns 200 status code no JSON payload data
I have a ESP-S3 board and am trying to get JSON data from our server. I am using the following code (see below) as a basis for mine.
This code works. If I change
http://jsonplaceholder.typicode.com/comments?id=10

to
http://mywebsite.com
I do get the html for our server's main page.
If I then change
http://mywebsite.com

to
http://mywebsite.com/profiles

I get status code 200 but no JSON.
I type http://mywebsite.com/profiles in a browser it returns the JSON or if I use postman and do a GET on http://mywebsite.com/profiles it returns JSON.
It sounds like this issue posted a couple of years ago:
esp32 http client response only 200 didn't receive the data after that
Any insight as to what I am doing wrong would be greatly appreciated.
#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "yourNetworkName";
const char* password =  "yourPassword";

void setup() {

  Serial.begin(115200);
  delay(4000);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  Serial.println("Connected to the WiFi network");

}

void loop() {

  if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status

    HTTPClient http;

    http.begin("http://jsonplaceholder.typicode.com/comments?id=10"); //Specify the URL
    int httpCode = http.GET();                                        //Make the request

    if (httpCode > 0) { //Check for the returning code

        String payload = http.getString();
        Serial.println(httpCode);
        Serial.println(payload);
      }

    else {
      Serial.println("Error on HTTP request");
    }

    http.end(); //Free the resources
  }

  delay(10000);

}

how big is the JSON response? There's not a huge amount of room for large responses. Try a smaller response and see if you still get nothing.

I can't reproduce what you experienced, your code works perfectly and I got the json back. The only difference is that I'm using an ESP32 instead of ESP32S3. Maybe you try to swap the lines between String payload = http.getString(); and Serial.println(httpCode);, this might provided sufficient time for payload to be received completely.

dandavis - that is definitely something to check. thank you for the suggestion. hcheung - the above code works for me too. It fails when I use my server.

dandavis - that was the issue. a smaller response size worked.