text:
Read nested array item from PROGMEM
I have a 2D array of uint16_t arrays (IR Remote Codes). Due to the size of this data in RAM I'm having all kinds of trouble when my array is larger than one code. Thus, I have been trying to move this whole structure into PROGMEM. Following various tutorials and this solution, I have come up with the code below for reading a single element out of the array and into a variable that I can feed to the IRLIB2 IRSendRaw function.
The variable that holds the code that is read out of PROGMEM is still huge and causing some problems. Is there a more direct way like a python list comprehension to access an arbitrary element and send it directly to the IRSender?
This PROGMEM_readAnything library looks promising, but I don't have enough C++ fu to make the mental leap to implement it in my code.
#include <IRLibSendBase.h>    //We need the base code
#include <IRLib_HashRaw.h>    //Only use raw sender

#define RAW_DATA_LEN 68
const uint16_t sources[3][RAW_DATA_LEN] PROGMEM =
  {{8550, 4306, 530, 1606, 530, 566, 502, 1610, //power on/off
  530, 566, 502, 574, 506, 1630, 506, 566,
  506, 1630, 506, 566, 502, 1610, 530, 566,
  502, 1634, 506, 1606, 530, 570, 498, 1634,
  506, 570, 510, 562, 506, 566, 502, 1634,
  506, 1606, 530, 1610, 530, 562, 538, 538,
  530, 542, 538, 1598, 538, 1570, 558, 542,
  538, 538, 530, 542, 538, 1598, 530, 1578,
  558, 1578, 562, 1000},

  {8546, 4310, 558, 1578, 562, 538, 498, 1638,  //source CD
  530, 542, 506, 570, 502, 1634, 502, 570,
  498, 1638, 534, 538, 498, 1638, 530, 542,
  506, 1606, 554, 1582, 558, 538, 510, 1602,
  554, 546, 506, 566, 502, 570, 510, 1602,
  554, 1582, 558, 538, 510, 566, 502, 1606,
  554, 546, 502, 1610, 558, 1574, 554, 546,
  502, 570, 510, 1602, 526, 1610, 526, 574,
  506, 1602, 526, 1000},

  {8550, 4306, 530, 1606, 534, 566, 502, 1606,  //source CDR
  534, 566, 502, 570, 510, 1602, 526, 570,
  510, 1602, 534, 566, 502, 1606, 534, 566,
  506, 1602, 530, 1606, 534, 566, 502, 1610,
  530, 570, 498, 574, 506, 566, 502, 570,
  510, 1602, 526, 570, 510, 566, 502, 570,
  510, 1602, 526, 1610, 526, 1606, 534, 1602,
  534, 566, 502, 1610, 530, 1602, 534, 1602,
  526, 574, 506, 1000}};

//Create a sender
IRsendRaw mySender;

//Read out one code into a variable and send to the IR transmitter
uint16_t myCode[RAW_DATA_LEN];
for (int i = 0; i < RAW_DATA_LEN; i++) {
   myCode[i] = pgm_read_word_near(sources[0] + i);
}
mySender.send(myCode,RAW_DATA_LEN,36);

you can't put a multidimensional array into PROGMEM. see "Array of Strings" in https://www.arduino.cc/reference/en/language/variables/utilities/progmem/

@Juraj Sure you can. Strings are a special case though. There's no difference in memory between a 2D array, and a single large 1D array.

It is not problem to fill the rest of the flash memory of an arduino uno with progmem data. For an arduino mega 2560 it is better te keep the progmem data section below the 64k boundery. You copy the data into a buffer of 68 uint16_t, that is 136 bytes. Is that the problem? The arduino uno has 2kbyte ram. What else is using your sram?

I had problems to read a two-dimensional array from PROGMEM. now I know. for one dimension the argument to pgm_read is arr + i. it is a pointer to the element. and for two dimensions the argument to pgm_read must be arr[i] + j

The library, as it stands, doesn't support direct sending from PROGMEM.  However it's not too hard to get around that - if your C++ is up to it.
The IRsendRaw class is a child class that extends the IRsendBase with a single function.  You just need to do the same thing to create a new class that implements the functions in a way that can read from PROGMEM.
This is the original:
class IRsendRaw: public virtual IRsendBase {
  public:
    void send(uint16_t *buf, uint8_t len, uint8_t khz) {
      enableIROut(khz);
      for (uint8_t i = 0; i < len; i++) {
        if (i & 1) {
          space(buf[i]);
        }
        else {
          mark(buf[i]);
        }
      }
      space(0); // Just to be sure
    }
};

You just need to make your own one of those in your sketch, called something different, and which uses the progmem functions instead of accessing buf[i]:
class IRsendRawPGM: public virtual IRsendBase {
  public:
    void send(const uint16_t *buf, uint8_t len, uint8_t khz) {
      enableIROut(khz);
      for (uint8_t i = 0; i < len; i++) {
        if (i & 1) {
          space(pgm_read_word_near(buf + i));
        }
        else {
          mark(pgm_read_word_near(buf + i));
        }
      }
      space(0); // Just to be sure
    }
};

Now you can define your sender object as:
IRsendRawPGM mySender;

And send the data directly:
mySender.send(sources[0], RAW_DATA_LEN, 36);

(Note: this code is untested).


text:
Controlling multiple Screens using IR
I'm a software Engineer, and recently I’ve been working on a new Software
Part of this Software is to be able to turn off and on multiple TV screens using timers in the software
First idea came to my mind is using relays with Arduino and connecting in to computer using Bluetooth chip but not all screens turns on once the power cable is plugged in
So, I tried IR CIRCUIT using NODEMCU and IR LEDS. And it worked but not perfectly,
The way I did this is by sending a combination of IR codes to screen to make a sleep timer so it will turn off the screen after some time.
But there was a delay when sending IR codes, and sometimes the code won’t be sent
This is the circuit I used (in addition to more  IR LEDS)

I just want to know why the codes are not sent every time
And if there is any better way to control the screens from computer?

Can you show us the code you have written?

There are ready-made items for this purpose, such as the iTach Flex with (triple) IR emitter. You may consider using something off-the-shelf to save time and to avoid messing around/frustration.

source: Stack Exchange

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

sort: votes


text:
Limitations of connecting to many Arduinos via Ethernet?
I'm planning a project where I need to control a lot of Arduino Unos from a single PC. I'll need to send commands to the Arduinos and receive responses, as well as have the ability to update each Arduino from the PC, preferably without Arduino IDE at some point. Connecting via USB is out of the question, as I have already tried this and got miserable results, in part because of the number of Arduinos I need to control. So now I'm considering connecting the PC to an ethernet switch and then from there connect each Arduino with an ethernet shield.
Which brings me to my questions. Are there any limitations I should be aware of, if I want to pursue this setup? Will controllings tens, or even a hundred, Arduinos at the same time be a problem? How about stuff like updating a specific Arduino on the network?
My current working prototype uses a Windows PC that connects to one of multiple Raspberry Pis, which then in turn communicates with a number of Arduinos via I2C, and updates them via USB. But if I'm able to do all this directly from the main PC to the Arduinos via Ethernet, that would be fantastic.
Thanks for reading, looking forward to any answers.

One Arduino, or a million Arduinos, it makes no difference.

With a lot of devices on the ethernet, you may want to consider a private wire that is dedicated to those devices.  That is, a second ethernet port or a VLAN off a capable switch.
As the number of devices increases, and the number of simultaneous talkers increases, you will start getting contention.  Chances are a modern switch can handle this to some extent, but you were not clear on how much traffic you are planning on sending, or how often each device talks, or if it is centrally coordinated (aka "polled") or just speaking whenever.

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


text:
ESP8266: Multiple analog inputs using software
Is there a way to get at least three analog inputs to the esp8266 (without a multiplexer)?
Each digital or analog pin on an Arduino can be configured as digital or "analog" (e.g., PWM software).
Here is a way to squeeze one additional analog input pin: hackaday.io/project/8435-2-analog-inputs-for-esp8266-without-multiplexer
Any ideas or software?

it depends on what you're feeding it. if it can be crude, you might be able to use mosfets.

1) nope it's not possible "in a straightforward way". you should use analog muxes.
2) the statement "Each digital or analog pin on an Arduino can be configured as digital or "analog" (e.g., PWM software)." means for PWM or the so called "analog output". not intended the ADC unit.
3) the link provided uses software tricks to measure 2 signals in a muxed fashion. it's up to purpose.
workarounds :
1) use CD4066 CMOS bilateral switch. it works with analog signals.
2) use GPIOs to supply voltage to measurement units. like the link you provided. it works for passives like photoresistors and for devices like LM35 temp sensor. but can't be used for devices like 3 channels analog-out accelerometers.

Um, for (2), I put it in quotes for that very reason.


text:
esp8266 advertising AP even when flashed with custom firmware
I bought several ESP8266 boards from an Amazon seller, and I have flashed them with custom firmware.  This firmware basically sends telemetry to an MQTT server, and has some OTA functionality to self-update from a web server I run.
I flashed them from the Arduino IDE initially, although have also since updated them OTA.
These devices properly connect to the AP I have defined, get an address, and send their mqtt messages.  However, they ALSO advertise an SSID that is FaryLink_XXXXXX where the XXXXXX relates to the MAC.
How is this possible, and how should I wipe their little brains fully?

WiFi.mode(WIFI_STA);

Ahh.  So obvious when you know what it is.  Of course, one wonders why it chooses that SSID when I can't find it in the source, or binary, anywhere...

please read the answer. setting mode only turns off the AP in setup(). it will start at boot

The Espressif ESP8266 SDK is part of every Arduino sketch for the ESP8266. The SDK handles the WiFi and other basic functions of the chip.
If enabled, the SDK remembers WiFi STA and SoftAP settings and start to connect right after boot. At default it is enabled. In Arduino sketch this is controlled by WiFi.persistent(bool) and of course this setting is stored too.
To clear SoftAP settings, call WiFi.softAPdisconnect(). To only turn off SoftAP, use WiFi.setMode(WIFI_STA).


text:
Brushed ESC won't move slowly
I'm trying to control the brushed motor in a Traxxas Slash RC car with the built-in XL5 ESC using the Servo library on Arduino. I previously had success controlling this car with a Pololu Micro Maestro, but it died on me, and so, while waiting for a replacement to arrive, I thought I'd give a more manual approach a try.
The problem is, the motor moves way too fast. My understanding is that, for this ESC (which allows for reverse driving), 90 degrees / 1500 ms should be the neutral point, with anything above this leading to progressively faster forward speed; and, below, reverse.
But, while it seems there is some speed modulation, the motor just abruptly begins with a very high speed at an angle (Serial.write(95)) of 95 or so, and then gets even faster from there.
A minimal version of my code is pasted below; my circuit has the signal pins of the steering and ESC servo connectors (white wires) attached to pins 2 and 9, respectively on a Pro Micro, their two 5V pins connected to each other (since the ESC supplies its own 5V), and their grounds connected to the Arduino's ground pins.
While it's possible that I need a special arming sequence to get this ESC to work properly (I do operate in the three-blink "training" mode, which is supposed to be slower), I would expect that problem to manifest as no motion at all, not too much motion.
I've tried powering the ESC with the original 9.1V battery (nominal 8.4V), and with a 8.4V regulated supply attached to a ~15V battery.
What could I be doing wrong here?
#include <Servo.h>

Servo throttle;

void setup(){

    Serial.begin(115200);

    throttle.attach(9);
    // throttle.write(91);
    // delay(300);

    int first = 90;
    for(int angle=first; angle < first+20; angle++) {
        Serial.println(angle);
        throttle.write(angle);
        delay(10);
    }

    // This doesn't work any better.
    // int first = 1500;
    // for(int us=first; us < first+10; us++) {
    //     Serial.println(us);
    //     throttle.writeMicroseconds(us);
    //     delay(50);
    // }

    throttle.write(90);
}

void loop() {
}

according to the documentation, you have to "teach" it the neutral, forward and reverse signals ........... your question has nothing to do with the Arduino

@jsotola After some more digging, you appear to be correct. After going through the   limit-setting sequence and also disabling or enabling the low-voltage detection (depending on power source), it works. However, I didn't have to do this with the Pololu driver, hence my original confusion. If you have a suggestion for where to move this question, I'm open to that. But I'll write an answer myself.

i  am unsure if the question fits anywhere in stackexchange , because it appears to be a device usage question

@jsotola So should I delete it?

just accept your own answer

Per @jsotola 's suggestion, I looked more closely at the manual (see the section "XK-5 Setup Programming"):

XL-5 Setup Programming (Calibrating your ESC and transmitter)
Read
through all of the programming steps before you begin. If you get lost
during programming or receive unexpected results, simply unplug the
battery, wait a few seconds, plug the battery pack in, and start over.

Disconnect one of the motor wires between the XL-5 and the motor. This is a precaution to prevent runaway when the speed control is
turned on before it is programmed.

Connect a fully charged battery pack to the XL-5.

Turn on the transmitter (with the throttle at neutral).

Press and hold the EZ-Set button (A). The LED will first turn green and then red. Release the button.

When the LED blinks RED ONCE, pull the throttle trigger to the full throttle position and hold it there (B).

When the LED blinks RED TWICE, push the throttle trigger to the full reverse and hold it there (C).

When the LED blinks GREEN ONCE, programming is complete. The LED will then shine green or red (depending on LowVoltage Detection
setting), indicating the XL-5 is on and at neutral (D).

I wrote a short program to send specified servo angles in [0, 180] interactively. The manual says to apply "full throttle" and "full reverse", but I wasn't exactly sure what these translated to in terms of servo angle/pulse width milliseconds. I gather that these are often given as 45° and 135° (1.25 ms and 1.75 ms), respectively, but that setting the limits to [0, 180] during this training period also worked. It's valuable to get the full range, so I can get finer gradations in speed. Since I don't expect to ever reach full speed in my application, and will only use the near-90 part of the range, this will be particularly helpful.
I'm still perplexed about what caused the original problem--the Pololu servo controller never needed this tuning process. Perhaps the limits were set to [45, 135], and I mistakenly sent 180, which put the ESC into some state not described in the manual. And I don't know whether I'll need to repeat this in the future, or
whether my new [0, 180] limits will prevent the above mistake from being a problem. For that matter, I don't know how non-volatile the non-volatile memory is on the ESC in which these limits are stored. Does it require periodic battery power to refresh?
Finally, while it might be even more particular to the XL-5 ESC and my power supply setup, another useful note is that the low-voltage detection mode might prevent movement independent of the setup process.


text:
Invoke a method in the main sketch from within a library
I need to use a specific library that issues error messages in the form of String texts. The library uses the Serial.println() function to send the messages to the Arduino IDE's serial monitor.
The problem is that I have the Serial lines from the Arduino linked to another device, therefore I can't use the Serial Monitor to see the messages. I have a method in the Main Arduino sketch that sends any String text msg generated to another device using Udp commands (wireless). This device is connected to a serial monitor unit.
My question is: How can I invoke the Udp method inside the main sketch of the Arduino program from within the aforementioned library? This would help me to convert the Serial.print() text messages from the library directly into Udp messages to be able to visualize them.
The Udp method I'm using is declared as void UdpSend(String msg) in the Arduino sketch. I'd like to use something similar inside the library to wrap the text msg and send it over to the method on the main program.
Any example or link to get this information will help.
EDIT1:
@Majenko,

On the target library, added:  void libUdpSend(const char *libMsg);
On the sketch, I added this method (Udp comm handler):
 void libUdpSend(const char *libMsg)
 {
   Udp.begin(localPort);
   Udp.beginPacket(Udp.remoteIP(), localPort);
   Udp.write(libMsg);
   Udp.endPacket();
   delay(40);
 }

Added this line on the library (right after the declaration on 1.) to test through the remote serial interface:
libUdpSend("String wrapper has been implemented SUCCESSFULLY!");

When trying to compile linking the library, the following exception occurrs:

error: expected constructor, destructor, or type conversion before '(' token
  libUdpSend("String wrapper has been implemented SUCCESSFULLY!");

I then switched to String as this is the type I want to wrap, Same steps:

On the target library, added:  void libUdpSend(String *libMsg);
On the sketch:
void libUdpSend(String *libMsg)
{
  Udp.begin(localPort);
  Udp.beginPacket(Udp.remoteIP(), localPort);
  Udp.write(libMsg.c_str());
  Udp.endPacket();
  delay(40);
}

Now the error message says:

request for member 'c_str' in 'libMsg', which is of pointer type 'String*' (maybe you meant to use '->' ?)

I am not an expert on pointers so I'd need some help on how to assign the pointer as argument on the UdpWrite function using the '->' command proposed by the compliler?
Let me know your thoughts on this.

I have a simple library for debug messages over Telnet https://github.com/jandrassy/TelnetStream . it creates an instance which can be used instead of Serial in any source file which includes TelnetStream.h

send a bug report to the lib creators and say that hardcoding serial for debug output is the wrong thing to do.

The connection between a sketch and a library is not one-way as many suppose.  Things can go quite happily in both directions.
What you are proposing is something I do quite often when developing a library and I need to get some debugging information out of the library. Yes, it's possible to directly use Serial in the library, but that's something I don't like, and often isn't appropriate anyway, as in your situation.
However, doing it the way you propose (and I use) is actually very simple.
You just make your function in your sketch and tell the library to use it.
For example, in your sketch:
void debug(const char *msg) {
    Serial3.println(msg);
}

And in the library add the line:
void debug(const char *msg);

Then at any point in the same file (or translation unit) you can use
debug("I am here");

That is assuming that the file that you are using it in is a C++ file (.cpp).  If it's a C file (.c) then you have to treat things very slightly differently.  You see, C++ makes a mess of the function names (even vanilla functions like that) which means they can't be seen by C files.  So you have to tell the compiler "I'd like this to be usable in a C file, please".
Which you do with a special "extern" wrapper around your function:
extern "C" {
    void debug(const char *msg) {
        Serial3.println(msg);
    }
}

And then debug() is usable in a C file in the same way as above.
However now it won't work in a C++ file...  (round and round we go...)
Simple to fix: add the extern "C" to the prototype in the C++ file:
extern "C" {
    void debug(const char *msg);
}

If you want to include your "extern" in a header file that could be included into either C or C++ files it's very common to use a construct such as:
#if defined(__cplusplus)
extern "C" {
#endif

void debug(const char *msg);

#if defined(__cplusplus)
}
#endif

That will add the extern "C" wrapper for C++ files (identified by the presence of the macro __cplusplus) but omit it for C files.
I have used "const char *" as the parameter for this example, but you can choose whatever parameters are appropriate for your usage.

@ Majenko - thx for your answer. I implemented the solution as you proposed it but the compiler is throwing an error generated on the modified library.
error: expected constructor, destructor, or type conversion before '(' token

 libUdpSend("String wrapper has been implemented SUCCESSFULLY!");

I tried to put the code here but the comment section has very limited size. I might send you a bit more of the info via email perhaps?.  Any ideas on something in the code I might be missing?  The target library is .cpp btw, so no extern C structure needed.
Thanks -EZ

Just edit your question and add it there.

See "EDIT 1" in the original question. Thanks!


text:
Linear Actuator Arduino Control
Update:
Here is my first try based on the code I found and it did not work.
The first time I uploaded it, it move to the "current positional value". But did not do the void loop part. Just holds the positions.
Thanks.
    //Includes
    #include <Servo.h>

    //Defines
    #define LINEAR_1_100PIN 11        //Linear Actuator Digital Pin
    #define LINEAR_2_100PIN 6      //Linear Actuator Digital Pin

    String msg;

    //max/min pulse values in microseconds for the linear actuators
    #define LINEAR_1_100_MIN      1050  //
    #define LINEAR_1_100_MAX      2000 //
    #define LINEAR_2_100_MIN  1050     //
    #define LINEAR_2_100_MAX  2000    //

    Servo LINEAR_1_100, LINEAR_2_100;  // create servo objects to control the linear actuators
    //int knobValue, sliderValue;  //variables to hold the last reading from the analog pins

    int linear100Value_1 = 1051;   //current positional value being sent to the linear actuator.
    int linear100Value_2 = 1051;  //current positional value being sent to the linear actuator.

    int speed = 10;

    void setup()
    {
      //initialize servos
      LINEAR_1_100.attach(LINEAR_1_100PIN, LINEAR_1_100_MIN, LINEAR_1_100_MAX);      // attaches/activates the linear actuator as a servo object
      LINEAR_2_100.attach(LINEAR_2_100PIN, LINEAR_2_100_MIN, LINEAR_2_100_MAX);  // attaches/activates the linear actuator as a servo object

      //Analog pins do not need to be initialized

      //use the writeMicroseconds to set the linear actuators to their default positions
      LINEAR_1_100.writeMicroseconds(linear100Value_1);
      LINEAR_2_100.writeMicroseconds(linear100Value_2);
    }

    void loop()
    {
   LINEAR_1_100.write(90);
   delay(1000);
   LINEAR_1_100.write(0);
   delay(1000);
   LINEAR_2_100.write(90);
   delay(1000);
   LINEAR_2_100.write(0);
   delay(1000);
    }

Old Question:
I am trying to make the code described in this tutorial:
http://learn.robotgeek.com/demo-code/118-arduino-linear-actuator-tutorial-analog-direct-control-of-small-linear-actuator.html
https://github.com/robotgeek/firgelliDirectControl/blob/master/firgelliDirectControl/firgelliDirectControl.ino
work with PWM from an Arduino, without the additional board.
So far the Arduino Examples>Servo>Sweep works as I would like to achieve it (delay changed to 30 ms) but very slowly and it does not seem to just go 180 steps out wait 30 ms and 180 steps in again. It sometimes moves twice in one direction. If I change the steps from 1 to 5 the servo does not move anymore (I expected it to go faster).
With the code above I understand I can control the servo with a Knob or Slider, but I would like to understand how I can control this Linear Actuator Servo with PWM from an Arduino PMW Pin (e.g. 11) and change the speed. Finally I would like to make the Servo consistently go x amount of steps out, wait for x ms and the same amount back in again.
Most importantly I would like to make sure it always ends at position 0, and that it does not accumulate errors.
Thank you for any help.

About being sure about returning to position 0 this is not a problem. You are not actually controlling anything with your PWM. You are only sending a signal to the IC inside the servo to tell it where to move the actuator. That IC knows in what position the actuator is located in any moment, usually using some kind of encoder (it's called a closed loop system) and it will make sure that it will move back exactly to 0 whenever you tell it to move to 0.
If you want to make things clearer you can use write method to send value to the servo.
void Servo::write(int value)
{
  if(value < MIN_PULSE_WIDTH)
  {  // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
    if(value < 0) value = 0;
    if(value > 180) value = 180;
    value = map(value, 0, 180, SERVO_MIN(),  SERVO_MAX());
  }
  this->writeMicroseconds(value);
}

Any value from 0 to 180 will set a position to which servo will move from MIN to MAX possible position. No need for manual calculation of microseconds.
You have to remember that PWM works constantly. If you write for example LINEAR_1_100.writeMicroseconds(1051) this code will set some timers, counters and prescalers inside the ATmega chip on the Arduino board and the value of PWM will be sent constantly until you change it.
So the delay(2000) doesn't stop the PWM signal, and servo remains in constant position.
The issue is here:
LINEAR_1_100.writeMicroseconds(1800);
LINEAR_1_100.writeMicroseconds(1051);

You set the value of 1800 and then immediatelly set value of 1051, but the ATmega didn't even have the time to send the first value to the servo.
Add a delay(1000) after every call of write or writeMicroseconds to allow the PWM to actually be sent to the servo.

Thank you for the clarification. But how can I integrate this into my code ? Do I just call void servo from void loop ? Do I have to define the MIN_PULSE_WIDTH, SERVO_MIN, MAX ? This sounds like the solution, but how can I change my code. Also the :: seems like C++ code to me and I am not as frequent with this. Thanks again.

Sorry for confusing you. You already defined those values when you created/attached LINEAR_1_100 and LINEAR_2_100 the code is taken from the Servo.h library. Don't look to much into it. All you need to do is write LINEAR_1_100.write(90) in the code and add delay(1000) after it to give Arduino some time to actually send the PWM value to the servo.

I changed my code (see above), but it still doesn't move. I just hear it ticking, but no movement.

Are you by any chance powering the servo directly from the Arduino that's connected to your PC? I simulated your code in Tinkercad and it works fine with virtual normal servos. Maybe your linear servos draw to much current and protection circuitry (in laptop) kicks in and disable power. Power them from external 5V source (not through Arduino because it can also burn)

Ok, thanks for the feedback. I don't but maybe the MA is not enough.


text:
Using a 48 characters char[] for PROGMEM
I am trying to create a charliplexed display of 6x8 LEDS using a Arduino Nano with the ATMega328p chip. Because of the limited storage I am trying to use PROGMEM. I did my research and found some usefull examples, but when I try to create a char[] of 48 charaters (0 = LED off, 1 = LED on), the monitor only shows a line filled with squares. Im not sure what this indicates, but when I limit the amount of characters to lets say 10, it works as expected. I made sure the buffer size matches the amount of max characters. What am I missing here?
I know it would be easier to use a multiplexer, but I prefer to find a working solution using progmem since this is a assignment where I would like to have my students find a solution to store the "LED data" for the whole alphabet without using external memory or a multiplexer chip. If this simply is not possible, I will look into using other hardware.
TIA!
This is the code I am using:
#include <avr/pgmspace.h>
const char string_0[] PROGMEM = "000000000000000000000000000000000000000000000000"; // "String 0" etc are strings to store - change to suit.
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";

// Then set up a table to refer to your strings.

const char *const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5};

char buffer[48];  // make sure this is large enough for the largest string it must hold

void setup() {
  Serial.begin(9600);
  while (!Serial);  // wait for serial port to connect. Needed for native USB
  Serial.println("OK");
}

void loop() {
  /* Using the string table in program memory requires the use of special functions to retrieve the data.
     The strcpy_P function copies a string from program space to a string in RAM ("buffer").
     Make sure your receiving string in RAM  is large enough to hold whatever
     you are retrieving from program space. */

  for (int i = 0; i < 6; i++) {
    strcpy_P(buffer, (char *)pgm_read_word(&(string_table[i])));  // Necessary casts and dereferencing, just copy.
    Serial.println(buffer);
    delay(500);

do you have place for terminating zero in buffer?

Obviously not. char buffer[49]; will fix that issue. Also I wouldn't bother to place string_table in PROGMEM if you are not desperate to save 12 bytes of RAM.

Yep, that was the issue... Since I never worded with progmem before, I didnt know I needed to use an extra index for it. Thanks!
Eventually I will be adding every letter of the alphabet, including capitals and non capitals. And maybe if there is some more space, some symbols haha.

You could try strlcpy_P(buffer, ...pgm..., sizeof(buffer)). That is a extra 'l' as in Lima.


text:
ESP8266 /ESP12F use flash button as input without using loop()
I couldn't find a proper answer anywhere on internet.
I want to use the FLASH button as input in the setup() function and do not use the loop() with deepsleep mode (this part comes later).
I tried demos wherein the button events are sometimes failed to be captured. How can I make it 100% sure to get detected as soon as I press reset or along with reset? Because there is a mismatch in the time when reset is clicked and the flash button press gets detected.

you want to read in setup if the button is pressed? pinMode(D3, INPUT_PULLUP); if (digitalRead(D3) == LOW) ...

you can't read buttons while resetting, can you elaborate on the goal a bit more?


text:
Arduino Uno 3.3V pin to GND short how to fix
Hi I am new to the Arduino world. I was playing around with my Arduino UNO making LEDs go on and off in a sequence. Then I connected a motor to the N.0 pins but found it doesn't work so I plugged it doesn't work so I plugged it in 3.3V pin and it worked. I tried to reverse the connections but the one cable slipped and it connected to the metal shielding of the motor now it is not working when plugging it in USB it. Power LED just flashes red and turns off emediatly. Reset button doesn't seem to do annything. Is there a possible fix for this.

There is, but it would probably cost you more than the cost of a new counterfeit Uno from AliExpress.

First you need to identify what component is what, and then work out which has been destroyed by your short circuit (probably the 3.3V regulator, whichever component that is). Then identify the component make and model, and buy a new one. Then replace it and hope. Since that is not an official Arduino UNO you are probably going to have problems identifying the components and their model numbers in order to get a replacement. Just ditch it and get a new one.

@Majenko I believe it is a "clone" and not a "counterfeit". A "counterfeit" would have the Arduino logo and would be sold as an "original" with fake box etc.

Tomaytos, tomahtos. It's a piece of cheap Chinese crap either way.

It was working fine so I really don't care about quality I just need a processing board for my project besides I am a begginer and not really worth it to invest in high quality expensive equipment I will break so thanks for suggesting AliExpress but is it trust worthy.


text:
Can't parse large json file
For a project I've to parse a big json file. Unfortunately it does not work as expected.
Here is the json file:
{
  "data1": "[encoded data, 4800 characters]",
  "data2": "[encoded data, 4800 characters]",
  "data3": "736",
  "data4": "266",
  "data5": "3211",
  "data6": "0"
}

I was able to successfully implement the whole thing on an ESP8266 with this code:
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>

// WiFi Parameters
const char* ssid = "SSID";
const char* password = "PASSWORD";

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);

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

void loop() {
  // Check WiFi Status
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;  //Object of class HTTPClient
    http.begin("http://jsonplaceholder.typicode.com/users/1");
    int httpCode = http.GET();
    //Check the returning code
    if (httpCode > 0) {
      // Parsing
      const size_t bufferSize = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(8) + 370;
      DynamicJsonBuffer jsonBuffer(bufferSize);
      JsonObject& root = jsonBuffer.parseObject(http.getString());

      const char* data1 = root["data1"];
      const char* data2 = root["data2"];
      const char* data3 = root["data3"];
      const char* data4 = root["data4"];
      const char* data5 = root["data5"];
      const char* data6 = root["data6"];

      Serial.print("data1:");
      Serial.println(data1);
      Serial.print("data2:");
      Serial.println(data2);
      Serial.print("data3:");
      Serial.println(data3);
      Serial.print("data4:");
      Serial.println(data4);
      Serial.print("data5:");
      Serial.println(data5);
      Serial.print("data6:");
      Serial.println(data6);
    }
    http.end();   //Close connection
  }
  delay(60000);
}

The ESP Code works perfect for me, but for my application I need an microcontroller with ethernet. So I bought an enc28j60 and a W5500 Board to migrate the ESP Code to the Arduino UNO.
The Code result is this:
#include <ArduinoJson.h>
#include <Ethernet.h>
#include <SPI.h>

void setup() {
  // Initialize Serial port
  Serial.begin(9600);
  while (!Serial) continue;

  // Initialize Ethernet library
  byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
  if (!Ethernet.begin(mac)) {
    Serial.println(F("Failed to configure Ethernet"));
    return;
  }
  delay(1000);

  Serial.println(F("Connecting..."));

  // Connect to HTTP server
  EthernetClient client;
  client.setTimeout(10000);
  if (!client.connect("192.168.178.5", 80)) {
    Serial.println(F("Connection failed"));
    return;
  }

  Serial.println(F("Connected!"));

  // Send HTTP request
  client.println(F("GET /test.json HTTP/1.0"));
  client.println(F("Host: arduinojson.org"));
  client.println(F("Connection: close"));
  if (client.println() == 0) {
    Serial.println(F("Failed to send request"));
    return;
  }

  // Check HTTP status
  char status[32] = {0};
  client.readBytesUntil('\r', status, sizeof(status));
  if (strcmp(status, "HTTP/1.1 200 OK") != 0) {
    Serial.print(F("Unexpected response: "));
    Serial.println(status);
    return;
  }

  // Skip HTTP headers
  char endOfHeaders[] = "\r\n\r\n";
  if (!client.find(endOfHeaders)) {
    Serial.println(F("Invalid response"));
    return;
  }

  // Allocate JsonBuffer
  // Use arduinojson.org/assistant to compute the capacity.
  const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60;
  DynamicJsonBuffer jsonBuffer(capacity);

  // Parse JSON object
  JsonObject& root = jsonBuffer.parseObject(client);
  if (!root.success()) {
    Serial.println(F("Parsing failed!"));
    return;
  }

  // Extract values
  Serial.println(F("Response:"));
  Serial.println(root["data1"].as<char*>());
  Serial.println(root["data2"].as<char*>());
  Serial.println(root["data3"].as<char*>());
  Serial.println(root["data4"].as<char*>());
  Serial.println(root["data5"].as<char*>());
  Serial.println(root["data6"].as<char*>());

  // Disconnect
  client.stop();
}

void loop() {

}

Every time a run the sketch I get the following error:
"Parsing failed!"
So I got to the following page:
https://arduinojson.org/v5/faq/why-parsing-fails/
I've tested the sketch with different buffer sizes, without success?
Is it possible that the memory simply is too small?
Or did I miss something?

you can use W5500 or enc28j60 with esp8266. use MemoryFree library to print free memory size at runtime

Do you have an example or a sketch for me? I did not make it work.

use esp8266 package 2.4.2 and delete the bundled Ethernet library

try an esp32, they have phy built in, and a lot more ram to boot...


text:
How to sample incoming 600khz pin and divide it by 4 and generate low frequency signal at output pin of arduino
I am trying to divide a incoming high frequency signal 600kHz by 4 and output wave at arduino MEGA2560 digital pin.

The input to arduino comes from incremental Encoder which is connected to motor that runs at 9000 rpm and the generates 1024 pulses per rotation.
I am trying to downsample the frequency I am getting from arduino to 250kHz or less.
I tried following approaches :
a. I counted the rising edge of the incoming wave and a interrupt is triggered as number of rising edge reaches certain value and ISR toggle an output pin.
b. I tried to get hardware counter work at T0 pin but I was not able to hit ISR when the count has reached specific value.

The problem with approach 1 is: As my frequency of incoming wave increases the output wave starts missing some pulses and generates one half cycle for 6/8/10 pulses of incoming wave. It should actually generate one half cycle for 4 pulses.
Here is approach 2 code:
#define outPin1 10
volatile short encoder = 4;

void setup ()
{
   pinMode (outPin1, OUTPUT);
   Serial.begin(9600);
   cli();
   // reset Timer 0
   TCCR0A = 0;
   TCCR0B = 0;

 }  // end of setup

 ISR(TIMER0_COMPA_vect)
 {
     digitalWrite(outPin1, !digitalRead(outPin1));

 }

 void loop ()
 {
    TCNT0 = 0;      //counter to zero

    // set compare match register to desired timer count:
   OCR0A = encoder;
    // turn on CTC mode:

   bitSet(TCCR0A, WGM01);
   // Timer 0 - counts events on pin D4

  bitSet(TIMSK0, OCIE0A);    // interrupt on Timer 0 CTC
   // start Timer 0
  // External clock source on T0 pin (D4). Clock on rising edge.

   bitSet(TCCR0B, CS02);
   bitSet(TCCR0B, CS01);
   bitSet(TCCR0B, CS00);
}

Please someone help me out with this issue

Why would you waste an Arduino on this when you can use a single 10¢ chip? http://www.ti.com/product/SN74HC163

I think the code you put the loop should be in setup. Otherwise you loop code is constantly resetting the counter, back to zero (TCNT0 = 0;)

Couldn't you just attach an interrupt to the input pin, have if count up every time it's called, and set the output to low when the count is equal to 4. 600kHz is probably slow enough to have enough time for the ISR to run it's code.

This is probably too fast to have have software involved in the loop.
You should try to use a hardware-only solution. Note the Arduino timers
should be usable as hardware frequency dividers:

configure a timer to be clocked off the input signal, so that it
behaves like a counter.
configure it for delivering a PWM output with a period of 4 timer
clock cycles and a duty cycle of 50%.

You may try this, but beware I have not tested it:
void setup()
{
    // Configure Timer 5 as a frequency divider:
    //   input: digital pin 47 = PL2 = T5
    //   ouput: digital pin 46 = PL3 = OC5A
    DDRL  |= _BV(PL3);    // set pin PL3 as output
    TCCR5A = 0;           // undo the Arduino core's configuration
    TCCR5B = 0;
    ICR5   = 4 - 1;       // period = 4 timer clock cycles
    OCR5A  = 2 - 1;       // output HIGH for 2 timer clock cycles
    TCCR5A = _BV(COM5A1)  // non-inverting PWM on pin OC5A
           | _BV(WGM51);  // mode 14: fast PWM, TOP = ICR5
    TCCR5B = _BV(WGM52)
           | _BV(WGM53)
           | _BV(CS50)    // clock on rising edges of T5
           | _BV(CS51)
           | _BV(CS52);
}

void loop(){}

It worked for one output of encoder but i also have another output from encoder for which i have no input pin to give on mega2560 since on T5 can be used and T0 has not Input capture functionality.   I have one idea whether i can use on one input of encoder and generate two wave at output pin with phase shift of 90 degress. Depending on a flag it must be possible for me to change which wave is leading or lagging

@Vishal777: Re “T0 has not Input capture functionality”: you don't need input capture. You can use T0 if you don't mind loosing the Arduino timing functions (millis() and co.) which depend on Timer 0. Or you could use T1 if you can solder a header onto the unpopulated footprint JP5. Re generating two waves at 90° from a single timer: I do not think this is possible.

I am trying to use timer 0 in CTC mode and triggering an ISR which toggles the pin when TCNT0 reaches 4. But without the valid input I am getting a wave at digital output pin 10. I think it is taking internal clock as reference instead of external clock. I have made all CS bits high to select clock from T0 PIN This is strange behavior

@Vishal777: Let me insist: “This is probably too fast to have have software involved in the loop.” An ISR is a piece of software, so forget about it.

I could successfully divide by 4 using 2 timers T0 and T5. As per my existing setup I get input wave of less than 200kHz. I have not tested for 600kHz input wave

@ EdgarBonet here is link for the code    http://collabedit.com/e3xth

I am writing another answer because what I propose here is radically
different from the previous answer. In that answer I wrote that this is
too fast for being done in software, and here I am going to contradict
myself. :-/
At 600 kHz, the input stays low for roughly 13 CPU cycles,
then high for another 13 cycles. You cannot do much in 13 cycles.
Notably, the prologue of an ISR can quite often take more than this.
Also, whenever the Timer 0 overflow ISR from the Arduino core fires, it
can delay your own ISR for way more than 13 cycles. That's why it
is usually illusory to expect any job to be reliably done in this time
frame. Especially if interrupts are involved.
That being said, if the CPU has absolutely nothing else to do. And
specifically if it is never interrupted, Then it can keep up with that
pace. Here is a program that should do what you expect. I initially
thought about writing it in assembly, but it can also be written in C,
as the compiler translates it in a quite straightforward way. If in
doubt, however, check the generated assembly:
/*
 * From one square wave generate two waves in quadrature at 1/4 of the
 * original frequency.
 *
 * https://arduino.stackexchange.com/questions/63202
 *                               _   _   _   _   _   _
 *  input:  digital 13 = PB7    / \_/ \_/ \_/ \_/ \_/ \_/
 *                               _______         _______
 *  output: digital 10 = PB4    /       \_______/       \
 *                                   _______         ____
 *  output: digital 11 = PB5    ____/       \_______/
 */

int main(void)
{
    DDRB = _BV(PB4) | _BV(PB5);  // PB4 and PB5 as outputs
    for (;;) {
        loop_until_bit_is_clear(PINB, PB7);  // wait for rising input
        loop_until_bit_is_set(PINB, PB7);
        PORTB |= _BV(PB4);                   // rise PB4
        loop_until_bit_is_clear(PINB, PB7);  // wait for rising input
        loop_until_bit_is_set(PINB, PB7);
        PORTB |= _BV(PB5);                   // rise PB5
        loop_until_bit_is_clear(PINB, PB7);  // wait for rising input
        loop_until_bit_is_set(PINB, PB7);
        PORTB &= ~_BV(PB4);                  // fall PB4
        loop_until_bit_is_clear(PINB, PB7);  // wait for rising input
        loop_until_bit_is_set(PINB, PB7);
        PORTB &= ~_BV(PB5);                  // fall PB5
    }
}

Note that, since this is not using the Arduino core, I wrote main()
rather than setup() and loop(). This overrides the main() provided
by the core, thus you don't have the initializations that come with it
and, in particular, you don't have the Timer 0 interrupt.


text:
Sending GPS data through a WiFi module
I'm trying to send GPS data using a neo-6m GPS module through WiFi using esp8266 module, I have both of the modules working alone, but when I try using both the WiFi works but won't send the data from the GPS.
I call the GPS and save the latitude, longitude, date and time to separate variables, then try sending those variables using the WiFi to the server on the Arduino Uno, but they just show up as 0's.
#include <TinyGPS++.h>
#include "WiFiEsp.h"

// Emulate Serial1 on pins 6/7 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(6, 7); // RX, TX
#endif

char ssid[] = "UPC9080883";            // your network SSID (name)
char pass[] = "OYKXVYND";        // your network password
int status = WL_IDLE_STATUS;

int ledStatus = LOW;

WiFiEspServer server(80);

// use a ring buffer to increase speed and reduce memory allocation
RingBuffer buf(8);

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial Serial2(RXPin, TXPin);

double  latitude, longitude;
int days, months, years, hr, mins, secs;
void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);  // initialize digital pin LED_BUILTIN as an output.
  Serial.begin(115200);   // initialize serial for debugging
  Serial1.begin(9600);    // initialize serial for ESP module
  WiFi.init(&Serial1);    // initialize ESP module

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  Serial.println("You're connected to the network");
  printWifiStatus();

  // start the web server on port 80
  server.begin();
}

void loop()
{
  Serial1.end();
  Serial2.begin(GPSBaud);
  GPS();
  Serial2.end();
  Serial1.begin(9600);
  WiFiEspClient client = server.available();  // listen for incoming clients
  if (client) {                               // if you get a client,
    Serial.println("New client");             // print a message out the serial port
    buf.init();                               // initialize the circular buffer
    while (client.connected()) {              // loop while the client's connected
      if (client.available()) {               // if there's bytes to read from the client,
        char c = client.read();               // read a byte, then
        buf.push(c);                          // push it to the ring buffer

        // printing the stream to the serial monitor will slow down
        // the receiving of data from the ESP filling the serial buffer
        //Serial.write(c);

        // you got two newline characters in a row
        // that's the end of the HTTP request, so send a response
        if (buf.endsWith("\r\n\r\n"))
        {
          sendHttpResponse(client);
          break;
        }
      }
    }

    // close the connection
    client.stop();
    Serial.println("Client disconnected");
  }
}
void GPS() {
  while (Serial2.available() > 0) {
    gps.encode(Serial2.read());
    if (gps.location.isUpdated()) {
      // Latitude in degrees (double)
      latitude = (gps.location.lat(), 6);
      // Longitude in degrees (double)
      longitude = (gps.location.lng(), 6);

      // Day (1-31) (u8)
      days = (gps.date.day());
      // Month (1-12) (u8)
      months = (gps.date.month());
      // Year (2000+) (u16)
      years = (gps.date.year());

      // Hour (0-23) (u8)
      hr = (gps.time.hour());
      // Minute (0-59) (u8)
      mins = (gps.time.minute());
      // Second (0-59) (u8)
      secs = (gps.time.second());
      Serial.println(longitude);
      Serial.println(latitude);
      Serial.println(days);
      Serial.println(months);
      Serial.println(years);
      Serial.println(hr);
      Serial.println(mins);
      Serial.println(secs);

    }
  }
}

void sendHttpResponse(WiFiEspClient client)
{
  // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
  // and a content-type so the client knows what's coming, then a blank line:
  client.println("HTTP/1.1 200 OK");
  client.println("Content-type:text/html");
  client.println();

  // the content of the HTTP response follows the header:
  client.println("
");
  client.println("
");
  client.print("Latitude= ");
  client.print(latitude);
  client.print(" Longitude = ");
  client.println(longitude);
  client.println("
");
  client.print("Date: ");
  client.print(days);
  client.print("/");
  client.print(months);
  client.print("/");
  client.print(years);
  client.println("
");
  client.print("Time: ");
  client.print(hr);
  client.print(":");
  client.print(mins);
  client.print(":");
  client.print(secs);
  // The HTTP response ends with another blank line:
  client.println();
}

void printWifiStatus()
{
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print where to go in the browser
  Serial.println();
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
  Serial.println();
}

SoftwareSerial can't listen on two instances. There is a .listen() function to switch between SoftwareSerial instances.
The esp8266 AT firmware doesn't wait until you listen on the SoftwareSerial instance. If there is a connection to the server it sends +IPD and data. If the SoftwareSerial instance doesn't listen the information about client connection is lost.
You must listen to esp8266 all the time, so you can't use two SoftwareSerial instances.
You could use the RX pin of Uno to receive data from GPS module over hardware Serial.


text:
Only half of the 16x2 LCD appears
I searched for answers but I didn't found any answers to my problem. Actually, I use my Arduino with a 16x2 LCD screen. But as the title says, only the half of the screen displays (8x2), the other side just doesn't turn on. Do someone knows how to solve this problem?

In order to get good help in solving your problem, please provide more details on your specific situation. Include your wiring diagram (schematic, or something similar) and the code you are using, and as much information as you know about the LCD panel you have (datasheet, source, etc.)

Try configuring it as 8x4 I found many strange configurations when I bought cheap LCDs from China.

i've never seen/heard of that particular problem/failure mode, so it might be defective.


text:
I am building an robotic arm by using flex sensor, servo and 2 xbees
Rx Code:
#include <Servo.h>
Servo myServo;

void setup() {
Serial.begin(9600);
myServo.attach(9);
delay(5000);
myServo.write(0);
}

void loop() {
  while(Serial.available()==0);

    int d = Serial.read() - '0';
    if(d>0)
    {
      int pos = map(d,0,9,0,180);
      pos = constrain(pos,0,180);
      myServo.write(pos);
      Serial.println(d);

      delay(50);
      }
      else
      {};

}

Tx code:
int sensorValue = 0;         // the sensor value
int sensorMin = 1023;        // minimum sensor value
int sensorMax = 0;           // maximum sensor value
int SensorMid = 0;
const int POWER_OF_TWO_TO_AVERAGE = 6;

void setup() {
pinMode(13,OUTPUT);
  Serial.begin(9600);

  while (millis() < 10000) {
    digitalWrite(13,HIGH);
    sensorValue = analogRead(A1);
    if (sensorValue > sensorMax) {
      sensorMax = sensorValue;
    }
    if (sensorValue < sensorMin) {
      sensorMin = sensorValue;
    }
  }
  SensorMid = (sensorMin + sensorMax )/2;
  digitalWrite(13,LOW);
  }

void loop() {
int val = map(analogRead(A1),SensorMid,sensorMax,0,9);
Serial.println(val);
delay(100);
}

I am building a robotic arm and I am facing some problems regrading to the servos stability with the flex, I am using the flex as the transmitter and the servo as the receiver, and when I press my finger my servo doesn't move properly.
Any suggestions?

Please show your code (a minimal, complete example that demonstrates the problems), your wiring diagram or schematic, and a more detailed description of the "doesn't move properly" issue. Otherwise, all anyone can do is make uninformed guesses.

@josecanuc, Please refer to the question, since I have edited the question

what does this mean? i press my finger

I am using flex sensor, it gives the signals by bending your finger @jsotola

Have you tried taking a mean of for example 10 or 20 consecutive readings? All analog signals have noise on them, which you can reduce by taking the mean value

Without knowing more about the actual problem of "doesn't move properly", what I initially see is that you are transmitting values 0-9 by using Serial.println(), which sends the byte data, and also a newline (ASCII value 10), so your RX code is probably getting alternating input of the intended value, and the value 10, which is getting subtracted from 48 (the ASCII value of '0'), mapped and constrained to 0.
Try changing your TX script to call Serial.print() instead. Your receiver doesn't care about each value showing up on a new line -- it doesn't know about lines.

What I mean by it doesn't move properly, that when I try bending the flex sensor, I guess that the servo doesn't receive the data properly due to the flex sensor resolution.

I think that the servo is not stable because that the flex is keep sending values even when I’m not touching it, how can I solve this problem @jose can u c

Why do you think that? If you want help from the public here, you have to provide actual data.


text:
What Version of the Sketch did I leave on there?
Is there a way to "ask" the Arduino what sketch was compiled on it?
There are several versions of the sketch and I need to see which version the Arduino has been running.

No, but if you really want to there might be a way. First of all, you should add a version number (text or a number) into your sketch. When there is output to the serial monitor or a display, then show the name and the version. Next, make a header and write in comments which version of the arduino ide is used. About your problem: with avrdude you can retrieve the binary code. When you also know which version of the arduino ide was used to compile the sketch, then you can compare the binary versions of the sketch, until you find the right one.

First, you have to store the desired information in your sketch.
#define VERSION F("0.01 4-Apr-2019")

void setup() {
   Serial.begin(9600);
   Serial.print(F("Test Sketch V"));
   Serial.println(VERSION);
}

void loop() {
}

Of course any other way might work as well:

Only print it, if at reset a test button is pressed
Check for a Serial command and respond the version info.
Don't print it, but use avrdude and a programmer to read the FLASH memory and search it for the version string. (Similar to jot's comment above)

If you have not set the flash protection bits you can read back the contents of the program memory. See https://www.evilmadscientist.com/2011/avr-basics-reading-and-writing-flash-contents/
By reading back the first pages you can then compare with the different versions of the sketch (hex file) and determine which version is on the device. The first pages are the different ISR vectors and should be unique for the sketches.
Cheers!


text:
Push and hold on/off switch for arduino
Many electronic devices turn on/off, or more correctly on/sleep, by pressing a button and holding it for two or three seconds. I would like to put this ability into a project using an Adafruit Feather board.  The sleep side is easy, I can detect a level and if it stays there for some time, run the code to put the processor to sleep.  My question involves the wake up side. The chip wakes up via an interrupt.
The question then becomes, how do I generate the interrupt source only after the button has been held for the designated time? I've considered two options:
1) Use a level interrupt and an RC circuit to do the delay.
2) Have the processor wake up immediately and then implement logic to determine if it has been held "long enough" and go back to sleep if not.
Am I missing an easy option? Is there a general consensus on the best way to do this? It seems like such a normal thing that I'm surprised my searches haven't turned up any tutorials.

Can't you just wait for the button to be released, and then to go to sleep? You could even disable the interrupt while awake, on only turn it on, right before going to sleep.

The problem with that is that random bumps get treated as requests to sleep/wakeup.  Press and hold for "long enough" is very desirable.

Oh, you want to have press-and-hold, for wake-up as well. In that case, have the MCU wake up from sleep by the button; wait till the button is released; if it's less than 3 seconds, go back to sleep.

I would go for option 2.
You can wake up the controller immediately, but only the processor.
Then just start waiting for the "long enough" time that you defined, regulary checking the button state. If the button is still pushed, then initiate full wake up. If it is released, go back to sleep.
This is the easy option, requiring no extra hardware, and only a dozen of so of lines of code.
Another option, that exist and have a somewhat similar behaviour, is to have your processor wake up regulary on timer, and checking the state of the input. This is what is done for "radio controled" devices, for example (Where the "button" is a radio circuit that need to be switch on and off).
Given a sufficiently long sleep between check, on average you will get the "long enough" delay.
This option is useful when you don't have available interrupt pins, or you need something more complex that a button as the input.

Waking up would up the power consumption by a lot. The wake up frequency would have to be, oh probably 3x the button press time to be good for a human.

It would indeed not be the best option, but I wanted to include it for completness. As I said, if possible, go for the other one.


text:
Remove gravity from accelerometer of MPU-6050
I am currently working with MPU-6050. Now I want to minus gravity from my accelerometer's value as we minus the offset.
Here is the code:
#include <Wire.h>
#include <MPU6050.h>
//read as rool:pitch:yaw:accX:accY:accZ
MPU6050 mpu;
unsigned long timer = 0;
float timeStep = 0.01;
float pitch = 0;
float roll = 0;
float yaw = 0;
float accX = 0;
float accY = 0;
float accZ = 0;
float rollRad = 0;
float pitchRad = 0;
float yawRad = 0;

int count = 0;

Vector minusGravity(Vector vec)
{
    /*
     float x = vec.XAxis, y = vec.YAxis, z = vec.ZAxis;
     vec.XAxis -= x * cos(yawRad) - y * sin(yawRad) + x * cos(pitchRad) + z
           * sin(pitchRad) + 0;
     vec.YAxis -= x * sin(yawRad) - y * cos(yawRad) + 0 + y * cos(rollRad) -
           z * sin(rollRad);
     vec.ZAxis -= 0 - x * sin(pitchRad) + z * cos(pitchRad) + y *
           sin(rollRad) + z * cos(rollRad);
    */

    return vec;
}

float accP(float value)
{
    int x = (int)(value * 10);
    return ((float)(x)) / 10;
}

void setup()
{
    Serial.begin(115200);
    while (!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
    {

    }
    //mpu.calibrateGyro();
    mpu.setThreshold(1);
 }

 void loop()
 {
    timer = millis();
    Vector norm = mpu.readNormalizeGyro();
    pitch = pitch + norm.YAxis * timeStep;
    roll = roll + norm.XAxis * timeStep;
    yaw = yaw + norm.ZAxis * timeStep;
    Vector normAccel = minusGravity(mpu.readNormalizeAccel());
    rollRad = roll * 0.0174533;
    pitchRad = pitch * 0.0174533;
    yawRad = yaw * 0.0174533;

    Serial.print(roll);
    Serial.print(":");
    Serial.print(pitch);
    Serial.print(":");
    Serial.print(yaw);
    Serial.print(":");
    accX = accP(normAccel.XAxis);
    accY = accP(normAccel.YAxis);
    accZ = accP(normAccel.ZAxis);
    Serial.print(accX);
    Serial.print(":");
    Serial.print(accY);
    Serial.print(":");
    Serial.println(accZ);
    delay((timeStep * 2500) - (millis() - timer));
}

I understand the problem is here :
vec.XAxis -= x * cos(yawRad) - y * sin(yawRad) + x * cos(pitchRad) + z
           * sin(pitchRad) + 0;
     vec.YAxis -= x * sin(yawRad) - y * cos(yawRad) + 0 + y * cos(rollRad) -
           z * sin(rollRad);
     vec.ZAxis -= 0 - x * sin(pitchRad) + z * cos(pitchRad) + y *
           sin(rollRad) + z * cos(rollRad);

New code :
      #include <Wire.h>
  #include <MPU6050.h>
  //read as rool:pitch:yaw:accX:accY:accZ
  MPU6050 mpu;
  unsigned long timer = 0;
  float timeStep = 0.01;
  float pitch = 0;
  float roll = 0;
  float yaw = 0;
  float accX = 0;
  float accY = 0;
  float accZ = 0;
  float rollRad = 0;
  float pitchRad = 0;
  float yawRad = 0;
  float gX = 0;
  float gY = 0;
  float gZ = -9.8;

  int count = 0;

  Vector minusGravity(Vector vec)
  {

    float x = gX, y = gY, z = gZ;
    vec.XAxis -= x * cos(yawRad) - y * sin(yawRad) ;
    vec.YAxis -= x * sin(yawRad) - y * cos(yawRad) ;

    x = vec.XAxis; z = vec.ZAxis;
    vec.XAxis -=  x * cos(pitchRad) + z * sin(pitchRad) ;
    vec.ZAxis -= - x * sin(pitchRad) + z * cos(pitchRad) ;

    y = vec.YAxis, z = vec.ZAxis;
    vec.YAxis -=  y * cos(rollRad) - z * sin(rollRad);
    vec.ZAxis -=  y * sin(rollRad) + z * cos(rollRad);

    return vec;
  }

  float accP(float value)
  {
    int x = (int)(value * 10);
    return ((float)(x)) / 10;
  }

  void setup()
  {
    Serial.begin(115200);
    while (!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
    {

    }
    //mpu.calibrateGyro();
    mpu.setThreshold(1);
    Vector normAccel = mpu.readNormalizeAccel();
    gX = normAccel.XAxis;
    gY = normAccel.YAxis;
    gZ = normAccel.ZAxis;
  }
  void loop()
  {
    timer = millis();
    Vector norm = mpu.readNormalizeGyro();
    pitch +=  norm.YAxis * timeStep;
    roll += norm.XAxis * timeStep;
    yaw += norm.ZAxis * timeStep;
    Vector normAccel = minusGravity(mpu.readNormalizeAccel());
    rollRad = roll * 0.0174533;
    pitchRad = pitch * 0.0174533;
    yawRad = yaw * 0.0174533;
    Serial.print(roll );
    Serial.print(":");
    Serial.print(pitch );
    Serial.print(":");
      Serial.print(yaw );
    Serial.print(":");
    accX = accP(normAccel.XAxis);
    accY = accP(normAccel.YAxis);
    accZ = accP(normAccel.ZAxis);
    Serial.print(accX);
    Serial.print(":");
    Serial.print(accY);
    Serial.print(":");
    Serial.println(accZ);
    delay((timeStep * 2500) - (millis() - timer));
  }

It is little buggy.
Can anyone help me figure out what is my mistake ?

I understand the problem is here .... what is the problem?  .... what do you expect to see? .... what do you see instead?

I just want to see acceleration due to movement, not due to gravity. I'm trying to counter gravity portion.

When I put it on a surface or holding it, there should be no acceleration.

@jsotola I may have found a solution, added an answer , can you verify it, if it is correct or not ?

A general comment: you are trying to compute pitch, roll, yaw by integrating the readings from the gyroscope and and to account for gravity. In my experience this is unreliable beyond a few seconds and you would need more sophisticated methods if you want to track orientation.

May I know what are those methods ?

I have edited the question & added new code, which is just a little buggy, can you help me figure it out ? @ChristianLindig

Look for Kalman filter or this article.

I don't have problem with angle, acceleration is the problem

Did the updated code to remove gravity acceleration work. Or did u find something else if u did can u please send?

I may have come to a solution :
Vector minusGravity(Vector vec)
{

 float x = vec.XAxis, y = vec.YAxis, z = 0;
 vec.XAxis -= x * cos(yawRad) - y * sin(yawRad) ;
 vec.YAxis -= x * sin(yawRad) - y * cos(yawRad) ;

 x = vec.XAxis; z = vec.ZAxis;
 vec.XAxis -=  x * cos(pitchRad) + z * sin(pitchRad) ;
 vec.ZAxis -= - x * sin(pitchRad) + z * cos(pitchRad) ;

 y = vec.YAxis, z = vec.ZAxis;
 vec.YAxis -=  y * cos(rollRad) - z * sin(rollRad);
 vec.ZAxis -=  y * sin(rollRad) + z * cos(rollRad);

 return vec;
}

Now this is far better, as after calculating effect of roll,pitch,yaw in every step the  x,y,z changes. I missed that part. I was calculating directly, so it was giving me wrong value.
vec.XAxis -= x * cos(yawRad) - y * sin(yawRad)
then, vec.XAxis -=  x * cos(pitchRad) + z * sin(pitchRad)
 doesn't give the same result as the wrong one vec.XAxis -= x * cos(yawRad) - y * sin(yawRad) + x * cos(pitchRad) + z
           * sin(pitchRad) + 0;

@jsotola can you verify it ??


text:
Arduino freezes while running code
I am frustrated with my arduino project can you help me?
I am using Arduino Uno, electric lock (high/low), 4 distance sonic modules. Basically I have 4 drawers, I am measuring the distance - how much are they opened and if they are opened in given limits, I set the electric lock open (high).
It is working, but after some while, it stops and it stops running.
I have tried to comment all serial communication - didn't help. I have tried to use proper variable data types - same. I have tried to buy much powerful power source - 12V 3,5A and I bought Electrolyte condenzator 4,7mF to balance the power peaks while the lock closes - didn't help.
The lock is turned on using relay, connecting it directly to power source 12V.
Relay is powered from 5V arduino supply and controlled by arduino Digital pin.
4 Sonic distance modules are powered from arduino power supply.
Its even more funny that it starts running after ~10 minutes from nothing. Im confused.
Code:
    // defines pins numbers
const int trigPin1 = 2;
const int echoPin1 = 3;
const int trigPin2 = 6;
const int echoPin2 = 5;
const int trigPin3 = 9;
const int echoPin3 = 8;
const int trigPin4 = 12;
const int echoPin4 = 11;
const int relayPin = 7;
//distance limits
const int minSuplik4=27;//suplik4
const int maxSuplik4=29;
const int minSuplik3=22;//suplik3
const int maxSuplik3=24;
const int minSuplik2=32;//suplik2
const int maxSuplik2=34;
const int minSuplik1=9;//suplik1
const int maxSuplik1=11;
/*
double PreDistance1[4]={0,0,0,0};//supliky
double PreDistance2[4]={0,0,0,0};//supliky
double PreDistance3[4]={0,0,0,0};//supliky
*/
long distance[4]={0,0,0,0};//array with distances
int i;
int x;

int trigPinX[4]={trigPin1,trigPin2,trigPin3,trigPin4};//supliky
int echoPinX[4]={echoPin1,echoPin2,echoPin3,echoPin4};//supliky
int maxD[4]={maxSuplik1,maxSuplik2,maxSuplik3,maxSuplik4};//supliky
int minD[4]={minSuplik1,minSuplik2,minSuplik3,minSuplik4};//supliky
void setup() {
pinMode(relayPin, OUTPUT);
pinMode(trigPin1, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin1, INPUT); // Sets the echoPin as an Input
pinMode(trigPin2, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin2, INPUT); // Sets the echoPin as an Input
pinMode(trigPin3, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin3, INPUT); // Sets the echoPin as an Input
pinMode(trigPin4, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin4, INPUT); // Sets the echoPin as an Input
digitalWrite(relayPin, LOW);
Serial.begin(9600); // Starts the serial communication
}
void loop() {

for (int i=0; i<4; i++)
{
  delay(5);
  distance[i]=DistanceFunction(trigPinX[i],echoPinX[i]);
  delay(20);
  /*********** DEBUG ************
  Serial.print("Distance");// Prints the distance on the Serial Monitor
  Serial.print(i+1);
  Serial.print(":");
  Serial.print(distance[i]);
  Serial.print("<");
  Serial.print(minD[i]);
  Serial.print(":");
  Serial.print(maxD[i]);
  Serial.print(">");
  Serial.print(";");
  *********************************/
}

if(distance[0]>=minD[0] && distance[0]<=maxD[0] && distance[1]>=minD[1] && distance[1]<=maxD[1] && distance[2]>=minD[2] && distance[2]<=maxD[2] && distance[3]>=minD[3] && distance[3]<=maxD[3])
      {
        OpenFcn();
      }
else
      {
        CloseFcn();
      }
delay(100);
}

int DistanceFunction(int trigPin, int echoPin)
{
  digitalWrite(trigPin, LOW);// Clears the trigPin
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);// Sets the trigPin on HIGH state for 10 micro seconds
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  long duration = pulseIn(echoPin, HIGH);// Reads the echoPin, returns the sound wave travel time in microseconds
  long distanceFcn= duration*0.034/2;// Calculating the distance
  return distanceFcn;
}

int OpenFcn()
{
  digitalWrite(relayPin, HIGH);
  //Serial.println("OPENED");
  for (int x=5; x>0; x--)
    {
      //Serial.println("Otevreno:");
      //Serial.println(x);
      delay(1000);
    }
}

int CloseFcn()
{
  digitalWrite(relayPin, LOW);
  //Serial.println("CLOSED");
}

That might be a memory/stack problem or an electrical pulse problem. I can not spot a memory/stack problem, so let's focus on the electric lock and the relay. How much is 4,7mF? I suggest to use 1000µF to the arduino 5v and gnd. If you replace the electric lock or relay with a led plus resistors, does that help? What can you tell about the electric lock and the relay? Can you give a link to them? Please add a message with Serial.println after the Serial.begin in the setup function, so at least you will know if the arduino has reset.

Please add all the extra information to your question. A arduino digital pin can give 20mA. The 40mA is the shortcut current and should be avoided. Are you powering a 70mA relay with a digital pin? That is the problem then. Can you give a schematic or drawing or photo of your wiring?

please post the serial terminal output as text instead of a picture ...... disconnect the electric lock and see if the program still crashes

I have tried to supply the sonic modules and the relay with external supply, but its the same problem. But I supplied the arduino with different source. Can this be the reason? Relay is this one http://www.g7electronica.net/1444-2227-thickbox/rele-srd-05vdc-sl-c.jpg
sonic modules are these https://www.banggood.com/cs/10Pcs-HC-SR04-Ultrasonic-Ranging-Sensor-Ultrasonic-Module-For-Arduino-p-942912.html

Ok so I tried to connect everything on external 5V 3,5A source and only the lock connected to 12V. It still crashes, the same behaviour.

If I disconnect the lock, controlling the relay without the lock, it is working good.

relay without the lock, it is working sounds like a missing freewheeling diode

It looks like that there was a problem in the relay module or power supply cord. I have changed these two HW elements and looks like it is working. The reason why it did malfuctioning the arduino was, that when i moved the drawer, it slightly moved the power cord which had bad connection, so it made voltage drop on arduino supply and started to do crazy things.
Thanks all for your time


text:
NRF24L01 Networking
We checked Xbee, ZigBee and other alternatives already and we're trying to figure out a way for good and cheap network system. NRF24l01 looks good but 32 bytes not enough actually. Even so looks like we'll use it but some questions;
Questions' scenario contains 1 master and 300 slave devices with NRF24l01. We're thinking about making a addressing system like computer networks and every message will contain device id or device group tag. Master will be at the center of the room. Room do not have any inner wall or obstacle. Maximum range is less than 100m².
1) May messages get corrupt or latency ?
2) Is there any prepared library for Arduino for this kind of communication ?
3) Do you think is there any better solution for this kind of master & slaves networking logic (must be cheap and stable) ?

google NRF24L01 mesh

1) May messages get corrupt or latency ?

For uni-directional Master to One Slave, no, there should be no corruption (at least not caused by there being lots of slaves present). For bi-directional Master to Multiple Slaves at the same time, yes, you're going to run into problems when the slaves try and reply. Keeping your protocol really simple will be beneficial.

2) Is there any prepared library for Arduino for this kind of communication ?

There's nothing special about what you propose. The RF24.h library will probably do the job (though I have never used it, so don't ask me how to use it).

3) Do you think is there any better solution for this kind of master & slaves networking logic (must be cheap and stable) ?

They're all a bit of a muchness really. RF communication is RF communication. It's how you use it that matters.
The nRF24L01+ has a number of benefits that mean you can do some things in hardware:

Multiple receive pipes, each with their own address - so you can have one for the device address, one for a group address, and one for a global "broadcast" address
Auto-acknowledge and re-sending of failed packets for more reliable communication (only for one-to-one communication)
Automatic packetisation so you don't have to worry about crafting a low-level protocol of your own
Direct communication giving low-latency
Power Amplifier option for greater range.

You could use WiFi, however that would struggle with so many devices (most home access points and routers can't handle more than a few dozen devices), plus it adds extra latency that it sounds like you don't want.
The nRF24L01+ is probably a good choice for this kind of communication - however, be cautious with cheap clone devices: some of them have a silicon error that causes them to not be compatible with other nRF24L01+ devices.

I was surprised to read that RF24.h supports packetisation which I read as in supporting payloads larger than 32 bytes. Could you provide a link that explains that?

@ChristianLindig By packetisation I mean that it deals with all the frame construction, CRCs, etc. You still have to split your data into 32 byte chunks and add any other identifying segment numbering.


text:
Can't store RFID data in the next 5 bytes of array
I'm working on RFID project to handle multiple cards.
I did most of the things OK. But now I have one problem. Which is the following:

The RFID code is 5 bytes, so I need an array of 5 bytes. If more cards then the array size = number of card * 5.
For my example I'm working with 2 cards. So array size is 10 bytes.
I can store the first card in the first 5 bytes.

The problem:
I can't store the 2nd card in the next 5 bytes in the array. I don't know why.
This is my only test code:
/****************************** LIBRARIES ******************************/
#include <SPI.h>
#include <RFID.h>

/****************************** DEFINITIONS ******************************/
// pins definitions
#define SS_PIN          10
#define RST_PIN         9

// setup definitions
#define CARDS           2
#define MXCD            CARDS*5

/****************************** VARIABLES ******************************/
// rfid variables:
byte crd_buf[MXCD],card_no;
byte register_lock,check_lock,print_lock;

/****************************** FUNCTIONES ******************************/
// rfid functions
void register_accepted_card(void);
void record_new_cards(void);
void check_card(void);
void print_registered_cards(void);

// objects
RFID rfid(SS_PIN, RST_PIN);

//////////////////////////////////////////////////////////////////////
void setup(){
  Serial.begin(9600);
  SPI.begin();
  rfid.init();
}

void loop(){
    register_accepted_card(); // apply only once
}

void register_accepted_card(void){
  if (!register_lock) {
    if (rfid.isCard()) {
      if(rfid.readCardSerial()){
        if(card_no>0){
          for(byte i = 0; i<card_no; i++){
            if(!memcmp((crd_buf+(i*5)),rfid.serNum,5)){

              Serial.println("already card is");
              for(byte p = i*5; p<(i*5)+5; p++){
                Serial.print(crd_buf[p],HEX);Serial.print(", ");}
                Serial.println();

              lcd_state = ALREADY_MSG;
              register_lock = 1;
            }
          }
        }

        //////////////////////////
        // problem is in this part
        //////////////////////////

        if(!register_lock){

          for(byte i=card_no*5;i<(card_no*5)+5;i++){
            crd_buf[i] = rfid.serNum[i];}

          Serial.print("loop#"); Serial.println(card_no);
          Serial.print("start index ");Serial.println(card_no*5);
          Serial.print("end index ");Serial.println((card_no*5)+5);
          Serial.println();

          Serial.print("card#"); Serial.println(card_no+1);
          for(byte i=card_no*5;i<(card_no*5)+5;i++){
            Serial.print(crd_buf[i],HEX);Serial.print(", ");}
          Serial.println();Serial.println("//////////////////////////");

          card_no++;
          if(card_no >= CARDS){lcd_state = FINISH_MSG;}
          else{lcd_state = REGISTER_MSG;}
          register_lock = 1;
        }
      }
    }
    rfid.halt();
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
My second question, for the part of checking the cards after finishing registering the cards to be accepted.
I did a for loop for the number of cards to get the card that is registered in the array and send a message that the card is stored and accepted, otherwise, it returns a denied message that the card isn't stored in the array with alarm buzzer.
The problem that is the for loop checks the card for all the indexes in the array which is what I want but the result is mixed with accepted and denied.
The question is how to get out of the for loop?
void check_card(void){
  if (check_lock){
    if (rfid.isCard()){
      if (rfid.readCardSerial()){
        for(byte i=0;i<card_no;i++){

          // start of for loop
          Serial.print("check# ");Serial.println(i);
          if(!memcmp(crd_buf+(i*5),rfid.serNum,5)){
            Serial.println("card accepted");
            digitalWrite(ACCEPT_LED,HIGH);
            digitalWrite(DENIED_LED,LOW);
            digitalWrite(BUZZER,LOW);
            check_lock = 0;
            sys_state = 1;
            lcd_state = ACCEPTED_MSG;
          }
          else{
            Serial.println("card denied");
            digitalWrite(ACCEPT_LED,LOW);
            digitalWrite(DENIED_LED,HIGH);
            digitalWrite(BUZZER,HIGH);
            check_lock = 0;
            sys_state = 1;
            lcd_state = DENIED_MSG;
          }
        }
            // end of for loop

      }
      rfid.halt();
    }
  }
}

Why not a 2D array of crd_buf[CARDS][5];? So much simpler to deal with.

OK, I should try your method. But I'm really confused of why it's not working as I tested it in codeblocks and it is working fine ! Is there something I don't know about Arduino compiler ? Is it possible that the compiler is not defined to handle these operations on arrays ? to me, I just don't think so, Arduino compiler is really professional. Maybe I'm doing something wrong .. But I should try the 2D version, thanks dude :)

Your problem is this bit:
      for(byte i=card_no*5;i<(card_no*5)+5;i++){
        crd_buf[i] = rfid.serNum[i];}

For the first card you're copying bytes 0-4 of the serNum to bytes 0-4 of crd_buf.
However for the second card you're copying bytes 5-9 of serNum to bytes 5-9 of crd_buf.  That's correct for crd_buf but wrong for serNum.
The right way would be to add card_no*5 to i when creating the index:
      for(byte i=0; i<5; i++){
        crd_buf[(card_no*5) + i] = rfid.serNum[i];}

Or better to define your card buffer as a 2D array so you don't need to do that calculation:
byte crd_buf[CARDS][5];

for (i = 0; i < 5; i++) {
    crd_buf[card_no][i] = rfid.serNum[i];
}

Or simpler:
memcpy(crd_buf[card_no], rfid.serNum, 5);

For your second question, don't print your message at all in the loop.
Instead start out assuming that access is denied. Then if a card matches, grant access.  The simplest way is with a flag.
if (rfid.readCardSerial()){

    bool accessGranted = false;  // A flag to store the state - start off denied.

    for(byte i=0;i<card_no;i++){
        if(!memcmp(crd_buf+(i*5),rfid.serNum,5)){
            accessGranted = true;
        }
    }

    // replace these with your own message routines.
    if (accessGranted) {
        Serial.println("Access Granted");
    } else {
        Serial.println("Access Denied");
    }
}

Comments are not for extended discussion; this conversation has been moved to chat.


text:
Why is no PWM signal generated using Timer 2?
I managed to work with timer 0 and 1 but am unable to generate a PWM with timer 2 in my atmega328p.
This is the code:
#include <avr/io.h>

int main(void)
{
    /* PD6 output */
    DDRD |= (1 << DDD6);

    /* 50% duty cycle */
    OCR2A = 128;

    /* fast PWM  */
    TCCR2A |= (1 << WGM21) | (1 << WGM20);

    /* prescaler = 8 */
    TCCR2B |= (1 << CS21);

    while (1);

}

Could someone explain what the issue is and why I am not seeing a pwm signal on pin 6 of my arduino uno board?
Thanks

The post is definitely on topic.  I don't understand why it has attracted a vote to be closed.

I am the one who up-voted the question, one of the three up-votes for the answer, and just up-voted your comment :)

It's a shame that multitudes of "leave open" votes don't cancel our erroneous "off-topic" votes. Clearly on-topic. And timers are always such fun! :)

The output compare unit of timer 2 is connected to pins PB3 (OC2A) and PD3 (OC2B). So you have to configure those as outputs.
Keep in mind that you can't choose any pin when using hardware pwm, this hardware feature is linked to specific pins.
You also have to set COM2A1 in TCCR2A. Otherwise OC2A is disconnected from the output compare unit (ref: Table 17-3 in datasheet).
The effect of COM2A0/1 depends on the configuration in WGM20-WGM22.
The same applies to OC2B respectively.

I tried what you suggested, but that doesn't seem to work: https://paste.ubuntu.com/p/K8KmKnqyvV/
Any suggestions?

I compiled/flashed your code and I found that in TCCR2A you have to set COM2A1 (see my edit).

@traducerad: The comment // enable timer 2 in your code is wrong. It should be // disable timer 2 in order to be consistent with what the following line actually does.


text:
Multiple void loops with ESP8266
I want to run multiple sketches on one sketch. I use the method of multiple void loops. It works but esp8266 take a lot of time to execute commands.
void Setup()
 {
  setup1();
  setup2();
 }
void loop()
 {
  loop1();
  loop2();
 }

Is there any method to avoid that ?

You should re-factor your code so it only uses one setup and loop function.

have you considered using multitasking?

@SimSon The Arduino doesn't support multitasking. It's a very basic microcontroller. It has a setup() function and a loop() function and that's it.

the OP seems to use an ESP8266. As far as I know there are libraries for multitasking. At least for the ESP32 I know for sure. Even on an atmega there are ways to implement multitasking, in my understanding the principle of multitasking has not much to do with the actual hardware.

@SimSon ESP32 has two cores, ESP8266 only one, so they're not the same

Without seeing what loop1 and loop2 do, it's hard to guess, but if esp8266 take a lot of time to execute commands then it doesn't matter how you write your code (multiple loop functions or put them all in one loop function) it's going to take just as long - the issue is in the code you haven't shown

@JarmondaX yes I'm aware of that. But even though multitasking might be managed differently, it still doesn't strictly depend on the hardware. Consider: even on the ESP32 one can run more than two tasks. Multitasking is pseudo-parallelism by principle. I have never used it on an 8266, but there seems to be https://github.com/nrwiersma/ESP8266Scheduler

@SimSon - OK, never considered that in such a tiny device :p

If the setup() or loop() functions call delay() then of course that will delay getting to the next function and will slow down the whole process.
The only way to deal with that is to rewrite the code, combining what you're calling and fixing it so that it takes into account the other work it needs to do.
Same thing if you call any blocking functions, like reading from Serial until you get a newline.
If that's not the case... well, the ESP8266 is a small, not particularly fast processor. If there are no delays or blocking functions then your code is running as fast as your code might run and you'll just have to live with it.

As long as you're not using delay() or other blocking code, as John mentions in his answer, that approach will work fine. I have a fairly large project where I defined a class ArduinoObject. The ArduinoObject class has a setup method and a loop method, and the main sketch creates and manages an array of ArduinoObjects (and another stack of a subclass of ArduinoObject called a MenuObject that manages menus on the LCD screen the project uses.)
At times there are a dozen or more ArduinoObjects being called on each pass through the sketch's loop() function and it works just fine. The key thing is to write your sub-loops to be FAST. They should do a tiny amount of work on each pass, and then a little more on the next pass (if needed.) You never want one of your sub-loops to take enough time to make the other sub-loops "stutter".


text:
Circuit diagram for running bipolar stepper motor using LDR
I am new to Arduino, some how I have put this code together to run stepper motor using LDR(kind of solar tracker program) I searched on net and tried using servo motor circuit to run stepper motor, assuming just replacing servo motor with stepper motor would work. I guess that is not the case (because servo motor is not moving according to LRD inputs). Please help me with circuit diagram.
Here is the code I am using

const int dirPin  = 5;
const int stepPin = 4;
const int enPin   = 6;
const int SensorPin1 = A0;
const int SensorPin2 = A1;
int sensorValue1 = 0;
int sensorValue2 = 0;

void setup() {

  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);

  pinMode(enPin,OUTPUT);
  digitalWrite(enPin,LOW);
  Serial.begin(9600);

}
void loop() {
  sensorValue1 = analogRead(SensorPin1);
  Serial.println(sensorValue1);
  sensorValue2 = analogRead(SensorPin2);
  Serial.println(sensorValue2);

  if(sensorValue1 < 40 && sensorValue2 < 400){
    Serial.print("No sun Detected");
    digitalWrite(dirPin,LOW);
    digitalWrite(stepPin,LOW);
  }
  else if(sensorValue1 > 400){

    digitalWrite(dirPin,HIGH);
    digitalWrite(stepPin,HIGH);

 }
else if(sensorValue2 > 400){
    digitalWrite(dirPin,LOW);
    digitalWrite(stepPin,HIGH);
}
}

Hardware Used:

Bipolar stepper motor- NEMA 23 20Kg torque
Stepper driver: TB6600
Power supply: SMPS 12V, 5amp
LDR: 2
Resistors: 2, 10K resistors
1 Arduino Uno
Breadboard

With most stepper drivers the stepper will move 1 (!) step when you put 1 pulse on the input (meaning a transition low-high-low or invers). Your code will at most drive the motor 1 step, most likely not enough to see it. Generate more pulses

Change digitalWrite(stepPin,LOW); to digitalWrite(stepPin,LOW);delay(1);digitalWrite(stepPin,HIGH);

Thanks @chrisl ..will try and let you know...but I am still looking for circuit digram

For the circuit diagram: Have you seen for example this User Guide on the TB6600? There it is mentioned, how the driver has to be connected to the Arduino and to the motor. You can even download the more detailed user guide as pdf.

If it helps, I tuned your code little.
const int dirPin  = 8;
const int stepPin = 7;
const int enPin   = 13;//with pin 13 You can monitor on-board LED, if its lit, "enable" is HIGH and stepper will turn.
const int rightSensorPin = A0;
const int leftSensorPin = A1;
int rightSensorRead = 0;
int leftSensorRead = 0;
int rightLightPct = 0;
int leftLightPct = 0;
int degreeChange = 1;

void setup() {
  Serial.begin(9600);
  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);
  pinMode(enPin,OUTPUT);
  pinMode(A0, INPUT_PULLUP);//no need extra resistors. Just connect one LDR leg to A0 and another GND.
  pinMode(A1, INPUT_PULLUP);
}

void loop() {
  rightSensorRead = analogRead(rightSensorPin);
  leftSensorRead = analogRead(leftSensorPin);
  rightLightPct = map(rightSensorRead, 0, 1023, 0, 100);
  leftLightPct = map(leftSensorRead, 0, 1023, 0, 100);
  degreeChange = map(abs(rightLightPct-leftLightPct),0,100,2,10);
  Serial.print("right = ");
  Serial.print(rightSensorRead);
  Serial.print(" left = ");
  Serial.print(leftSensorRead);
  Serial.print(" Pct r/l = ");
  Serial.print(rightLightPct);
  Serial.print("/");
  Serial.println(leftLightPct);
  if(rightLightPct < 15 && leftLightPct < 15){
    Serial.println("Sun is detected");
    digitalWrite(enPin, LOW);
    digitalWrite(dirPin,LOW);
    digitalWrite(stepPin,LOW);
    delay(5000);//if somthing get in a way, program waits 5 sec. If nothing in that time, program will continue. That time may erase or add some more.
  }else if(rightLightPct > 50 && leftLightPct > 50){
    Serial.println("Sun is set!");
    digitalWrite(enPin, LOW);
    digitalWrite(dirPin,LOW);
    digitalWrite(stepPin,LOW);
  }else if(rightLightPct > 20 && leftLightPct > 20){
    Serial.println("Seeking sun!");
    digitalWrite(enPin, HIGH);
    digitalWrite(dirPin,LOW);
    digitalWrite(stepPin,LOW);
    delay(1);
    digitalWrite(stepPin,HIGH);
  }else if(rightLightPct > leftLightPct){
    Serial.println("Turning CW!");
    digitalWrite(enPin, HIGH);
    digitalWrite(dirPin,HIGH);
    digitalWrite(stepPin,LOW);
    delay(1);
    digitalWrite(stepPin,HIGH);
  }else{
    Serial.println("Turning CCW!");
    digitalWrite(enPin, HIGH);
    digitalWrite(dirPin,LOW);
    digitalWrite(stepPin,LOW);
    delay(1);
    digitalWrite(stepPin,HIGH);
  }
}


text:
Wire with MCP23008 I/O expander with I2C
I'm trying to read from an MCP23008 I/O expander using the Wire library over I2C. The MCP23008 is wired to address 0x04, giving an effective device address of 0x24. Writing to the device GPIO seems to work fine, and I'm a bit confused on how to read from the GPIO.
So I set it up for read as follows:
#define MCP23008_DEVICE_I2C_ADDRESS 0x20
#define MCP23008_SLAVE_I2C_ADDRESS  0x04

#define MCP23008_REGISTER_IODIR     0x00
#define MCP23008_REGISTER_GPIO      0x09

#define IO_ALL_PINS_INPUT           0xFF

inline void eeprog::_read_enable()
{
    Wire.beginTransmission(MCP23008_DEVICE_I2C_ADDRESS | MCP23008_SLAVE_I2C_ADDRESS);
    {
        Wire.write(MCP23008_REGISTER_IODIR); // Set I/O direction
        Wire.write(IO_ALL_PINS_INPUT);       // Set all pins as input
    }
    Wire.endTransmission();
}

after which I attempt to read from it, by first addressing the GPIO register and then requesting a byte to read:
inline uint8_t eeprog::_read()
{
    Wire.beginTransmission(MCP23008_DEVICE_I2C_ADDRESS | MCP23008_SLAVE_I2C_ADDRESS);
    {
        Wire.write(MCP23008_REGISTER_GPIO); // Select the GPIO register
    }
    Wire.endTransmission();

    Wire.requestFrom(MCP23008_DEVICE_I2C_ADDRESS | MCP23008_SLAVE_I2C_ADDRESS, (uint8_t)1);

    return Wire.read();
}

Looking at my logic analyzer this is what I get:

The NACK seems to indicate that the read went wrong.. actually a bit unsure what "Data read: 07" means in this context, did it read the value 7, or did it try read address 07?
Any ideas what I could be doing wrong? Am I missing something obvious from the documentation?

Everything is fine and nothing is wrong.
You are reading the GPIO register and its contents is 0x07.
The NACK at the end is not an error, it is a way to communicate between the Master and Slave.
When the Master reads data, the Master gives an ACK after each databyte from the Slave. The Master is not trying to tell the Slave that it was received, but rather it tells the Slave that another byte is going to be read.
After the last databyte, the Master send a NACK and after that a STOP.
Since only one byte is read, the Master sends a NACK and a STOP. The Master is telling the Slave that no more data is needed.
The I2C bus is only two wires. There are START, STOP, ACK and NACK conditions and the clock pulse can be stretched by a Slave. The possibilities are limited. For example when the Master wants to read 6 bytes and the Slave has only 1 byte. The Slave has no way to tell the Master that it has only 1 byte, and the Master will read those 6 bytes, valid or not.

Thank you. I just assumed that the NACK condition indicated an error since I previously had written my "write" code wrong and got NACK on the bus.


text:
How to calibrate the MQ7 sensor module?
I recently bought a MQ7 sensor module like the one in the attached picture. I have read several tutorials, and they're all different. Some of them says that i need to connect the module directly to 5v and wait 24 hours to made it work properly, others says that i need to program different periods (5v and 1.4v) and wait the same time to make correct meditions. I read this Datasheet, but i think that the information it has is not for the module.
If anyone knows how to setup this module i will aprecciate an answer (i want to read analog values).
Thanks in advance and sorry for my bad english.

first of all, you need to understand how these sensors work.

the sensor itself is just a resistor (like a normal resistor, with 2 legs) which is constructed from materials that are affected in presence of a specific gas. the gas changes its resistance. but as it's obvious, these type of materials are not calibrated.
in order to make that resistor sensitive enough, we have to warm it. so the manufacturer puts a simple coil element near the resistor in the capsule and you connect it to 5v. it warms up (it draws a lot of current) and thus, the effect of gas on the resistor becomes greater and we can measure it easily. when they say connect and let it be for 24 hours they mean warming up the resistor. I think it's a little high. I used them after a few minutes of warming up but it depends on situation and desired precision.
the resistor and element, have separate pins and are completely independent. you have to connect the coil to 5v (because manufacturer made it like that) and use the resistor anyway you like. even with a ohmmeter.
as we have to use Arduino, so we have to measure a resistor with the ADC of Arduino. the procedure is straightforward. you put a normal resistor in series with the sensor resistor and make a voltage divider (search that if you don't know about it. it's a fundamental thing to know in electronics).I think there should be a schematic in datasheet for it. and you measure the voltage with ADC.

and some notes :

you have to use A0 pin of the module if you want reading the value like the procedure above. this pin is the output of voltage divider(the sensor + blue pot on the board) and should be connected to ADC.
the D0 is just the output of another circuit present on board for another purpose. it's a comparator output. it's used for situations where you only need to do something (like turning emergency lights on and off) when the gas goes up from a level. you don't read anything with ADC. you just turn the pot to set a threshold (that's empirical) and digital pin get high and low according to that.
the voltage divider's GND and VCC are connected to GND and VCC of heating element accordingly. so you have just one pair of GND/VCC

So basically i just need to connect it to the respectives pins and wait to let the module heat. No different periods (5v and 1.4v) nedeed in the code, right?