text:
Control DC motor in both directions with two relays
I am using an Arduino and two relays to control 12V DC motor.
I need to rotate the motor in both directions.
For the first trials it worked fine. Finally one next switching fried my Arduino.
I think there is something wrong in the schematic.
I believe that Arduino was killed by reverse voltage spike produced by motor.
I already know that I need a diode across the motor. However, I have two directions here.
So, what is the proper schematic for my task?

Isn't this relay used to control AC devices? http://www.techydiy.org/keyes-sr1y-relay-module/

@Adamelli your link does not help here. That guy does not power an Arduino and a motor with the same power source.

It wasn't to help you. You didn't specify what relay.

@Adamelli, yes, it is a relay module to control AC devices.

Some potential issues to consider: https://electronics.stackexchange.com/a/130253/266181

@Adamelli, I don't power motor from the arduino! look at my schematic. I power motor from an external power supply.

I didn't say you powered the motors from the Arduino. Start reading at, "Yes, you can use a relay as that switch"...

Let us continue this discussion in chat.

please don't crosspost
...  https://electronics.stackexchange.com/questions/552144/control-12v-dc-motor-with-arduino-and-two-relays-in-both-directions

In short, you're probably overloading your regulator.
It's difficult to say for sure, but I have a suspicion and can give a framework for thinking about it with some very crude numbers.
If you're powering the Nano from a 12 V source, you are dropping 7 V across the regulator.  If you do the math on this 7 V drop, it means every 14 mA drawn through the regulator induces nearly a tenth Watt of heat in the regulator.  7 V * 0.014 A = 0.098 W.  I'm guessing you have a budget of perhaps 300mW based on the way the Nano's regulator is set up.
The ATmega328P says it uses 5.2 mA (typical) or 9 mA (maximum) at 5 V and active at 8 MHz.  But really it will use more at the 16 MHz frequency.  For sake of argument, I'm just going to say it's using 14 mA, because it makes the math easy and because power usage scales somewhat linearly with frequency.
Just the power led will use about 3 mA, if it's an official Nano, but for simplicity sake, I'll call it 7 mA, being half of 14 mA and we'll ignore the fact that there are other loads on the board like the serial transceiver.
Your relay coils will use at least 30 mA, but likely more, perhaps a lot more.  But for ease of calculation lets go optimistic and say they only use 28 mA (cause 2 * 14 mA).
So we have the ATMega328P inducing 100 mW in the regulator, the power led and some extras adding 50 mW. at at least one relay coil energized for another 200 mW.  So right there you're already at 350 mW.  If you screwed up and managed to energize both relays, 550 mW.  Hopefully the regulator will enter thermal shutdown when this happens, in which case all you need to do is let it cool down and, you know, stop doing that.  But it may also just die,which is more likely if you have a clone that happens to use a crappier regulator.
But, I think these numbers are conservative.  For example, a datasheet for a Songle SRD-05VDC-SL-C relay that a lot of these modules use seems to say it will use closer 70 mA each, rather than 28 mA.  This means operating just one of these coils by itself, nevermind the rest of the Arduino, will cause nearly half a Watt to be dissipated in the regulator if you're powering from 12 V.  If you managed to turn on both coils well... nothing good.
If this is not the problem you're having, it is a problem.  You can save yourself a fair bit of trouble by powering your Nano from USB with a powered hub or reasonable quality USB-output wall adapter.  Doing so bypasses your regulator altogether.
If you're going to continue staging down 12 V to 5 V for the relay coils, then you may need an external regulator to operate the relay modules, just to unload the the Nano's regulator.  Exactly how you'd go about that depends somewhat on the construction of the relay module.  Some of them make it a bit easier on you and are design to accept voltage from a second source for the coils.


text:
BLE scanner and WiFi web server on the ESP32 board
I am trying to put BLE and WiFi web server on the same ESP32 board, using Arduino IDE.
However, BLE library is too heavy. It spends about 73% of program size and there no room for WiFi.
Program too big. The size is 1328706 bytes (of a 1310720 byte maximum

These are libraries I am trying to use in the same solution:
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include <EEPROM.h>
#include <WiFi.h>

Is there anything I can try to spare program size?
Is there any alternative?

What partition scheme do you use? If you don't use OTA and keep SPIFFS at minimal size, maybe thats enough

@chrisl, I don't set any partitions. I simply installed ESP32 onto Arduino IDE and merged two examples - BLE Scan and WiFi Web Server. Honestly speaking, I know nothing about partitions...

Every board has different tables for dividing the flash memory between the program itself, the SPIFFS for static/persistent files and OTA (over the Air Updates). Please describe, which board ypu have chosen in the IDE and what stettings are selected in the menu for it

@chrisl, Thanks a lot! I chose another partition and now it works.

source: Stack Exchange

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

sort: votes


text:
Current mouse pointer position with Digispark attiny85
I am trying DigiMouse library for attiny85 Digispark board.
It allows to emulate the mouse quite well.
However, I also need to know the current cursor position. Is there a way to get it?

emulate an "absolute position" mouse ... regular mouse only sends "relative move" values

There is no way for a mouse of any kind (especially not one as minimal as DigiMouse.h) to know the current cursor position - USB just doesn't provide that kind of facility.
Instead you need to implement an "absolute" mouse (aka a "tablet").  However DigiMouse doesn't implement such a facility. So you would have to implement your own tablet driver.
A normal mouse sends a "delta" for the position. That is, a difference in position from whatever the current position is.  An absolute mouse, or tablet, sends the position on the screen as a proportion of some maximum set of dimensions.  Ideally that would be the same dimensions as your screen, but doesn't have to be.
The main differences between DigiMouse and whatever you would implement for a DigiTablet would be the "HID Report Descriptor". This defines what the data that is sent means and how the computer should interpret it.

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


text:
formatting strings in Arduino for output
I wander what is the best option for formatting strings in Arduino for output.
I mean what's a preferable way in the point of view of performance, memory usage  – things like that.
I see, people usually use direct Serial.print/println, like this:
  int x = 5;
  // 1st option
  Serial.print("x = ");
  Serial.println(x);

Or like this:
  // 2nd option
  Serial.println("x = " + String(x));

But what is wrong with, I believe, more traditional way of doing this:
  // 3rd optoin
  char strBuf[50];
  sprintf(strBuf, "x = %d", x);
  Serial.println(strBuf);

  // better one?

If you need the result in a single string then your 3rd option is the preferred way.
If you don't, then the first option of printing each part separately is the most efficient in terms of memory.
The second version, String concatenation, is the worst option in all respects and should be avoided at all costs.
I often use sprintf to a buffer if I need a specific format (for instance leading zeroes on a number).
If you want to avoid the extra code bloat of sprintf you can use various combinations of strcpy, strcat and itoa etc to build up a string into a memory buffer (if you really need to put it in a buffer).
Note that on an 8-bit Arduino sprintf has no float support - so you would still need to use dtostrf to format a float into a char buffer first, or print it directly.

I agree with Majenko's answer.
I created a simple CStringBuilder class to combine the first and third approach mentioned in your question. It enables to build the c-string with printf and with Print functions, which can print float or IPAddress. It is available in StreamLib in library manager.
#include <CStringBuilder.h>
#include <IPAddress.h>

const char* s = "Lorem ipsum";
char c = 'X';
int i = 42;
float f = PI;
IPAddress ipAddress(192, 168, 0, 1);

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

  char buff[150];
  CStringBuilder sb(buff, sizeof(buff));

  sb.print(F("Some text: "));
  sb.println(s);
  sb.print(F("Some char: "));
  sb.println(c);
  sb.print(F("HEX of char: "));
  sb.println(c, HEX);
  sb.print(F("Some integer: "));
  sb.println(i);
  sb.print(F("Some float: "));
  sb.println(f, 3);
  sb.print(F("IP address: "));
  sb.println(ipAddress);

  int l = sb.length();
  sb.print("this text doesn't fit in the remaining space in the buffer");
  if (sb.getWriteError()) {
    sb.setLength(l);
  }
  sb.println("test test");

  Serial.print("size to print: ");
  Serial.println(sb.length());
  Serial.println();
  Serial.println(buff);

  sb.reset();
  sb.printf(F("Formatted: %s;%c;%05d\r\n"), s, c, i);
  Serial.println(buff);
}

void loop()
{

}

Other classes in the library are BufferedPrint and ChunkedPrint.  Both support sprintf.

The wrong thig with option 3 is the buffer length, you should use snprintf instead.
The other problem is that first you build the string, then you print the output, the program traverses the string twice. Option 2 creates object from string, then applies + operator to create a new string, then prints it - it is comfortable with short strings, but least efficient (depends on the compiler optimalizations).
Option 1 is most effective, since it directly prints arguments to the output char by char (see Arduino Print class) and traverses the arguments only once.
You can use stdarg.h to create one-liner with Serial.prints:
#include <stdarg.h>

void Serialprintln(const char* input...) {
  va_list args;
  va_start(args, input);
  for(const char* i=input; *i!=0; ++i) {
    if(*i!='%') { Serial.print(*i); continue; }
    switch(*(++i)) {
      case '%': Serial.print('%'); break;
      case 's': Serial.print(va_arg(args, char*)); break;
      case 'd': Serial.print(va_arg(args, int), DEC); break;
      case 'b': Serial.print(va_arg(args, int), BIN); break;
      case 'o': Serial.print(va_arg(args, int), OCT); break;
      case 'x': Serial.print(va_arg(args, int), HEX); break;
      case 'f': Serial.print(va_arg(args, double), 2); break;
    }
  }
  Serial.println();
  va_end(args);
}

Then you can use it like sprintf (but efficiently):
void setup() {
  int n = 42;
  float f = 42.42;
  const char* s = "answer";
  Serial.begin(9600);
  // The answer is 42 (101010 BIN, 2A HEX), in float 42.42
  Serialprintln("The %s is %d (%b BIN, %x HEX), in float %f", s, n, n, n, f);
}

void loop() {
}

The printf() family of functions is far preferable to me as the programmer, but in a resource-constrained environment such as the smaller AVR (and other) processors, the extra code space may not be justified or available, or the performance hit of interpreting the format string may be limiting. And sprintf(buf, ...); Serial.print(buf); also takes a stack hit for the temporary buffer (compared to just printf(...); ) It's a trade-off between code size and speed vs. you having more flexibility to write the code to the create the output you want.

printf will use roughly the same buffer space as sprintf; it has to buffer the print somewhere.

Good point about the data space (IF we know that printf() family use a buffer on the stack rather than a static one). My comment about code space still applies.

The third option, sprintf, is unsafe and may give buffer overruns if buffer is not sized correctly.  You can use snprintf instead.
However I would recommend my SafeString library and tutorial
for general string processing and output.


text:
Is it possible to split project into several folders?
It is possible to split the project into server files. However, it looks like they all must be in the same folder with the.ino file.
Is it possible to split project into several folders? I’ve got several git repositories which I want to use in the same project and I can’t use them as libraries. Each repository must have its own folder…

What operating system are you using?

@Majenko Win10. Does it matter for this case? All things are quite similar everywhere nowadays.

Yes you can. It works and many projects use subfolders. And NO, you will not see them in your Arduino IDE. As st2000 said, Arduino IDE is simple and people likes it because it is simple. If you want the control of your processor and code, use PlatformIO.

@Adriano how? I can refer the headers in subfolders but Arduino IDE does not compile the definitions from subfolders. And, guys, how you even can call it simple? Looks like things are simple only for simple deeds.

If you have a header inside a subfolder, you can just call #include "subfolder/header.h" and it works. You can see this big project for example: https://github.com/xoseperez/espurna/tree/dev/code/espurna - but you will not see the files inside the Arduino IDE. Simple means, that if you don't have programming skills, you are able to open and edit something without loose time to find out what an IDE is and how it works. In future, with the PRO version, it will be easier to develop something... I hope ;)

@Adriano As I said, I have no problem with headers. I have .cpp files inside a subfolder. How to make IDE compile them? I don't need to work with them via IDE, it's ok.

@zhekaus I wrote the answer as answer, not as comment. Hope this is ok for you. I know what you want. You want the comfort of Visual Studio in a simple text editor with integrated compiler. You can use Visual Studio + Visual Micro and you will have all the comfort you want ;) But Arduino IDE also gives you a lot of options to develop more complex projects.

I will try to give an answer as it is not easy to understand what you mean.
Probably it is also better if you know how the Arduino IDE works, before try to make complex projects.
Short answer:
Yes, it is possible
Normally, you have an ino-file, some other files and many libraries. If you want create something for your project, you can just create a folder inside the library folder.
But this is not what you want right?
You can create many folders inside your project and include any header inside your folders just with
#include "subfolder/yourfile.h"
The files will not be opened with your Arduino IDE.
You can also create your "mini library", so the compiler will compile it with your project. This library need to be in a subfolder called src. At this point it will be converted and compiled for your project.
Simple working example:
testsub.ino
#include "src/test.h"
Test *test = new Test();
void setup(){
  Serial.print(test->number());
}
void loop(){
}

Create a subfolder src and place your files:
test.h
class Test
{
public:
  Test();
  int number();
};

and
test.cpp
#include "test.h"
Test::Test() {
}
int Test::number() {
  return 95;
}

If you want another "library", you can create another subfolder called src.

You know, that's finally quite something! Thank so much!
However, how can I have extra subfolder with the same name src?

You need to place the second subfolder inside the src folder. And there, you can place another src folder. This is the only way at the moment.


text:
Initialize object with PROGMEM constants
I have a class which has a const char * property:
    class A
    {
    public:
        const PROGMEM char* text;
    };

    void setup()
    {
        // A a{"Hello World!"};
        // A a{PSTR("Hello World!")};

        A a;
        a.text = PSTR("Hello World!");

        Serial.begin(9600);
        delay(30);
        Serial.println(a.text);
    }

    void loop()
    {
    }

I’d like to spare some RAM using PROGMEM.
How to initialize a object then?
Obviously, it can’t be like this:
    A a{PSTR("Hello World!")};

This will do:
    A a;
    a.text = PSTR("Hello World!");

However, I need to pass string to the constructor.

does a.text = F("Hello World!"); do what you want?

@dandavis, it does not. you've missed that a.text is not const __FlashStringHelper* - it's const char*

It is a shame that gcc only supports the __flash qualifier in C mode,
not in C++, so we have to use PROGMEM instead. Unlike __flash, which
qualifies a variable just like const, the PROGMEM attribute only has
effect when allocating room for a variable. Once the allocation is done,
the compiler forgets about the attribute. In particular, a declaration
such as
const PROGMEM char* text;

does not allocate flash space, so it generates the warning
warning: ‘__progmem__’ attribute ignored [-Wattributes]
     const PROGMEM char* text;
                         ^

You can thus forget the attribute when declaring a pointer, as there is
no such thing as a “pointer to PROGMEM”. You just use a const char *
instead.
Now, the second issue is that, as far as Serial.println() is
concerned, the pointer above is a plain const char *, so it will
interpret it as an address in RAM, and print garbage. If you want
Serial.println() to know you are giving it an address in flash, you
should provide it with a const __FlashStringHelper* pointer.
Here is the solution I propose. Tested on an Uno-compatible board:
class A
{
public:
    A(const char* s)
        : text(reinterpret_cast<const __FlashStringHelper *>(s)) {}
    const __FlashStringHelper* text;
};

void setup()
{
    A a{PSTR("Hello World!")};
    Serial.begin(9600);
    Serial.println(a.text);
}

void loop(){}

Edit: After seeing the last version of Juraj’s answer, I must say
that I agree with him. Since we are using the Arduino API, it makes more
sense for the constructor to take a const __FlashStringHelper*, and
for the caller to use the F() macro.

your solution works fine! thank you very much!

const char* text; is a pointer to constant not a constant pointer (char * const text is a constant pointer). So you can assign a pointer to a constant char array to const char* text; even a pointer to an array in PROGMEM.
The compiler doesn't know the difference between a PROGMEM pointer and a pointer in SRAM. It is on you to work in code with a pointer to PROGMEM the right way.
so remove PROGMEM from const PROGMEM char* text;

add constructor to initialize an object.
A(const char* _text) {
  text = _text;
}

and then
A a(PSTR("Hello World!"));

EDIT:
you could use Arduino's F() macro and __FlashStringHelper type, because it is supported by Serial print and co.
class A
{
public:
  A(const __FlashStringHelper* _text) {
    text = _text;
  }
  const __FlashStringHelper* text;
};

void setup()
{
    A a(F("Hello World!"));

    Serial.begin(9600);
    delay(30);
    Serial.println(a.text);
}

void loop()
{
}

__FlashStringHelper type is trick to distinguish PROGMEM strings from char arrays in SRAM..

This is not an answer on my question. How to store strings in flash memory? Strings must be passed to the contructor.

it is unclear what is what you don't know. I enhanced the answer

Hum... Your solution won't let use Serial.println. And added user-defined  constructor does not any difference here.

@zhekaus, yes, your question combined 3 problems. Edgar got them all, but the true solution is to use F macro, not PSTR, if possible. I enhanced the answer


text:
Ultrasonic Sensor receiving Side
I'm doing my project regarding 40khz ultrasonic sensor which will be used to get accurate distance measurements. I have a separate transmitter and receiver. I want to get the time between the moment my transmitter transmitted the waves and the time my receiver received it. However, I couldn't actually make it work. Does any of you give me a code that would help me transmit and receive the 40khz waves and get the time in between so I could use it to compute for the distance?Thank you in advance. I would greatly appreciate it!

What is your exact hardware? Most commercial US sensors I know have their own measuring implemented on board.

@mystery what about the HC-SR04?

I know that one quite well. It should serve OPs wish for example code https://github.com/sparkfun/HC-SR04_UltrasonicSensor/blob/master/Firmware/HC-SR04_UltrasonicSensorExample/HC-SR04_UltrasonicSensorExample.ino

I'm using arduino uno, and separate ultrasonic transmitter and receiver. I'm not using any commercially available ultrasonic sensor

This is the most basic ultrasound pulse and receive code. I wrote it to work with the HC-SR04 modules; so hopefully it will work fro you too as those also sound at 40khz.
The main functionality comes from the pulseIn() funciton.
#define TRIGPIN 9
#define ECHOPIN 10

void setup() {
  Serial.begin(9600);
  pinMode(TRIGPIN, OUTPUT);
  pinMode(ECHOPIN, INPUT);
}

void loop() {
  digitalWrite(TRIGPIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGPIN, LOW);

  uint16_t duration = pulseIn(ECHOPIN, HIGH, 4000);
  int distance = (duration*.0343)/2;
  Serial.println(distance);
}

Note that you will need to adjust the 4000 (μs) to whatever timeout in you want (or emit entirely if you don't want it).

Hi Sir! Sadly, I'm not using any commercially available ultrasonic sensor like HC-SR04. I have separate transmitter and receiver transducer Sir.

@JeniferRicalde That is fine, can you provide a link to these? The code will still work assuming the transmitter and receiver are simply digital outputs (i.e. send HIGH to transmit sound on the transmitter and the receiver outputs HIGH when it receives).

Sir, will it be ok if I ask for your email?I wish to send the code. I cannot attach it in here

Why not? Just insert into the question like I have in my answer the .ino file.  Or make a link with https://pastebin.com/

I'm sending 8 pulses of 40khz waves then the receiver will measure the voltage peak of the wave it received so that it may know the time interval.however, i'm not quite sure if my code is right

here's the link:
https://pastebin.com/4chsLQ6R

I used, Mr. Kerry Wong's code

@JeniferRicalde I am sorry but since you have just copied someone's code it is especially difficult to debug without being able to try things out (since I don't have that setup). However there are two things: you can use the delay() function to delay in milliseconds and use delayMicroseconds() for micros - there is no need to write your own delayMilliseconds() function because delay() already works. And secondly, I recommend you use the Serial lib to print the readings from the receiver to help debugging.

I don't have 'a code', but what you can do is using a timer set to 40 kHz and send the pulses you need. .
If nothing else needs to be done (nor in the future) you can use a delay function.
Also check the pulseIn function from Arduino, you can use this convenience function for the checking the result.

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


text:
Control solenoid valve with arduino running on battery
I built a simple setup according to this tutorial using a 9v battery (in the meantime replaced it with a 120A battery):
https://www.bc-robotics.com/tutorials/controlling-a-solenoid-valve-with-arduino/
Also i attached a humiditiy sensor to measure the soil-humidity.
My plan is:
2 times a day (evening and morning before sunrise) wake up arduino and check humidity, if it is below a certain %, open the 12v-valve, wich i operate at 9v (like the one in the tutorial).
I read a lot about how to reduce power on the arduino and found this tutorial for the pro mini, wich seems a LOT easier than to modify the standard arduino uno:
https://www.whizzy.org/2015/06/howto-very-low-power-usage-on-pro-mini-v2-arduino-clone/
Now, my question is:
would a pro mini v2 work as well for controlling the valve? On the uno, i have the vin-pin wich provides the 9v for the valve, on the pro mini instead, as far as i understood, i need to use that pin (named RAW pin there) as power supply for the arduino... but how would i get out the 9v from the arduino like i did on the uno? Is there any possibility at all?
Thanks in advance!

there is nothing about a battery in the tutorial. how did you connect the battery to Uno if you connected the solenoid to Vin, where I would connect the battery too?

Hi, thanks for your resonse!
I connected the battery to the standard jack.. (wich obviously is not present on the pro mini)

Because you are using a 9V battery, do not remove the power regulator as per the instructions in your second link. You need that regulator to lower the voltage down to the 3.3V or 5V (depending on the version chosen).

You can connect more than one wire to a single Arduino pin.

@sa_leinad:
Thanks, that was one major doubt, even if it sucks a lot of energy.. (i would choose the 3.3, since i do not need a lot of processing power, it does not need to be fast or super-precise timing).
In another tutorial (on the uno however) they talk about replacing the linear regulator with another one by soldering out the default one and putting in a dc-dc regulator... do you think that that would work to save power on the mini too?

@Gerben:
You mean connect two wires to the raw-pin? and when the first one inputs power, the second one gets 9v too beside the arduino?

@pixx: Yes, there are more efficient DC-DC regulators out there, particularly switchmode regulators. It won't save you a lot, but the difference may be worth it.

Exactly. That’s what I meant.

Vin and the barrel jack are the same power input on Uno.
RAW is the label for Vin on Mini Pro.
You can connect the + of the battery to power rail of the breadboard and from there to Vin/RAW pin of Arduino and to the solenoid powering contact.

Thanks!
That sounds great! I connect the + from the battery to lane 1 for instance and from there one pin goes to the arduino and another pin to the solenoid if i understand the solution?

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


text:
Grbl on Arduino Uno (Elegoo) with DM542 + nema24 stepper motor not working
i've already searched and tried for a quite depressing amount of hours, but am not able to solve this problem:
The parts are the following:
 - Elegoo Arduino Uno, on wich i flashed GRBL
 - 24v Power Supply (wich powers the stepper motor(s)
 - Nema24 3nm stepper motor
 - A DM542 Driver
 - bCNC (exe-build on win7 and win10)
Now, i connected one stepper-driver and stepper-motor as x-axis to the arduino.
The wiring is as following:
 - 5v from arduino to the three + Pins (ENA, DIR and PUL)
 - Pin 2 to PUL, Pin 5 to DIR, Pin 8 to ENA
 - 24V go to + and ground port of the driver, the 4 motor-wires are wired accordingly to the driver
I downloaded GRBL from Github and flashed it to the Arduino (i can run grbl-commands from the serial monitor inside the arduino ide, grbl is unlocked), connected everything and opened up bCNC, searched for the arduino on com-port, wich is shown correctly, and connected wich works fine (in the main screen "connected" shows up).
However when i try to move the x-axis under the control-panel in bcnc, nothing moves, on the screen the numbers change correctly and i get an ok in the logs, but the motor does not move a bit.
I double checked the wiring and tried to write a little program in arduino ide to move the stepper motor without grbl (deleted grbl, wrote a little program wich manually set the intervals ecc), without changing the wiring, that worked...
How can i debug this? Any suggestions?
Thanks in advance!

As you wrote, that you connected the positive pins of ENA, DIR and PUL to 5V, I guess you use the common anode connection scheme from the DM542's datasheet (the driver seems to have optocouplers for the inputs). That would mean the inputs are active low (a Pulse would be a transition from HIGH to LOW and then back to HIGH).
GRBL v1.1 has by default an active high pulse signal:

By default, a step signal starts at normal-low and goes high upon a step pulse event. After a step pulse time set by $0, the pin resets to low, until the next step pulse event.

(from the GRBL github wiki). I guess, this is the problem. Please try to set GRBL for inverting the pulse signal with $2 (you may well find a corresponding setting inside bCNC.
Be sure, that GRBL is outputting the signals, that your driver is expecting in your connection scheme.

Hi, chrisl,
thanks for your response!
I'll try it and let you know if it worked ;-) And yes, i use a similar datasheet with the same wiring wich was delivered with the stepper motors =)

Hey chrisl, it worked!!! Thanks man!
I had to invert the ENA-Pin too, but now it works like a charm!
Now i need to figure out how to set the options when the arduino is connected to bcnc, but that's another story.
Thanks again!!


text:
Improper sampling of wave
I am using Arduino Mega 2560 to sample and serially send a square wave. I am using Processing 3.3.6 for logging the data to .csv file. I am receiving about 6k samples at the moment. When I try sampling a square wave, min= 0V, max=3V at 200Hz, the number of samples at the two amplitudes(at 0 and 3V) are not at all close by. What could be going wrong?
This is my Processing code:
//import the required libraries
import processing.serial.*;

Serial mySerial;
Table table;
String filename;

void setup()
{ //print(0);
  //set mySerial to listen on COM port 4 at 1000000 baud
  mySerial = new Serial(this, "COM4", 1000000);

  table = new Table();
  //add a column header "Data" for the collected data
  table.addColumn("Data");
  //add a column header "Time" and "Date" for a timestamp to each data entry
  table.addColumn("Time");
  table.addColumn("Date");
}

void draw()
{ print(1);
  //variables called each time a new data entry is received
  int d = day();
  int m = month();
  int y = year();
  int h = hour();
  int min = minute();
  int s = second();
  //int s_prev=0;
  char d1 = 'a';

  if(mySerial.available() > 0)
  { //print(2);

    //set the value recieved as a String
    String value = mySerial.readString();
    //check to make sure there is a value
    if(value != null)
    {
      String[] parts = value.split("x"); //returns an array with the 2 parts

      //print(parts);
      //print('\n');
      for(int i=0;i<parts.length;i++)
      {

        String Part = parts[i];
        TableRow newRow = table.addRow();
        //place the new row and value under the "Data" column
        newRow.setString("Data", Part);
        //place the new row and time under the "Time" column
        newRow.setString("Time", str(h) + ":" + str(min) + ":" + str(s));
        //place the new row and date under the "Date" column
        newRow.setString("Date", str(s + 100));// + "/" + str(m) + "/" + str(y));
      }
    }
  }
print(4);}

void keyPressed()
{ print(5);
  //variables used for the filename timestamp
  int d = day();
  int m = month();
  int h = hour();
  int min = minute();
  int s = second();
  //variable as string under the data folder set as (mm-dd--hh-min-s.csv)
  filename = "data/" + str(m) + "-" + str(d) + "--" + str(h) + "-" + str(min) + "-" + str(s) + ".csv";
  //save as a table in csv format(data/table - data folder name table)
  saveTable(table, filename);
  exit();
}

This is my arduino code:
int val[2000];
void setup()
{
  Serial.begin(250000);

  //ADCSRA = 0;             // clear ADCSRA register
  //ADCSRB = 0;             // clear ADCSRB register
  ADCSRA &= ~(bit (ADPS0) | bit (ADPS1) | bit (ADPS2)); // clear prescaler bits
  //ADCSRA |= bit (ADPS0);                               //   2
  ADCSRA |= bit (ADPS1);                               //   4
  //ADCSRA |= bit (ADPS0) | bit (ADPS1);                 //   8
  //ADCSRA |= bit (ADPS2);                               //  16
  //ADCSRA |= bit (ADPS0) | bit (ADPS2);                 //  32
  //ADCSRA |= bit (ADPS1) | bit (ADPS2);                 //  64
  //ADCSRA |= bit (ADPS0) | bit (ADPS1) | bit (ADPS2);   // 128
  //pinMode(A0, INPUT);

}

void loop()
{
  for(int i=0; i<2000; i++) {
    val[i] = analogRead(A0);
  }
  for(int i=0;i<2000;i++){
    Serial.print(val[i]);
    Serial.print('x');
  }

}

Why have you asked two questions about this in quick succession?

In the previous one, I wanted to know about sampling and sending faster. Here, I want to know if I am sampling correctly.

You are doing 2000 samples really close together in rapid succession with no concept of time between them, then you are spending a considerable amount of time sending that data through serial.
That's not how you sample signals.
Instead, you need to set up some kind of time-based periodic sampling system, either through a timer interrupt or some other facility provided by the ADC (read the datasheet to see what interrupts the ADC can generate and what sample trigger sources there are) which runs completely asynchronously.  Then when (and only when) a sample set has been captured do you send that data through serial.
If your sampling takes longer than your sending through serial (unlikely) and you have the memory for it you can set up two buffers and "ping-pong" between them so you are sampling at the same time as sending.  Otherwise, all you will be able to do is capture a short window of data and then send it afterwards, so you get short bursts of samples.

Thanks. I see where I went wrong. Would using the free running mode of the ADC serve my purpose better?

As long as you attach an interrupt to it to read each sample, yes.

Suppose I take a sample and send it serially within the ISR function, that would make all my samples equally spaced in time right?

As long as the serial sending takes less time than the time between samples, possibly. Sending serial from inside interrupts takes special care since it itself is interrupt driven.


text:
Why is Arduino Pro Mini not powering this LED?
First off, I'm very new to Arduinos and electronics in general, so feel free to explain like I'm 5.
As a bit of background to this question, the project is simply using a Pro Mini to run a servo, with a button to turn it on and off, and an led to indicate when it's on. To make sure I was getting the button right, I built the circuit on a breadboard with just the button and LED. The button was supposed to switch the LED on and off. It did not.
I removed the button from the equation and just tried to power the LED with the Mini. No go.
It's a blue LED, so the resistor (100) was chosen assuming a forward voltage of 3.3V and current of .02A. I've tested the resistor and LED combo with JUST the battery pack, and it lights up bright like it should.
I have a 9V battery running into RAW (I've also tried a 6V pack). I had pin 2 as an output with digitalWrite(HIGH), running into the resistor, then into the LED (+, long end), and then back to a ground pin. I've tried other ground pins on the board to make sure it's not that. I've switched pin 2 to analogWrite(255), still nothing. I have tried connecting it to VCC instead. Nothing.
However, writing HIGH to the onboard LED works fine, so I can see that the sketch is indeed running.
I've verified the LED polarity. I have tried a different Pro Mini. Nothing. It's a Pro Mini 328P according to the stamp on the back, which Google says runs at 5V and 16 MHz.
Please tell me what stupid mistake I am making so I can stop wanting to rip my hair out. Thank you.

Do you have this in setup()?  pinMode (yourLEDpin#, OUTPUT);

I do indeed:
pinMode(2, OUTPUT);
pinMode(ledPin, OUTPUT);

If it doesn't even work with Vcc, then maybe the battery is dead. What voltage do you measure across it?

Sadly, I do not own a multimeter, so I can't directly test the battery or arduino pins.
Indirectly though, I don't think the battery is dead. It does power the LED in a simple circuit when the mini isn't involved, and when I hook up the mini, it powers on and starts running the sketch, as evidenced by the onboard LED behaving as expected.

maybe you have 3.3v pro minis, whose output won't light up a resisted blue LED

Nope. It turns out the problem is that I'm an idiot.

Thank you both though for trying to help.

This was my mistake. I had attached the Arduino to the breadboard by pushing in the provided pin strips, and then putting the mini on top of those, assuming that since the pin was through the hole and looked to be touching, a connection was made. It wasn't.
Rather than continue to mess around with fiddly connections, I just took the plunge and soldered the entire thing to a circuit board. The LED and the button work perfectly as expected, and now I just need to attach the servo.


text:
Powering Arduino Mega 2560 from a Raspberry Pi Usb
I have a Raspberry Pi B+ running 7x24. I have to connect an Arduino Mega 2560 to its USB. The Arduino has only one nRF24L01-PA-LNA powered from its 3V3.
Can I power the Arduino from the Pi's USB?

I think the quickest away of getting an answer would be to RTM.  Search for the technical specs and what ampage the Pi can put out and see what the mega draws.  TBH I suspect that it isn't going to work.

If you are powering your RPi from power supply 5V/2A at least there should be no problem. USB hub on the RPi should not give more than 500mA to power Arduino. Also there is a fuse on Arduino's board to prevent any damage from USB power.
Check both Arduino and RPi schematics for more details about modules used there:

Arduino
Raspberry

The power of the Pi looks OK. But! The 3V3 ouput of the Mega has 50mA output. The nrf24L01-PA-LNA consumes 45mA in receiver mode but needs 115mA in emission mode. Emission is a peak. Using capacitor would be a solution but it is on the limit, I think it's not the solution for 7x24.

raspberry pi can power ur mega board normally,but the 3v3 in the mega board is not stable and has noise,so it is better to use 3v3 supply source for ur NRF the simplest to use is just hooking a piece of 1117 to 5v of ur mega board

Thanks, I got 5V from an other USB for the 1117 and for a capacitor. Works like a charm. :)

Yeah, as the others have mentioned you can power the Arduino form the raspberry pi's power supply, but you cannot transit data from the raspberry to the Arduino without a third party software.


text:
MQTT over serial
I'm planning to build a 32 relay IOT node next to my Raspberry Pi. The relays will be controlled by an Arduino Mega 2560. The Pi will run Home Assistant and Mosquitto so I would prefer to communicate with the arduino using MQTT.
The Arduino and the Pi will be next to each other, the simplest connection would be over serial.
I have found a library: https://github.com/vortex314/serial2mqtt it looks not easy to set up. Do you have any other ideas?
Thank you!

Why do you need MQTT over serial. You can just send the number of the relay that should be turned on over serial?

That library is designed for the ESP32 which has substantially more power than the Mega2560.

Finally I have found the solution!
Using mysensors (mysensors.org) I can use the Arduino Mega as a node and a serial gateway. So Home Assistant can control it directly.

As the author of the serial2mqtt gateway. Maybe it's time to have a new look. I've included the binaries for different platforms in the build : https://github.com/vortex314/serial2mqtt/tree/master/build
So to get started : unzip the binary and update the serial2mqtt.json config.
Should be piece of cake. Let me know otherwise via github.

Thank you @Lieven
It's a very nice project. Even the documentation is very useful. I already have my system set up but I will keep in mind serial2mqtt. I will definitely try it out.


text:
Driving two stepper motors using one stepper motor driver
Using an Arduino Mega, I currently control two stepper motors that never operate at the same time and never will. I am using two EasyDriver stepper control boards with two separate power sources. I was wondering if I could go down to just one stepper control board, one power source but somehow switch the 4 input wires from one motor to another when I need to turn a specific motor. Is there a switch I can control with Arduino where I can plug in 8 wires and say "ok, use the 4 left most wires" or "switch to the right most 4 wires". Does that exist or is that more complicated than what I currently have?

If we call the motor leads A1, A2, B1, B2 on each motor and control, you could tie the two motor A1's to A1 on the control, and motor B1's to B1 on control.  Then wire a DPDT relay as below.  (Coil not shown.)  Note, DPDT relays are about $4 on ebay, with labels like “DR21A01 DC 5V DPDT Relay Module Polarity reversal switch Board for Arduino UNO”.

simulate this circuit – Schematic created using CircuitLab
Since you have equipment in place and working, it might not be worthwhile to change your setup.  However, even without adding a relay, you probably can power both motor controls and motors with a single power supply, ie could use one instead of two power supplies.  The current draw when a stepper motor is idle is a small fraction (eg 10-20%) of the high current drawn when the motor steps.  If you don't have power attached to a stepper motor, there is only its cogging resistance to keep it from turning; it does not take a large torque to turn an unpowered stepper motor.  If that's a concern, the DPDT relay approach might be unsuitable.


text:
Action while button is pressed
My issue is that I can't rotate the motors continuously. If I press any button, motor.step will be executed and then it stops, even though I didn't release the button.
This is my project so far.
Code:
#include <AFMotor.h>

//define steppers
AF_Stepper motor1(48, 1);
AF_Stepper motor2(48, 2);

char data;

void setup()
{

  motor1.setSpeed(200);  // 10 rpm
  motor2.setSpeed(200);  // 10 rpm
  Serial.begin(9600);
}

void loop()
{
  Serial.println(data);
  if (Serial.available())
  {
    data = Serial.read();
    if (data == 'A')
    {
      motor1.step(200, FORWARD, DOUBLE);
    }
    if (data == 'B')
    {
      motor1.step(200, BACKWARD, DOUBLE);
    }
    if (data == 'C')
    {
      motor2.step(200, FORWARD, SINGLE);
    }
    if (data == 'D')
    {
      motor2.step(200, BACKWARD, SINGLE);
    }
    if (data == 'E')
    {
    delay(50);
    }
  }
}

App Inventor blocks:

This statement: data = Serial.read(); consumes the data sent over the serial port, so to get continual movement, you will have to constantly feed in A or B, etc. from whatever is generating that data.
Alternately, you could define a 2nd set of single-character commands to accompany the start-rotation parts so that send one command to turn on the motor, and a different command to turn off the motor. You would need to add a variable to hold the current state (started or stopped) of each motor, and turn on or off those states depending on what commands come in from the user.
(untested code)
#include <AFMotor.h>

//define steppers
AF_Stepper motor1(48, 1);
AF_Stepper motor2(48, 2);

char data;
int8_t motor1state=0;  // 0=> Stopped, -1=>Reverse, 1=>Forward
int8_t motor2state=0;

void setup()
{
  motor1.setSpeed(200);  // 10 rpm
  motor2.setSpeed(200);  // 10 rpm
  Serial.begin(9600);
}

void loop()
{
  Serial.println(data);
  if (Serial.available())
  {
    data = Serial.read();
    if (data == 'A')
    {
      motor1state = 1;
    }
    if (data == 'B')
    {
      motor1state = -1;
    }
    if (data == 'C')
    {
      motor2state = 1;
    }
    if (data == 'D')
    {
      motor2state = -1;
    }
    if (data == 'F')
    {
      motor1state = 0;
    }
    if (data == 'G')
    {
      motor2state = 0;
    }
    if (data == 'E')
    {
    delay(50);
    }
  }

  if (motor1state>0)
  {
    // Step forward
    motor1.step(200, FORWARD, DOUBLE);
  }
  else if (motor1state<0)
  {
    // Step backward
    motor1.step(200, BACKWARD, DOUBLE);
  }
  else
  {
    // Do nothing
  }

  if (motor2state>0)
  {
    // Step forward
    motor2.step(200, FORWARD, SINGLE);
  }
  else if (motor2state<0)
  {
    // Step backward
    motor2.step(200, BACKWARD, SINGLE);
  }
  else
  {
    // Do nothing
  }
}

Thanks for you reply.
Now, if I press any button, the steppers won't stop rotating until I press any other button and then again, they won't stop. I'll somehow tweak this and maybe make a use of it. @jose

That's the point.

I just rebuilt the mobile app for the 'G' and 'F' cases, now everything's fine. Thank you, you're great! @jose

Everything's working correctly, but I am getting broken pipe error(516) messege randomly while I'am controlling the steppers? @jose

What does the other end look like? You added a bluetooth tag -- are you sending from an Android app? An error like that would not indicate a problem with the Arduino code, but with the bluetooth module or the Android side.

I'm sending from an android app. Bluetooth module was working fine til now. If you got time, you could send me a DM on twitter, as I just followed you, and I would be able to provide more specific information with screenshots included. @jose

Serial isn't a keyboard. When you send 'A' you send 'A'. Whatever that source is - if you send a single A you send a single A, and you receive a single A.
You will have to come up with some other protocol and write some special software on your computer that monitors the keys directly, and sends something along the lines of "I Pressed A" and "I Released A".


text:
Missing arduino bootloader problem?
I have a arduino clone that is not being assigned a /dev/tty by Debian Stretch (Stable).  It does have the ch340g chip.  I have tried the driver from the manufactures site with no joy.  Would the lack of a bootloader cause this problem?
Thanks.

Trying a random manufacturer driver makes no sense on a Linux system, the proper CH34x driver is already in the mainline kernel sources.  To figure out what is actually wrong you should start with dmesg and lsusb.

Been there done that.  And the source is from the Actual board manufactures site. usb 2-1.3: new full-speed USB device number 14 using ehci-pci
[136679.079624] usb 2-1.3: device descriptor read/8, error -32
[136679.207639] usb 2-1.3: device descriptor read/8, error -32
[136679.314532] usb 2-1-port3: unable to enumerate USB device

this information should have been in your question when you posted it . ... please update your question with this info (use the edit button)

What is actually wrong with the board is a different question than was asked.  Though again, despite being irrelevant to the actual issue, with Linux you all but never want to use a manufacturer's driver, and definitely not when there's a known-good and actually code reviewed one in the mainline kernel sources.

No.  On Arduino-style boards which use distinct chips for the main processor (ATmega328p) and Serial interface (CH34x/ATmega8u2/ATmega16u2/FT2232 etc) the presence or absence of a bootloader on the main processor has no bearing on the recognition of a USB/Virtual Serial device by a host.
However on ATmega32u4 and some ARM-based boards it can.
Since you are describing a classic board with distinct chips, whatever your actual issue is, it is something else.

Figured as much.  I was just hoping that when a new board gets here I could install a bootloader to it and have it start working.  So I expect that the chip is bad and I have a brick.  To bad it would cost as much to send it back as it cost in the first place.

If you desolder the USB chip the ATmega processor might still be good.

See my question & answer about debugging board issues


text:
Genuino UNO 5V pin is reading 0.3V
So I was trying to set up the LCD screen that came with my Genuino starter kit when I noticed that the board screen did not power on at all, unlike a few days ago when it worked.
In order to verify that the UNO was delivering power I simply connected an LED in series with a 220Ω resistor, between the 5V and ground pins. The LED did not power on.
I then, with the UNO still connected over USB, measured the voltage between across the resistor and LED and found it to be around 0.2-0.3V. Going further, reading the voltage between the 5V and ground solder connections on the back of the board and the reading is about the same.
I can power the LED from a digital pin that I set to HIGH, the issue seems to just be with the 5V pin.
Is there anything simple that I am missing (I hope there is) or is there likely a problem with my board? If there is a problem, could I use a digital pin to power a larger circuit such as that with an LCD or would the current supplied be too low?

Are you sure you have the 5V pin and not Vin?   And that driving an LED from a digital output worked under the same circumstances where the 5V pin did not?

Positive, disconnecting only the power connection and moving it to either 3.3V, Vin or a HIGH digital output results in the LED powering on.

Maybe you should try where the pin sticks through the bottom of the board.  It is possible for the sockets you plug into from above to fail mechanically and not make contact with whatever you plug in.

I have tested both the sockets and the solder connections under the board to no avail, the behaviour is consistent.

Power it off, get an ohm meter with sharp leads and start tracing continuity from the ATmega VCC pin to the inactive 5v pin.  Or if your time is worth more than the board, replace it.

And you do know that there are two ground pins, right?

I have tried but can't seem to find the fault. I may just replace it. And yes I have tried all three ground pins. Thank you for your time.

If the chip is running the only thing that can stop the 5v pin getting power is physical damage. There is only metal between the chip and the pin.

the LCD can be powered by a digitalWrite(HIGH), but the backlight cannot.

There are a couple more places you can sample the 5V signal, see the photo here:

On the right, on the ICSP header, the pin marked VCC is also connected to the 5V signal. Try testing that.
(The other one is pin 2 of the ICSP interface for the USB chip, but the one on the right should be adequate for testing).
I don't know why you are mucking around with LEDs and resistors, just put your meter between Gnd and 5V.
I find sometimes that the hookup cable has failed, try testing that (or try with a different cable).


text:
How to measure the supply voltage of Arduino without using an analog pin
I'm using Arduino Nano to measure temperature with a 10 kohm thermistor and a voltage divider. My problem is I'm getting only 4.2V on the 5V pin. The power is supplied via a USB cable from a desktop PC.

I measured the output voltage of a USB port on the PC and it was around 4.5V. It doesn't look normal. So I suspect the power supply unit of the PC is not strong enough.
But it still makes sense to measure the voltage at the 5V pin since there is no guarantee it's exactly 5V. Its error will affect the calculated resistance of the thermistor. So I got it by connecting the pin directly to the A1 pin.
On the other hand, it seems to me Arduino internally and digitally knows the value of the supply voltage. So it would be faster and easier to get it rather than using the A1 pin. But I don't know how to do it.
After searching on the Internet, I could find only these things which didn't help me much.

voltage level - What are the 5V and VIN pins for? - Arduino Stack Exchange
voltage level - Getting 3.3v on 5v pin in Arduino Uno - Arduino Stack Exchange

I also considered using an external power supply, say 9V to the VIN pin but I don't feel like doing that much.
How can I measure the supply voltage of Arduino without using an analog pin?

The analog inputs measure a voltage ratio: input/reference. Thus the calculated resistance of the thermistor is not affected by variations in the supply voltage.

Okay, so the integer returned by analogRead() is input/reference(1.1V)/5V*1023?

analogRead() returns Vin÷Vref×1024, where Vin is the voltage at the input pin and Vref is usually (if youy did not mess with analogReference()) the supply voltage.

In the case of your voltage divider, analogRead() returns Rthermistor÷(Rthermistor+Rpullup)×1024, irrespective of the supply voltage.

This page says "voltages between 0 and 5 volts into integer values between 0 and 1023" so is it really 1024? If it were 0-5 volts into 0-5, it would be Vin÷Vref(5V)×5, though 0-5 have 6 integer values.

Yes, it's 1024. The ADC saturates at 1 step below Vref. C.f. the datasheet of the microcontroller, which is the only authoritative document for that matter.

Great! So the maximum measurable voltage is not exactly 5V, but 1023/1024*5V if Vref is 5V?

Actually it's 1022÷1024×Vref, because when you read 1023 you don't know whether the input voltage is 1023÷1024×Vref or anything higher. Actually, any voltage above 1022.5÷1024×Vref is expected to give a reading of 1023.

Yes, you can do it.
You can measure the voltage of the internal (approximately) 1.1V reference voltage using the ADC and use the results of that to calculate what the reference voltage you used (VCC) must have been to get the results you did.
This is a function I commonly use:
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1125300L / result; // Back-calculate AVcc in mV
  return result;
}

Depending on how close to 1.1V your internal reference voltage is, you may need to adjust the value 1125300L in the code above.  Measure the actual VCC voltage and adjust that value until it results in the same voltage being returned (multiplied by 1000 since that function returns millivolts).
However, as Edgar Bonet mentions, you don't need to care about the supply voltage in your situation, since your thermistor readings are just a ratio that input voltage, whatever it is. Change the input voltage and you will get the same results, since the ADC returns a value between 0 and Vcc in 1024 steps. With different supply voltages you still get 1024 steps.

How did you get 1125300L? And why is it 1125300L / result? It seems to me ADCL | ADCH << 8 is a 10 bit ADC value so something like result = 1125300L * result / 1024 would make sense. But for this one result is the denominator.

1125300 is 1100 (1.1v as mv) times 1023 (ADC max value).

In this page, it is 1126400L = 1.110241000. I'm wondering which I should believe.

There are massive arguments around the net regarding if you should use 1023 or 1024. I say 1023. The max value of the ADC is not equal to VREF, but is VREF "minus one LSB" (as stated by the datasheet). 1024 would be VREF but you can't get 1024 out of the ADC.

IMHO it's 1024. Edgar Bonet's comments sound reasonable. For the denominator thing, I was wrong. the equation is Vin(1.1V) = ADC/1024AVcc(5V) since it reads "1.1V reference against AVcc". That's equivalent to AVcc = 1.11024/ADC = 1126.4/ADC.

Regarding the use of delay(2) to allow AREF to settle, how long you actually have to wait depends on the size of the capacitor from AREF to ground, as well as the drive capability of the new source. I've observed changing MUX from 1.1 to Vcc settles faster than from Vcc to 1.1.

Without doing per-board calibration, the value this yields is inaccurate to the point of being useless.

@Boann It's precise enough to detect whether the Arduino is powered by a USB port or a Li-ion battery, so it's certainly not useless. If you need accurate measurements, Arduino is certainly the wrong hardware.

Per https://www.gammon.com.au/forum/?id=11497&reply=2#reply2 I measured my bandgap voltage as 1.082 with an void setup (){analogReference (INTERNAL);analogRead (A0);}

The Nano has an ATMega328P MCU, which has an internal 1.1V reference voltage.
You use analogReference() to change the reference voltage that analogRead() compares the analog inputs against.
You will need to use a voltage divider to ensure that your maximum possible supplied voltage ends up being no higher than the 1.1V reference.
You'll still need to use an analogInput pin.

If you do this, you will make the resistance reading dependent on the supply voltage, which is what the OP wanted to avoid in the first place.

I see. You are correct; I was only solving the problem of how to compute the supply voltage, but with the supply voltage known, the resistance reading for the thermistor can be calibrated in software.

What Edgar was saying is that the thermistor measure is ratiometric, so using a ratiometric way of measuring the thermistor voltage the supply voltage perfectly cancel out. If you use the 1.1V reference you will have to make more calculations and will have a less precise measurement

Hi, my intention was to know the supply voltage without making the system complicated. I think the value of the voltage doesn't matter as @frarugi87 suggested the two voltages cancel out. If it were not so high it generates tremendous heat and break parts or so low it can't be measured, it's fine.


text:
Arduino UNO reprogram the MEGA8u2 using external programmer
As they say in https://www.arduino.cc/en/Hacking/DFUProgramming8U2 you need to solder a 10k resistor in order to reprogram/reset the MEGA8u2 chip on Arduino UNO but sometimes you may lack the needed tools.
Is there a way to reprogram the MEGA8u2 using an external programmer or an another arduino as a programmer?
My idea behind this is to use the ISP LAYOUT for ATMEGA8U2 in order to load the correct bootloader:

How is that easier than soldering in a 10K resistor?

Actually in my case I do not know if I can solder one: https://arduino.stackexchange.com/questions/50807/how-to-re-solder-the-resistor-in-order-to-reprogram-the-mega8u2

Sure you can. Solder in a 6 pin header and you can program the ATMega8U2 using any Atmel hardware programmer. It's just a standard MCU, after all.  I'm not sure how the DFU side of things works - whether it's built into the chip in ROM or not1, but if it's just a bootloader in flash your programming may wipe it out stopping DFU from working in future. Not a problem if you can't get into DFU mode anyway.

1: The DFU is firmware stored in the "boot" region of the flash. As long as you don't erase or overwrite that region of the flash DFU will still function in future. Of course, you can also re-install the DFU firmware at any time you like.


text:
Can I use this approach so I can sniff both TX and RX signals using a Second arduino?
Based upon this answer I can hook up 2 arduinos like this:

But AFAIK The main microcontroller uses an RS232 protocol and AtMegau16 (or ATMegau8) converts it into USB one emulating an FTDI chip.
But in my case, I need just the RX port from the second in order to just sniff data. So I looked on how I can pirate the RS232 signal and I found this schematic:

Resulting to this monstrocity:

But would this allow me the secoind UNO to capture both RX AND TX signals?

You only need the diode on the TX line, and you only need the resistor on the RX line.

You can try this, but your sniffer will only work satisfyingly if the communication protocol is half-duplex. This means, that TX and RX are never transmitting at the same time. If the protocol is full-duplex, and both wires transmit at the same time, their signals are mixed together, resulting in erroneous data. To tackle this situation, you need two serial receiver channels, one for TX and one for RX.

This approach may work in some cases but will not work in all cases.
Assuming the intent is to listen to both the transmit and the receive side of an RS232 type signal.
An RS232 signal may swing from -12 to +12 Volts.  Many logic inputs behave unexpectedly when driven by voltages higher than their supply rail.  A resistor may mitigate this problem.  A logic level shifter would be better.
The circuit diagram in the question is an example of a wired OR connection.  If either serial transmit line is high the data from the other will be blocked.  As illustrated in this diagram from wikipedia.org.

So this circuit diagram will only work reliably for half duplex communications.  If full duplex monitoring is required, two independent receivers / monitors will have to be used.


text:
How to indicate an End of a stream on USB
I am making a Lora-USB passthrough device using arduino and somehow I want to indicate that a stream over some data has ended.
So far I have done:
void onLoRaReceive(int packetSize) {
  if (packetSize == 0) return;          // if there's no packet, return

  byte[packetSize] buffer=[];

  while (LoRa.available()) {
    site_t recievedData=LoRa.readBytes(buffer,packetSize);
    Serial.write(buffer,recievedData);
  }
}

So what I want to know is how the software reading from the serial interface will know that a packet has ended; One way I thought is by sending an EOF byte but I am afraid of "rogue" EOF values in packet data.
An another way is to send the packet size through the Serial interface as well but how I will make it understand that what I am sending now is the size and expect X size of data?

LoRa has a moderate data rate and typically substantial gaps between packets, so a simple thing you can do is send the data as printable ASCII hex with newlines or other terminators.
This will just short of double the amount of data you have to move, but do so in a very simple and deterministic way, and you can crank up the serial baud rate to handle it, especially as the baud rate only actually "exists" between two ATmega chips within the Uno.
Another plus is that the data becomes human readable, which is handy for debugging, especially if you might want to intermix advisory messages and data.

What you need is some form of protocol. Some system that both ends of the communication channel agree on.
Most serial protocols use certain characters to indicate certain things, and indeed the ASCII character set has certain characters earmarked for certain jobs in communication, so it makes sens to use those.
One you can use is EOT - End Of Transmission - character 0x04. Note: there is no such thing as an "end of file character 'EOF'". That's purely a DOS construct.
And yes, you may wonder about a rogue 0x04 in the data stream triggering the end, and you're not the first to think about that. That's why there's character 0x10 - DLE. That's Data Link Escape. Its purpose is to tell the receiving end "The next character I send is a data character. Don't interpret it as a control character.".
So for every 0x04 in the data stream you should send 0x10,0x04 instead.  Your receiver code then sees the 0x10 and makes a note that the next character should not be interpreted as a control character, but raw data.
Problem solved.
But what, you ask, about there being a rogue 0x10 in the data stream?  Isn't that going to cause the same problem?
Yes. And you deal with it in exactly the same way. Just prefix it with 0x10. Since the receiver should then know to always interpret the next character as data, regardless of what it is, it will see the next 0x10 as data.
So as an example, sending the following data stream:
0x06,0x31,0xc7,0x04,0x91,0x10,0x04,0x73

would be done as:
0x06,0x31,0xc7,[0x10],0x04,0x91,[0x10],0x10,[0x10],0x04,0x73

(Added 0x10s highlighted with brackets).
It can be good to use some of the other control bytes as well, such as SOH for Start Of Header, STX for Start of TeXt, ETX for End of TeXt, etc. You can then do such things as tell the receiver where the start of your packet is, and what the different bits of it are. Adding a header with the length and a checksum can also be worthwhile too, for increased reliability and data integrity.

I wonder also if FTDI devices also have in-protocol serial transmission handling and Arduino Serial interface offers these type of handlings out of the box.

Also in case of calues that are over a 7-bit ASCII range ( >128 ) should I escape it with 0x10 as well for example the 0xFF value?

Why would you want to? You only need to DLE the bytes that your protocol uses.


text:
Turn off the second builtin Nodemcu 0.9 led
I'm making a low energy consumption device so I'd like to turn off all the led when I'm idle.
Unfortunately the nodemcu turn on a blue led while I'm idle (during delay(ms))
Here is my code:
#define LED    16

void setup() {
  initialSetup();
  //Turn off the built-in led
  digitalWrite(LED, HIGH);
}

void loop() {
  //Here I do everything
  doStuff();
  //GO TO SLEEP
  delay(3600000);
}

The led that turn on during delay is the one near to D0 pin.
The led that I can control and so turn off (pin #16 -> D0) is near the 5v pin.
It's possible to completely turn off all led to consume less?

See this link which shows your second LED exactly (the image is for v1.0, I have v0.9 and the code below works just the same in this situation):
'Onboard LEDs? NodeMCU's got two!':
https://lowvoltage.github.io/2017/07/09/Onboard-LEDs-NodeMCU-Got-Two
Quote:

ESP-12 LED Blink:
 void setup() {
        pinMode(2, OUTPUT);     //Initialize GPIO2 pin as an output
 }

 void loop() {
   digitalWrite(2, LOW);   // Turn the LED on by making the voltage LOW
   delay(1000);            // Wait for a second
   digitalWrite(2, HIGH);  // Turn the LED off by making the voltage HIGH
   delay(2000);            // Wait for two seconds
 }

Or write it like this (ie. using 'D4' rather than '2'):

ESP-12 LED Blink:
 void setup() {
        pinMode(**D4**, OUTPUT);     //Initialize GPIO2 pin as an output
 }

 void loop() {
   digitalWrite(**D4**, LOW);   // Turn the LED on by making the voltage LOW
   delay(1000);            // Wait for a second
   digitalWrite(**D4**, HIGH);  // Turn the LED off by making the voltage HIGH
   delay(2000);            // Wait for two seconds
 }

Regards, Geoff

Thank you, I've already read that link and it talks about nodemcu 1.0, mine is nodemcu 0.9 and pin #2 correspond to port D4 and does NOT turn off any led

I have a NodeMCU v0.9 and have just tested it.  Referring to the pin as '2' or 'D4' both cause the LED you describe to flash...

Oh sorry, you are right! I used that port also for another sensor so it remains always on. Now I wired the sensor to port D5 and I've no problem! Thank you, you have the best answer!


text:
NodeMCU 1.0 - Port D3, relay and pump does not boot
I'm trying to create a watering system using a NodeMCU 1.0, a relay and some pumps.
Currently I've port D0, D1, D2, D5, D6, D7, D8 already in use.
I'm trying to use the port D3 (GPIO0) as follows, but when I plug or reboot the NodeMCU, sometimes (!) at boot the relay starts, the pump starts watering and the board does not finish the boot.

The only way to start the board are the following:

Unplug the current from relay
Unplug D4 until boot ends
Disconnect the pump from relay

I tried to substitute the pump with a led and a resistor and I've no problem.
I tried also to put a resistor before the pump and it starts (but the pump does not work).
At boot my first command (after defining variable and object is setting D3 as HIGH)
#define D0 16
#define D1 5
#define D2 4
#define D3 0
#define D4 2
#define D5 14
#define D6 12
#define D7 13
#define D8 15
#define A0 17
#define TX 1
#define RX 3
#define MSG_BUFFER_SIZE 128

// Initialize clients
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
char msg[MSG_BUFFER_SIZE];
int iteration = 0;
int ID = -1;
int first_run = 1;

void setup() {
  //Initial setup
  digitalWrite(D3, HIGH);
  pinMode(D3, OUTPUT);
  delay(4000);
  Serial.begin(9600);
  ...
}

I really don't understand where is the problem.

what do you expect the top relay to do? ... where is the pump? ... where is the power supply?

D3 is io 0 the boot mode selection pin. it must be HIGH for normal boot. NodeMCU has a pull-up on it.

@jsotola the ralay should turn on and off the water pump when I receive a specific mqtt message. The pump is the white stuff in the picture and is physically nearby the sensor. The power is provided via USB to nodemcu

@Juraj I set D0 as high, is it wrong?

D3 is connected to the FLASH button on the board. It is used to control the boot mode on startup. If this pin is LOW on startup it will stay in flash mode, ready to receive a new program. If it is high on startup it will then execute its saved program (normal boot).
What probably happens here is, that your relay board pulls D3 to LOW, when its connected (probably only a bit stronger than the NodeMCUs builtin pullup resistor). Probably it has a pulldown resistor on its input pin (to keep the relay open by default). The NodeMCU then sees D3 being LOW on startup and stays in flash mode, never executing your code. To let the NodeMCU execute your code, D3 needs to be HIGH at startup! If this happens randomly, then the pullup and pulldown resistors are probably have similar values, so that the noise in the system can switch the state of the pin.
You now have different possibilities:

You could remove the pulldown resistor from your relay board, so that the pullup resistor on the NodeMCU can pull the pin to HIGH during start, until your program will set it to LOW again. Then you need to live with the fact, that the relay will be ON during startup of the NodeMCU, running your pump in that time.
You can do the above, but also move the pump connections to the NC (Normally Closed) contact of the relay. This means the pump is activated, when D3 is LOW, and deactivated, if it is HIGH, so the logic is inverted. D3 being HIGH on startup would then mean the pump isn't running. The caveat is, that if the pumps power is on, which the NodeMCU/relay power is off, the pump will be running.
You can use a different pin for this function. One that is free of a special boot function. We don't know, what you are doing with the other pins. D3 would be a good fit for an input pin, that needs the pullup resistor (like for connecting a button). Or an output pin, where the state at startup is not dictated by the outside device.

Thank you for this precious answer. The first option (remove pulldown) seems fine to me. How can I remove the pulldown and exactly what is it? I've a relay SRD-05VDC-SL-C

I tested to set NC the relay but I get the same result. Sometimes (actually often like 4 times out of 5) the board does not start and remains in flashing. Keep testing the other 2 ways

That part number is only the relay itself, not the relay module, that you use. Can you provide a product link for that? And when doing my second point, you still need to remove the pulldown resistor from your relay module. Using the NC port of the relay doesn't change anything on the signal line. My second point is only to prevent the pump to run during the NodeMCUs startup and its a tradeoff. Best would really be to use a different pin.

I bought this relay (https://it.aliexpress.com/item/1005005865597217.html).
It's the model with 4 channels


text:
MQTT not working on ESP8266 (Nodemcu 0.9)
I'm trying to use NodeMCU on my ESP8266 (NodeMCU 0.9) but the board keep crashing and I don't understand why.
I tested the mqtt broker using command line and it works perfectly, so I can suppose that the problem is not the server.
I was following this guide but it doesn't seem to work with me.
Here's the code I wrote:
Previously:
#include <PubSubClient.h>
#define MQTT_SERVER    "1.2.3.4"
#define MQTT_PORT      1883
#define MQTT_USER     "user"
#define MQTT_PSW      "psw"
...
WiFiClient client;

Then:
PubSubClient clientMqtt(MQTT_SERVER, MQTT_PORT, this->client);
//Try mqtt connection
while (!clientMqtt.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (clientMqtt.connect("ESP8266Client", MQTT_USER, MQTT_PSW)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(clientMqtt.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
}

//Try send message
clientMqtt.publish("bin", "test", true);

The code works correcty until clientMqtt.connect("ESP8266Client", MQTT_USER, MQTT_PSW) where at the first/second attempt crashes.
This is the output:
Attempting MQTT connection...
failed, rc=-2 try again in 5 seconds
Attempting MQTT connection...
failed, rc=-2 try again in 5 seconds
Attempting MQTT connection...

Soft WDT reset

ctx: cont
sp: 3ffefa90 end: 3ffefe30 offset: 01b0

>>>stack>>>
3ffefc40:  3ffe897d 40202c5d 3ffefcc4 40202dab
3ffefc50:  3ffe89b7 3ffefcc0 3ffefcc4 40203cdc
3ffefc60:  514d0400 00045454 3ffe89a7 40204cdc
3ffefc70:  3ffe89c0 3ffe89a9 00000000 3ffe88fa
3ffefc80:  3ffeeb70 3ffefdb0 3ffeedd8 3ffe88fa

The Soft WDT reset means that the software watchdog timer reset. Depending on the version of Arduino core to the ESP8266 using delay() can cause this to happen, though current versions handle this better, and using delay() does not cause problems. Make sure you are up-to-date with the Board Manager definitions for ESP8266-based projects.
This page has lots of information on the watchdog timers and especially notes how to use a tool called ESP8266/ESP32 Exception Stack Trace Decoder to determine exactly what line in your code caused the reset to happen.
This page notes that the PubSubClient library can cause problems with the watchdog feeding and gives examples of some alternative yield() and delay() functions you can include and call instead of the built-in versions, which help alleviate resets when using PubSub on ESP8266.
The software watchdog timeout is on the order of 3 seconds, so you can also try reducing your delay(5000) to something shorter, like delay(1000) while debugging, to rule out the 3-second WDT reset due to the delay() call.
Your output also indicates status -2 to the state() function. The documentation for PubSubClient notes that this means "the network connection failed". So one other thing to check is that your device actually connects to the WiFi network and that the MQTT server is listening on the IP address and port you specify.


text:
Follow redirect of a captive portal with NodeMCU 0.9
What am I doing?
Trying to connect to a free wifi with a Nodemcu 0.9.
What I have already done?
Connecting and loading a test page in order to be redirected to the login page
Connection code:
 const char* ssid = "polimi";

  Serial.println("Attempting to connect");
  WiFi.begin(ssid);
  //Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

Detection of captive portal
  String host = "clients3.google.com";
  String site = "/generate_204";

  Serial.print("Connecting to ");
  Serial.println(host);

  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  // We now create a URI for the request
  Serial.print("Requesting URL: ");
  Serial.println(site);

  client.print(String("GET ") + site + " HTTP/1.1\r\n" +
    "Host: " + host + "\r\n" +
    "Connection: close\r\n\r\n");
  delay(500);

  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  Serial.println("");

  Serial.println("###Connection closed###");

What am I obtaining?
Nothing, but I wanted to obtain the html strings of the captive portal
What I'd Like
Find a way to follow the redirect and finally send a POST with my credential.

nothing? it connects to wifi? it connects to server? maybe it takes longer then 500 ms until the response arrives

@Juraj For sure it connects to the wifi then print the "requesting url..." and "###connection close ###". Absolutely no redirect. Client. Readstring does nothing

your way of waiting for the response with delay is wrong. see some WiFiClient example

@Juraj Can you show me where to find interesting example? This is what I've found on internet. I suppose I'm waiting using: while(client.available()). If I am writing here is because I don't understand where's the error

now I see that the esp8266 library has not so good example. try to adopt AVR WiFi Shield library example or this example https://github.com/jandrassy/UnoWiFiDevEdSerial1/blob/master/examples/WiFiLinkWebClient/WiFiLinkWebClient.ino

use the httpclient instead of the low-level stuff to make it easier on yourself.

@dandavis Is there any working httpclient?

So far I was able to import RestClient.h that allows me to send a POST request, now it will be quite hard to read a possible redirect

there's a few built-in "ESP8266HttpClient" example, which use a high-level interface.


text:
Does the reset button clean a programe that you programmed?
does the code clean from arduino if i touch reset button?

No, reset does not do that.

No, it only causes the microcontroller to start over the existing program/code.


text:
Arduino WiFi/ESP8266 WiFi Password Changed
I am working on a project for a friend who is not very tech savvy involving an ESP8266. It will need to be connected to his WiFi network.
The issue is that he occasionally changed the password to his WiFi network. Since I will not be able to access this device at a moments notice, it needs to be able to adapt to a change in the password. Is this possible with the ESP8266, or should I switch to an Arduino WiFi board, or is something more powerful necessary?

The most common solution is to have the ESP act like an accesspoint, if it can't connect to the wifi network. It will then host a webpage, where you can set the correct networkname and password.

The ESPEasy firmware does the trick, but it may not do whatever you preprogranmed it to do

The WiFiManager library was written for exactly this purpose.

Yes that's possible.
Just don't hard-code the password: store it in EEPROM.
A common way of doing it if for the ESP to present a wifi access point which serves a configuration page when it cannot successfully connect to another access point.  Store the SSID and password in EEPROM.

On my laptop, if the wifi network password changes, I do not need to re-enter the password, it figures it out automatically. Is there a way I can do this on the ESP?

I think you are mistaken about that.

Ok, I just realized I can use bluetooth for this project as well. Is there a way I can add a password to bluetooth to restrict access to specific devices?

That's a new question.

Bluetooth authentication isn't very strong, you could do an ethernet connection, since these aren't password protected.

Think about it, you don't want any device to be able to do this.  Imagine you got hacked and someone got your password.  If this was possible, then you wouldn't be able to stop them by changing the password.


text:
Detect where pressure is being applied by using force resistors
I have 3 force resistors in a row, on top of which I have placed a board. I read values from the resistors through analogue ports. My goal is to be able to detect whether someone is pressing on the top, middle, or bottom of the board.
So far I can easily detect the left and right, like this: I first calibrate the 3 sensors for 2 seconds. Then I detect if pressure is applied on any of the calibrated sensors. If yes, I sum for all of them the values that they return on each round of the loop, until force has stopped being applied. I finally compare the 3 values against each other and I find which received higher pressure in total. This works perfectly fine for the left and right. However, when the board is pressed in the middle, pressure is applied on all 3, since the board is flat. Sorting the values does not help, because very often the left and right sensors have recorded a higher value than the middle.
I noticed that when the board is pressed on the left, the right sensor records very few values, and the same for the other way around. So, I get a high success rate in detecting middle presses like this:
int threshold = 80;
if (left_sum > threshold && middle_sum > 80 && right_sum >80)
    return middle_pressed;

However, when someone presses hard enough on the left or right, the if statement is satisfied.
Is there a more accurate way to detect where force is being applied?
(Following is a quick schematic I made - I am not at all an expert so please excuse me for my mistakes, I just hope it illustrates more or less what it is supposed to)

simulate this circuit – Schematic created using CircuitLab
Please ignore the double arrows right on top of the resistors.

Is there something between the board and the FSR ? To spread the pressing force over the FSR ? For example a sheet of 1mm silicone. I don't know a smart mathematical solution, because the board does not bend. A resistive touch screen detects the middle of the force, but the top layer bends. I would use a threshold at the end of a calculation. First I would calculate which one is most likely to be pressed (using all three sensors for each calculation), and after that I would apply a threshold to check if it will be accepted. Do you really need the middle FSR ? It does not give more information.

Thank you for your answer! To clarify, the board on top is too thick to bend, so I cannot do much about it. You are right that the middle one does not do much, so I will consider removing it. Another thought I had is if both left and right detect pressure to return the middle if left/right < threshold. This will probably minimise the risk of getting the middle if you pressing too hard.

Okay, removing the middle FSR is a good idea, it is only confusing. Be sure that the FSR are attached to a flat surface. There must be something (1 mm silicone sheet) between the FSR and the board. This is really important to get consistant values. Now you can do math. Calculate with two sensors where the force is pressed, determine the position and the total force (if possible in Newton). Use the threshold at the end of the calculation when the position and total force is known.  In the code you might need to check two position limits and one threshold limit for each virtual button.

Yes you are right about the silicone, I had already put on the sensors these silicone "legs" that you stick on things that you don't want to slide. Here is my code if anyone is interested. At the moment the results are almost perfect (it fails to detect ~1/20 trials) and I am looking into how I can improve it further https://gist.github.com/jackgu1988/085fb432b1d0005083cbd5570a55d6ab

As I wrote before, I would calculate the position and the total force, and after that decide which virtual button was pressed. You are making decisions before any decision should be made. I'm sorry, but I can't put it into code right now.

Sorry about my ignorance but I come from a different background so I don't know much about this yet. What do you mean "position of the total force"? If you can explain it I can put it into code. Thank you very much!

the position and the total force. I have made a (very long) answer.

Let's assume that you have only two FSR sensors. With those you can make three virtual buttons (above the left sensor, above the right sensor and in the middle).
To measure someone's weight, it is allowed to have a scale under each foot and add both weights. We can use that to calculate the total force pressing to the board, by just adding the two forces.
The FSR sensors have a curve to calculate the force in newtons. It is very inaccurate, but works more or less. That can be added later. For now let's assume that it is linear to the ADC value of the Arduino.
Are the FSR sensors connected to an analog input and GND ? Do you have a resistor between the analog input and 5V ? I assume you do. You need the resistors so that a nice pressing force to the board results somewhere in the middle of the ADC range.
Pseudo code:
setup()

  Measure both ADC values (or a number of values and use the average)
  Store them as offsets in a global variable.

loop()

  Measure both ADC values, substract the offset.

  Translate the ADC values into force.
  The more force the higher the number should get.
  Any range is okay for now.
  They can be translated into Newton later.

  The total force is by adding the two forces.

  The position in percentage is the force of the right sensor
  divided by total force times 100.
  Then the position will be 0 for left sensor, 50 for middle
  and 100 for right sensor.

  If the total force is above threshold, then check the position.

  for example position -50 to 20 for left virtual button.
  for example position 30 to 70 for middle virtual button.
  for example positition 80 to 150 for right virtual button.

You can start by printing the forces to the serial monitor. Press the board and check if the numbers increase when pressing more.
Don't get confused when you print the position. It will be very noisy when no force to the board is applied. It should be valid when the total force is above the threshold.
For the position I allow a large error of 50 percent left of the left sensor and right of the right sensor. It depends on the mechanical construction and the rest of the code if that makes sense.
Print the results to the serial monitor.
If that is working well, then you have to detect a single press.
Let's assume that as soon as the threshold is reached, a press to a virtual button is accepted. Let's not wait until the peak of the force is reached.
The State Change Detection example can be used to create a single event for pressing the virtual button.
Any jitter or noise (for example a single press to the board results into two events for the virtual button) can be solved by averaging or filtering in software. I think that it will be needed.
I'm not sure if all of this is okay. I hope that someone else will look into it as well.

Thank you very much! This makes sense to me and I agree that this is the best way that it should be done. I will both waiting for the peak of the force (and take the decision after state change) and calculating on each round of the loop and see what works faster. I do not mind taking the decision afterwards, as I am more interested in the system being as fast as possible in detecting state changes.

If you make a variable active when a virtual key is pressed (as long as it is being pressed), then that variable is the same as the digitalRead of the State-Change-Detection example. I see no advantage to wait for the peak. The virtual key press is already accepted when it was above the threshold, it does not matter what follows (small peak or big peak). It has to drop below the threshold to be able to accept a new virtual key press. The State-Change-Detection is for one key, you have three virtual buttons and only one button can be pressed at a time, so there is a little difference.

My assumption is that force will only be applied on one spot at a time and then released (no sliding or whatsoever). So, I am treating as a change of state when any of the FSRs is measuring something (above the calibration threshold). By checking on every round if some threshold is exceeded, I have to sum two numbers and then run an if statement. If I check afterwards, I just store two numbers on each loop and afterwards run the if statement once.

I prefer clean programming above getting into troubles. It's no problem to check everything thousands times per second. You might need to slow the sampling down to about 100 times per second with millis. That's just optimizations for later.

I totally agree in general, but in this case I am trying to get accuracy as close to the millisecond as possible, because I also care about exactly for how long a button was pressed. Based on your help (especially from this answer) I have managed to significantly reduce the complexity of the code already.

Is there a more accurate way to detect where force is being applied?

normalize your measurements vs. the static values of those strain gauge readings obtained during calibration.


text:
Detecting the light source location using multiple photoresistors
I am not an expert yet, so please forgive any possibly wrong terminology that I may have used.
I am planning to place 6 light sensors in 1 meter (or maybe more) distance from one another, like this (sorry about the bad schematic, I am not an expert, but I hope it makes sense):

simulate this circuit – Schematic created using CircuitLab
I am going to place them in a relatively dark room. My goal is, when I am pointing a flash light towards them to be able to tell which sensor is measuring the highest values (where the light is coming from), and for how long (in milliseconds).
I know how to do the connections and measure values. My questions are two:

Which is the most efficient way to detect which of the 4 sensors is recording the higher values? I am assuming I have to compare the values that they are recording. However, I think that if in each loop I sort the captured values, the process might become heavy. I guess I could minimise the comparisons, since for example if LDR1's value is higher than LDR2 and LDR3, I can assume that the light source is cannot be pointing towards LDR6 for example. However, I am thinking that maybe there could be an even more efficient way to detect that (not necessarily in software).
Since the room will not be completely dark, the analog pins will record some values even when I am not pointing the flash light towards them. Is there a way to filter that out? I have come across calibration (https://www.arduino.cc/en/tutorial/calibration), but I am not sure whether this is the optimal solution. Please take into account that the light source might not be very strong (but its light will definitely be brighter than the room light).

The answer from Curt Sampson provides several good design considerations, plus the quite-reasonable suggestion that you run some experiments to characterize your LDRs and their placements.
Note that if you want to know which sensor has the highest reading, a simple find-maximum-value loop will do that, without any sorting:
int maxR = reading[1], maxS=1;
for (byte i=2; i <= nSensors; ++i) {
  if (reading[i] > maxR) {
    maxR = reading[i];
    maxS = i;
  }
}
// Now we know sensor maxS has max reading, maxR

The code above follows the 1–6 numbering scheme given in the question, and assumes that reading[i] stands for the reading from sensor i.
Code below, however, numbers the sensors and their readings from 0 to 5 instead of from 1 to 6, to allow simpler conditions in for loops.  From a programming standpoint, it makes sense to call the first sensor 0 if its data is stored in cell 0.

Finding x, y direction of the light
Assumptions behind the following code are that higher readings indicate more light, and that if necessary some background-lighting calibration has been done, and that background lighting has already been subtracted from readings data.  We also assume that maximum readings are less than (2¹⁵)/N, where N is number of sensors.
The point of the following code is to set two variables, x and y, that represent the relative location of a light source.  For example, if x and y are both positive, the light is above and to the right of the top right LDR.  If  x is negative and  y is near zero, the light is to the left of the middle-left LDR.  If knowing the signs of x and y is adequate for your purpose, then there's no need to do more arithmetic than shown.  On the other hand, if you want to compute some sort of angle, you can use atan2(y, x) to compute the direction of the light, in radians.
int reading[nSensors];
const int xdir[] = { -1, 1, -1, 1, -1,  1}; // x-direction sensor weights
const int ydir[] = {  1, 1,  0, 0, -1, -1}; // y-direction sensor weights
int x=0, y=0;
for (byte i=0; i < nSensors; ++i) {
  x += xdir[i] * reading[i];
  y += ydir[i] * reading[i];
}

Edit 1: Tracking the time a light is on
Issues with light-timing include what levels to start or stop timing at; necessary resolution (milliseconds? minutes?); necessary range (eg, is what happened a minute ago relevant); and when to reset accumulated time data.  It may be simplest to track the on times of all the sensors at the same time, then select one of the times or combine some times.  Do you want the largest time, the newest time, the newest large time, or the time corresponding to the largest light?
For example, the code below tracks light levels that remain high long enough to register, in smoothed averages, as above some threshold.  At intervals, current indications are rotated into bit maps that track the last 16 on-off levels for each LDR, and counts of number-of-ons are updated too.
// Initialization ...
uint16_t expAvg[nSensors]={0};  // Exponential averages over time
uint16_t bitMaps[nSensors]={0}; // Track each sensor's last 16 on-off levels
byte onCounts[nSensors]={0};    // Number of recent times sensor avg > threshold
unsigned long prevMilli=millis();
const int markInterval=50;   // ms interval for recording light levels
const int onThreshold=547*16; // Some light-is-on threshold

// In each pass of loop() ...
for (byte i=0; i < nSensors; ++i)
  expAvg[i] = reading[i] + 15*expAvg[i]; // exponential averaging with 1:16 weight

// In loop(), at intervals ...
if (millis()-prevMilli >=  markInterval) {
  prevMilli = millis();
  for (byte i=0; i < nSensors; ++i) {
    onCounts[i] += (expAvg[i] > onThreshold) - (!(bitMaps[i] & 0x8000));
    bitMaps[i] = (bitMaps[i]<<1) | (expAvg[i] > onThreshold);
  }
}

This will most likely do it! I really like the second solution. However, in order to calibrate it, is the method that I posted in my question likely to work? I need to measure for how long the flash light was on (in milliseconds), so I guess I will need either some calibration or a high pass filter.

@jackgu1988, see edit - although I guess I didn't address the ms on but instead fraction of on time in last .8 seconds (with constants shown)

This will probably do it! Thank you very much. For the moment I am waiting for a couple more sensors to be delivered. I'll report back when I test it.

There's only one ADC (analog to digital converter) on the ATmega328P; the analog input pins are multiplexed so that you choose which particular pin you want to sample. (See Section 28 of the datasheet for details.)
Taking a sample takes time; how long depends on how you do it. The analogRead() function is documented to take about 100 microseconds. Reading your six sensors is thus going to take at least 600 microseconds.
The sample returned is a 10-bit integer and so easily fits into two bytes, or even one byte if you drop the low two bits (which is reasonable for some applications, and probably yours, because they're likely to be more sample error than data anyway). Whether you do that or not, however, you're left with a very tiny amount of data to sort from one set of reads: just six values.
The Arduino runs the ATmega328P at 16 MHz, and most instructions run in single clock, giving you performance approaching 16 instructions per microsecond.
We could work out, based on the type of sort you use, the number of comparisons and swaps you're likely to make in the average and worst cases, but there's no point to that on such a tiny data set because the total time your routine takes is almost certainly going to be dominated by other overhead. So I'm just going to say that the sort will be something on the order of a hundred clock cycles.
That means your sort would add around 6 or 7 microseconds to your 600 microsecond total read time you've got so far, or 1%; you don't have to worry about it at all.
You'll actually spend a lot more time doing other sorts of processing. But it's a pretty fast CPU, as we've seen above, so there's a good chance if you're careful that your loop will still be dominated by the sampling time of the ADC for each of the sensors.
My suggestion is to go ahead and write the thing but record actual timings in your loop for the sampling and the processing. After you've played around with it for a bit you'll have a better idea of the particular costs for each for your particular application and then you can worry about whether or not you need optimization. I suspect you won't.
Regarding the "filtering," that's going to be an integral part of your processing algorithm because the "room light" values can be vastly different from time to time depending on the current lighting in the room. I don't think you want to "filter" anything out, but instead compare the values of all of the photoresistors; at a first guess, similar values from all of them would mean that there's no flashlight and some giving you significantly higher values would indicate that there is one. But my second guess is that a) you'll want your sensors a lot further apart than 1 meter (perhaps in the corners of the room) and b) it's not going to be so simple; you're likely to see fairly different values from the sensors even in a quiescent room. This is where you get to play and experiment to find out how this really works!
It also occurs to me that putting the photoresistors several meters away from the ADC is going to involve a lot of wire, which adds resistance, capacitance and noise, all of which are going to interfere with your measurements. There's not a lot you can do about this; you can play a bit with measuring known-value resistors at the ends of the wires to see how bad the problem is, but if it's terrible you'd probably need to use a separate Arduino for each sensor and have them communicating back to a central place for analysis.

Thank you! This information is very helpful. I was also thinking that maybe I can wire the resistors in a way that I can minimise the amount of checks. For example, having 3 instead of 6 analog inputs (each input representing 2 sensors) and depending on the returned values to be able to tell which sensor is receiving more light.

You could try to come up with clever ways to wire the photoresistors in serial and/or parallel to reduce the number of samples you need to take, but that's a pretty darn tricky thing to do. I would probably first start with adding more sensors and, if the loop is too slow due to the length of time it takes to sample all of them, figure out an algorithm to sample only some of the sensors and leave others alone based on what's been sampled recently. But first I'd get something really basic working.

authors: Сергей Сергеевич