text:
Multiplexing a piano keyboard with arduino nano
I'm trying to use a cheap keyboard with 37 keys as a MIDI controller by reading the multiplexed keys with an Arduino nano. The keys are grouped in six groups with a max of 8 keys per group. Which results in my setup of 8 digital INPUTS which are pulled HIGH, and 6 OUTPUTS, which are pulled LOW, when reading that group of keys.
This works great when I only have 3 groups in my loop. However whenever I add another group it does not work anymore. It doesn't matter which groups are activated.
One group reading looks like this:
digitalWrite(A0, LOW);
for (byte j = 12; j > 4; j--)
{
  uint8_t note = offset + 20 + (12-j);
  uint8_t key_state = digitalRead(j);

  if ( (key_state == 0) && (notes_pressed[note] == 1) )
  {
    notes_pressed[note] = 0;
    Serial.write(note + 100);
  } else if ( (key_state == 1) && (notes_pressed[note] == 0) )
  {
    notes_pressed[note] = 1;
    Serial.write(note);
  }
}
digitalWrite(A0, HIGH);

With A0 being the group pin.
I think this has to do with the pins not being able to be pulled low as quickly because of weak output drivers or something similar. Unfortunately I don't have an oscilloscope to check the levels.
I have added delays to ensure the levels have settled when the reading occurs but to no avail.
Edit:
Schematic is pretty much just this. The diodes in the keyboard I left out, but they are there as necessary:

#include "HardwareSerial.h"

#define offset 48

void midi_note_off(byte channel, byte key, byte velocity);
void midi_note_on(byte channel, byte key, byte velocity);
void midi_command(byte command, byte channel, byte param1, byte param2);

byte notes_pressed[37];
void setup() {
  Serial.begin(115200);
  pinMode(12, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(A0, OUTPUT);

  digitalWrite(4, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(2, HIGH);
  digitalWrite(A0, HIGH);
  digitalWrite(A1, HIGH);
  digitalWrite(A2, HIGH);
}

void loop() {
  digitalWrite(4, LOW);
  for (byte j = 8; j > 4; j--)
  {
    uint8_t note = offset + (8-j);
    uint8_t key_state = digitalRead(j);

    if ( (key_state == 0) && (notes_pressed[note] == 1) )
    {
      notes_pressed[note] = 0;
      Serial.write(note + 100);
    } else if ( (key_state == 1) && (notes_pressed[note] == 0) )
    {
      notes_pressed[note] = 1;
      Serial.write(note);
    }
  }
  digitalWrite(4, HIGH);

  digitalWrite(3, LOW);
  for (byte j = 12; j > 4; j--)
  {
    uint8_t note = offset + 4 + (12 - j);
    uint8_t key_state = digitalRead(j);

    if ( (key_state == 0) && (notes_pressed[note] == 1) )
    {
      notes_pressed[note] = 0;
      Serial.write(note + 100);
    } else if ( (key_state == 1) && (notes_pressed[note] == 0) )
    {
      notes_pressed[note] = 1;
      Serial.write(note);
    }
  }
  digitalWrite(3, HIGH);

  digitalWrite(2, LOW);
  for (byte j = 12; j > 4; j--)
  {
    uint8_t note = offset + 12 + (12-j);
    uint8_t key_state = digitalRead(j);

    if ( (key_state == 0) && (notes_pressed[note] == 1) )
    {
      notes_pressed[note] = 0;
      Serial.write(note + 100);
    } else if ( (key_state == 1) && (notes_pressed[note] == 0) )
    {
      notes_pressed[note] = 1;
      Serial.write(note);
    }
  }
  digitalWrite(2, HIGH);

  digitalWrite(A0, LOW);
  for (byte j = 12; j > 4; j--)
  {
    uint8_t note = offset + 20 + (12-j);
    uint8_t key_state = digitalRead(j);

    if ( (key_state == 0) && (notes_pressed[note] == 1) )
    {
      notes_pressed[note] = 0;
      Serial.write(note + 100);
    } else if ( (key_state == 1) && (notes_pressed[note] == 0) )
    {
      notes_pressed[note] = 1;
      Serial.write(note);
    }
  }
  digitalWrite(A0, HIGH);

  digitalWrite(A1, LOW);
  for (byte j = 12; j > 4; j--)
  {
    uint8_t note = offset + 28 + (12-j);
    uint8_t key_state = digitalRead(j);

    if ( (key_state == 0) && (notes_pressed[note] == 1) )
    {
      notes_pressed[note] = 0;
      Serial.write(note + 100);
    } else if ( (key_state == 1) && (notes_pressed[note] == 0) )
    {
      notes_pressed[note] = 1;
      Serial.write(note);
    }
  }
  digitalWrite(A1, HIGH);

  digitalWrite(A2, LOW);
  for (byte j = 5; j > 4; j--)
  {
    uint8_t note = offset + 36 + (5-j);
    uint8_t key_state = digitalRead(j);

    if ( (key_state == 0) && (notes_pressed[note] == 1) )
    {
      notes_pressed[note] = 0;
      Serial.write(note + 100);
    } else if ( (key_state == 1) && (notes_pressed[note] == 0) )
    {
      notes_pressed[note] = 1;
      Serial.write(note);
    }
  }
  digitalWrite(A2, HIGH);
}

I know the last part looping over a single value is unnessecary but it should still work.

The Arduino outputs are about 25 Ω, whereas the internal pull-up is roughly 30 kΩ, so a single OUTPUT LOW can pull low many INPUT_PULLUP pins. Could you show the schematic of your keyboard + Arduino setup?

You have unbalanced parentheses on line 82.

Thanks, that must have happened while pasting here!

your for loops are messed up ......the order of keys in the columns is not all the same (if your schematic is correct) ... first column is 5 to 8 ... second column is 12 to 5 ... third column is 5 to 12 ... fourth column is 5 to 12 ... fifth column is 12 to 5 ... sixth column is a single key that does not require a for loop

stop calculating note ...  note = offset + 20 + (12-j) ... use increment instead ... note++

A few excerpts from the program:
#define offset 48
//...
byte notes_pressed[37];  // valid indices: 0 – 36
//...
uint8_t note = offset + (8-j);  // j ≤ 8, thus note ≥ 48
//...
notes_pressed[note] = 0;

That last line writes past the end of the notes_pressed array, and
overwrites who knows what in memory. This could be the source of the
issue you are facing.

There are several issues to be considered when designing a switch matrix for an embedded processor regardless if it is a musical or computer keyboard:

Contact bounce: This is more important for a computer keyboard
then a musical keyboard.  However if the switch are particularly
bad, it may audible.  Software may be used to mitigate the problem
but will also add delay between the key press and the beginning of
the note's sound.
Pull Ups: Any logic input should not be left unconnected or
floating.  This can lead to unexpected results.  Use Pull Up
resistors (or Pull Down depending on your design) to mitigate this
problem.  The Arduino Uno's embedded processor (the
ATmega328P) comes with built in Pull Up resistors.
The Arduino IDE abstracts this feature by including a parameter it
the pinMode() function call to invoke this feature.
Rollover: In a switch matrix 1 or 2 simultaneous switch
closure can be uniquely detected.  However, if 3 switch closures
connect 2 rows and 2 columns together, they can not be uniquely
detected.  This is because current can flow through the 3 closed
switches activating both rows and both columns nullifying the
ability for the embedded processor to scan individual rows or
columns.  To mitigate this problem a diode is added to all
switches in the switch matrix such that there is no current path
between rows or columns.

From the Rollover wikipedia page:

Most music keyboards use isolation diodes in their keyboard matrix to
implement full n-key rollover, making them immune to both key ghosting
and key jamming

This image if from this stack exchange question:

Thanks for your input.

This is something I want to mitigate later if necessary. However now I don't get any reaction to button presses or releases.
I am using the Arduino Pull Ups
The keyboard I bought has these diodes built-in

Sounds like you have already taken into account the basics.  Wait ... I thought you did manage to create some notes?  If you are creating no notes that means anything could be wrong including the MIDI player!  Hummm ... you should start over then.  Check all your wiring (using test equipment if you have any).  Then use a version of your code that does not change between different columns.  Then try 2 columns.  Add delays in the code after changing columns to see if that helps.

Sorry I worded that wrongly. I get no reaction to button presses, whenever I uncomment more than three columns in the loop. It does not matter which ones are commented, the other ones react properly. I tried with some delays, but I will try to add these in different places, to maybe get a different behaviour.

Re “built in Pull Up and Pull Down resistors”: The Uno has built-in pull-ups, but no pull-downs. Re “if two switch closures occur in the same row or column, they can not be uniquely detected”: It seems to me you need at least three switches to be pressed in order to create this sort of ambiguity.

No pull downs?  My bad - I corrected the answer.  If scanning by lowering the column voltages and 2 columns are electrically connected by 2 closed switches in the same row (w/no diodes) then I do not see a way to tell the difference ... oh, I see what you mean.  You don't need to tell the difference.  You just need to detect they are both closed.  Ok, I'll fix that too.


text:
Returning struct from function generates 'does not name a type' compilation error
I have a main.ino file that contains
struct EulerAngles {
  double roll, pitch, yaw;
};

void setup() {
  EulerAngles angles;
  angles = anglesCalc();
  Serial.print(angles.yaw);
}

void loop() {
  Serial.println("In loop");
  delay(1000);
}

and an angles.ino file that contains
EulerAngles anglesCalc(){
   EulerAngles a;
   // calculate a
   return a;
}

When I compile the program, I get a compile error in the main.ino file:
   code/so_examples/main.ino:5:1: error: 'EulerAngles' does not name a type
 void setup() {
 ^~~~~~~~~~~
code/so_examples/main.ino: In function 'void setup()':
code/so_examples/main.ino:7:12: error: 'anglesCalc' was not declared in this scope
   angles = anglesCalc();
            ^~~~~~~~~~
code/so_examples/main.ino:7:12: note: suggested alternative: 'angles'
   angles = anglesCalc();
            ^~~~~~~~~~
            angles
[Build] Error occurred.

How do I fix this? Note that struct is declared before all else, so this answer does not seem to apply.  I am using the Stino plugin for Sublime Text as the IDE.

The original question was a paraphrase of a much larger program, but in that program, I did move the struct up to the top and it did not fix the problem. I have now set up a dummy program that reproduces the problem (has the struct at the top), and have modified the question to show that real code and also the real compiler error message.

what IDE do you use? the main ino file must be named as the sketch folder so_examples.ino to be concatenated by the Arduino builder before the other ino files. the files are concatenated in the order of Arduino IDE tabs. https://arduino.github.io/arduino-cli/latest/sketch-build-process/

Renaming main.ino to so_example.ino does not help. But I am using Sublime Text with the Stino plugin. If I open the renamed file using the Arduino IDE and compile, it works fine. So it looks like a problem with the Stino/Sublime Text IDE.

Arduino IDE doesn't allow to open a ino which is not in a folder with the same name

Good idea.  The trouble with the Ardino IDE on a Mac running Big Sur is that it is unstable, it keeps crashing on me.  As well, it does not seem to have any syntax checking in the editor, plus I do all my development work in Sublime Text.  I will raise an issue on the Stino plugin and just stop trying to use functions which return structs until issue is rectified.  Thanks to all  that helped to resolve this.

There is an open issue with structs with the Sublime Text plugin. I have added an answer with the details.  I plan to delete all my comments on the question/answer, as are out of date and just add noise.

There is an open issue with the Stino Arduino plugin for Sublime Text which means that structs are not handled properly.
Thank you to Jura and Edgar Bonet for helping me to answer this question.

the orignal question didn't mention Stino

I believe that the final form of the question and and accepted answer should be as clear, and if possible, not require reading comments to understand it.  By editing the question to add the Stino clarification, it makes it clear it is not a redundant question.  Deleting unnecessary or out of date comments also enhances the clarify of the Q and A.  However, I notice you have a lot more experience in this community than me (I normally am on SO), so prepared to take your advice on this matter. I have added an acknowledgement of your and Edgar Bonet's assistance in my answer.

I would avoid having multiple .ino files, because of the issues raised
in the other answers. If you want to split your code into multiple
files, the scheme that works reliably is to have:

a single .ino file, named like the containing folder, holding the
“main” program (this is Arduino-specific)
a pair of .h/.cpp files for each “module” implementing a sub-feature
of the program (this is common C++ practice).

Within the .h/.cpp pair, the .h file declares everything the compiler
needs for understanding code that uses the feature: type definitions
(including classes) and function prototypes. The .cpp file holds the
actual implementation.
Applying this scheme to your case would give:
my-sketch.ino (actually, with the name of the containing folder):
#include "angles.h"

void setup() {
  EulerAngles angles;
  angles = anglesCalc();
  Serial.print(angles.yaw);
}

void loop() {
  Serial.println("In loop");
  delay(1000);
}

angles.h:
struct EulerAngles {
  double roll, pitch, yaw;
};

EulerAngles anglesCalc();

angles.cpp:
#include <Arduino.h>
#include "angles.h"

EulerAngles anglesCalc() {
   EulerAngles a;
   // calculate a
   return a;
}

Note that including <Arduino.h> is only useful if the code uses the
Arduino core API. Otherwise you can omit it. The main sketch does not
need to include <Arduino.h> because it is implicitly included in the
.ino file by the Arduino IDE. There is no such implicit inclusion when
the IDE processes .cpp files.

it is much easier to use multiple ino files then maintain a .h files

Try to add struct at the first of function, such as:
struct EulerAngles anglesCalc(){
   EulerAngles a;
   // calculate a
   return a;
}

source: Stack Exchange

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

sort: votes


text:
Analog input voltage rises when motor is working
I'm making automatic water plant system. I'm using:
Arduino Uno
3.3-6V water pump -https://www.amazon.com/Vipe-Micro-Submersible-Motor-Water/dp/B01N0X3CW4
Capacitive soil moisture sensor - https://www.amazon.com/Gikfun-Capacitive-Corrosion-Resistant-Detection/dp/B07H3P1NRM
I've noticed that when motor turns on sensor readings are much higher. First I thought that the problem is in sensor, but when I measured sensor output in both cases (when motor is on and when motor is off) there was no difference, voltage was the same. Then I measured voltage in analog pin A0 that I used, and I saw there is increase in voltage when pump is on (+0.4V), so my guess is that this voltage is added to  sensor output voltage which is giving me higher values in my serial monitor.
For powering my pump I'm using same circuit as in this example:
https://www.devacron.com/arduino-tip120-control-dc-motor/
Just except potentiometer there is my sensor, powered via 3.3V Arduino pin (its GND is connected to Arduino GND). I also tried connecting all grounds together in one point, didn't help. I powered Arduino with usb and with 9V supply, in both cases same problem. Tried powering pump and Arduino with same and with different power supplies, no luck either.
I should also add that there is no change in AREF and 5V pin when pump is working. 4.97V in both cases.
Does anyone have any idea what can be the problem and how to solve it?
Here is how I wired everything:
https://i.sstatic.net/8IDQR.jpg
I also tried with 0.1uF ceramic and 10nF electrolytic capacitors. as suggested, wiring it like this: https://i.sstatic.net/fNQnX.jpg
Didn't make much difference, problem is still there.

Nothing coming to mind immediately, at least nothing I have good reason to think is actually the problem.  Even with the reference diagram and understanding how you've effectively replaced the potentiometer with the sensor, it would be good to have a picture of the actual wiring.  Sometimes it just reveals things you didn't think to mention.

My first thought is that you have a noise problem with either the sensor itself picking up noise and misinterpreting it as input or noise being picked up by the analog pin and interfering with your readings.  You might try it without the pump motor hooked up so that you can isolate the problem.

@jwh20 without the motor, sensor reading are stable when connected to analog pin. Can there be a problem with Arduino? I do not have other just this one, but I don't know what are the chances that something is wrong...I bought it just for this project and I must also add that in this project I had a lot more components connected (I removed everything except pump and sensor to try to isolate the problem, just as you said) and everything else works great, even bme280 sensor and oled display, which are connected to A4 and A5 pins. Maybe is noice from the pump...But I can't remove it completely...

Why don't you show how you have things hooked up?  I suspect you have either a power supply issue or a noise issue caused by the motor.  You either need to beef up the supply to your motor and/or filter the noise being produced by it.

@timemage  I will draw what I've done, no problem and edit my main post

That may help.  But clear actual pictures of real wiring won't hurt.

@timemage jwh20 I added link in my first post hope it's clear enough

Try adding some bypass capacitors across the motor leads and also from Vcc to GND at the moisture sensor.

I have only one thought beyond what jwh20 has said, but it's dependent on your 2.2k resistor not really being 2.2k.

@timemage  Yes, It is actually a 2k resistor on the picture, not 2.2 you are right, I made I mistake. I'm pretty sure though it's not a current problem. I also tried with higher value resistors, even tried just turning the motor on all the time directly from power source, without that transistor circuit and signal from Arduino, just motor, diode, sensor and Uno, with only grounds connected together and same thing happened. So I hope that  capacitors will solve my problem.

The diode on your schematic drawing is in the wrong configuration. It supposed to connect across the motor with cathode to 5V and anode to the join of motor and the collector pin of TIP120. See what is a protection diode for explanation. You get it wrong because the link that you provided has a wrong connection too.

@hcheung, compare with the image of the actual wiring.  They probably just got it backwards trying to make the diagram quickly.

Try adding some bypass capacitors at the two points I've added arrows to:

I suggest two in each spot, one a 0.1uF (or similar) ceramic dipped or disc and the other a 1 or 10uF electrolytic.  Keep the polarity in mind for the electrolytic.
Oh, and another thing.  Be sure your motor is not pulling your power supply voltage down.  It's possible your phone charger supply is inadequate to supply the power needs of the motor.  Use a voltmeter across the input to the Arduino and check the voltage when the motor runs.  If it's dropping much below 5V you need a better power supply.  Well, I see now that you are only powering the motor from that 5V supply.  So that's probably not it.

Thank you very much for suggestion. Unfortunately, I don't have them right know at my place, but I could get them tomorrow when shops are open, so I will post results then :)

ok I tried with capacitors, one 0.1uF ceramic, and one 10uF electrolytic where I put longer lead to + side and shorter to -. I can get a picture of my circuit if it's needed if you think I maybe wired it bad. Didn't help. Sensor value in water is 250 and when motor is on, in a few seconds value goes up to 450, then it goes down to 400 in about 30 seconds and that's it...

Please update your question with a photo of what you've tried.

ok I added and put a photo hope it's clear enough

It's clear there is some sort of interference caused by the motor or your motor control circuit that is causing the reading from what I suspect is a very sensitive "antenna" moisture sensor and the caps are just not enough.  How about a different approach?  You might try pumping water for a few seconds and then stopping the pump and taking a series of readings over a few minutes until the values stabilize.  Then repeat as needed until you get to the moisture reading you want.

I already did that in my code, before even asking this question. I'm reading from sensor every two minutes which is more then enough from values to stabilize, so it's not affecting functionality of my project at all. However, I asked this question because I was pissed that I couldn't find solution. I googled, read many forums, solutions, and nothing worked so I decided to ask here in case that maybe someone would have any new idea. Is it possible that Arduino is faulty? I'm not planning to buy a new one, but I would like to know where the problem is :) Thank you anyways :)

I doubt the Arduino is defective. These types of issues can be difficult to track down but it's also exacerbated by the way you have constructed this so far, specifically with wires going all over the place being quite long, no shielding, etc.  Since we addressed, to some degree at least, the power, the next is noise being introduced into the analog input line from your sensor.  Don't feel bad about this, you're at the interface between theory and real-world issues.  Noise problems keep engineers up at night!

This particular sensor just generated an analog signal and the ADC in the Arduino just reads that voltage.  You might also try putting a capacitor, try a smaller one like your 0.1 uF, from that signal line to GND.  That will help to "slow down" the signals on that line.  You not really needing to take readings quickly in this application since you really are not ever changing the moisture content quickly.

Thank you for suggestions :))

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


text:
W5100 Ethernet Shield to Custom Board Problem
I've been using an Arduino Ethernet shield and an Arduino Mega in my project, but now I'm trying to migrate all the components onto my own PCB. My board uses a W5100 same as the Arduino, but nothing shows up when I connect Ethernet to my computer. Even if there is no communication with the MCU the W5100 should show up as a network device and starting pinging.
I have spent A LOT of time troubleshooting this issue, and I would like to confirm one thing. Using the factory default register settings, I should be able to just connect the W5100 to my computer, and it will start pinging back and forth and be identified as a network device . . . assuming I have the circuit set up correctly just like the Ethernet shield. I used a combination of the recommendations from Wiznet and the Arduino Ethernet shield schematic to make mine.
Edit:
Here is my schematic for the Ethernet module. The question I'm really trying to get answered first is regarding the default state of the W5100. Do I need to set some registers or something to get the W5100 in the same state it is in on the Arduino shield?

Sorry, I'm confused - Have you already made your own PCB combining both the Arduino Mega and the W5100 ethernet shield circuitry? Also more details will help the SE community suggest some answers.

A picture or even a schematic would be apreciated.

A bit late to the party but... it may be that you are using pins 1, 2, 3 and 4 instead of 1, 2, 3 and 6 on the RJ45. It is unclear whether you are connecting via a header, in which case you my disregard this, or straight to the RJ45, in which case you need to change your pin:
1. white/orange
2. orange
3. white/green
6. green

You need to connect the SCS pin of W5100 to Arduino mega 2560 PB4 pin (pin number 23 raw IC pin number). Then only the W5100 will be selected in active mode.
for reference: https://www.arduino.cc/en/Reference/Ethernet
"Arduino communicates with the shield using the SPI bus. This is on digital pins 11, 12, and 13 on the Uno and pins 50, 51, and 52 on the Mega. On both boards, pin 10 is used as SS. On the Mega, the hardware SS pin, 53, is not used to select the W5100, but it must be kept as an output or the SPI interface won't work."

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


text:
Problem understanding code
This is a segment of an Arduino sketch, that I am trying to understand.
I know that the purpose of the entire code is to control 2 stepper motors linked to their respective drivers which are linked to a Mega 2560, but since I am new to Arduino, I am having problems with some functions.
This is a segment of the code. I am having problems with some statements such as unsigned short FLG = 0; and I cannot make out at all the timer interrupts part.
What does it all mean?
/* The “define” function is NOT A PROGRAMMING STATEMENT. Actually it sets up a macro which causes a text replace to occur before code is compiled. The pre-processor of the IDE will replace the variables such as “stp” to the integer value 22 in the following subsequent sections like the “void setup” function and the “loop” function if they are called. This function helps reduce RAM usage. */

#define stp 22
#define dir 23
#define stp2 26
#define dir2 27
#define EN  24
#define dir_ 25

int i, j, t, X = 0, Y = 0, Z = 0;
// here, the integer is creating variables such as i, j, t
//and also assigning values to some of them such as X, Y and Z.

unsigned short FLG = 0;

unsigned int Speed1 = 0, Speed2 = 0; // creating variables assigning initial values; due to unsinged only positive

int ser_1[3];

int po(int, int);

void setup() {     // You define how your Arduino will be used and set up any pins and communications you will be using. This will run first and only once.

  Serial.begin(9600); // begin the data transmission between Arduino and pc at speed of 9600 bits per sec
  delay(500); // stop for 500 milliseconds

  Serial.println(“hi”); // this will print the word “hi” on the serial monitor window on pc via serial port

  pinMode(stp, OUTPUT); // tells arduino to use digital Pin 22 to output electricity
  pinMode(dir, OUTPUT); // tells arduino to use digital Pin 23 to output electricity
  pinMode(stp2, OUTPUT); // tells arduino to use digital Pin 26 to output electricity
  pinMode(dir2, OUTPUT); // tells arduino to use digital Pin 27 to output electricity
  pinMode(EN, OUTPUT); // tells arduino to use digital Pin 24 to output electricity

  noInterrupts(); // to prevent disruption of timing of codes, disables some functions in the background

  /* To use timers, the built-in timer registers on the AVR chip that store timer settings need to be configured.  There are a number of registers per timer.  Two of these registers –the Timer/Counter Control Registers- hold setup values, and are called TCCRxA and TCCRxB, where x is the timer number (TCCR1A and TCCR1B, etc.).   Each register holds 8 bits, and each bit stores a configuration value. */

  TCCR1A = 0x80; //
  TCCR1B = 0x0A; // Enable reset on compare match, 1:8 clock. don’t understand
  OCR1AH = 0x9C;
  OCR1AL = 0x3F;
  TIMSK1 = (1 << OCIE1A); // enable timer compare interrupt
  interrupts();
}
ISR(TIMER1_COMPA_vect)   // timer compare interrupt service routine
{
  res();
}
void loop(){

if(Serial.available())
 {
  ser_1[i] = Serial.read();
  char ch = Serial.read();
if(ch==’S’)
   { i=0;
     X=0;
     while(1)
{
  if (Serial.available() > 0)
     {
      ser_1[i]=Serial.read();
      ser_1[i]=ser_1[i]-48;
      X=X+(ser_1[i]*(po(10,i)));
      i++;
     if(i==3)
       {
        FLG++;
        break;
        }
      }
    }
}

if (ch==’A’)
  { i=0;
    Y=0;
     while(1)
     {
        if (Serial.available() > 0)
      {
      ser_1[i]=Serial.read();
      ser_1[i]=ser_1[i]-48;
      Y=Y+(ser_1[i]*(po(10,i)));
       i++;
      if (i==3)
          {
           FLG++;
           break;
           }
          }
        }
      }

     if(FLG==2)
    {
      Speed1=X;
      Speed2=Y;
      digitalWrite(EN,LOW);
        delay(100);
      StepForwardDefault();
        delay(1000);
      StepForwardDefault2();
         delay(1000);
      ReverseStepDefault2();
      ReverseStepDefault();
      delay(1000);
      digitalWrite(EN,HIGH);
      delay(1000);
      }
      else
      Serial.println(“sequence is stop”);
}
 /*****************po******************/

int po(int num, int pow)
{ int result=1;
  if(pow==0)
  return 1;
  else
 {
  for(int f=1;f<=pow;f++)
    {
  result=result*num;
    }
 return result;
 }
}

/************ MOTOR 1 Function *****************/

void ReverseStepDefault()
{
  Serial.println(“motor a reverse”);
  Serial.println(“Moving in reverse at default step mode.”);
digitalWrite(dir_, HIGH); // Pull direction pin high to move in “reverse”
digitalWrite(dir, LOW);
delay(100);
for(int x=1; x<200; x++) // Loop the stepping enough times for motion to be visible
{
  digitalWrite(stp, HIGH); //Trigger one step
  delay(305-X);
  digitalWrite(stp, LOW);  // Pull step pin low so it can be triggered again3
  delay(305-X);
  }
}

/************ MOTOR 2 Function *****************/

void ReverseStepDefault2()
{
  Serial.println(“Moving b reverse”);
  digitalWrite(dir_, HIGH); // Pull direction pin high to move in “reverse”
  digitalWrite(dir2, LOW);
  delay(100);
  for(int x =1; x<200; x++) // Loop the stepping enough times for motion to be visible
  {
   digitalWrite(stp2,HIGH); // Trigger one step
   delay(305-Y);
   digitalWrite(stp2,LOW); // Pull step pin low so it can be triggered again3
   delay(305-Y);
   }
}

void StepForwardDefault2()
{
   Serial.println(“motor b forward”);
   digitalWrite(dir_,HIGH); // Pull direction pin high to move in “reverse”
   digitalWrite(dir2,HIGH);
   delay(100);
   for(int x=1; x<200; x++) // Loop the forward stepping enough times for motion to be visible

{
  digitalWrite(stp2,HIGH); // Trigger one step forward
  delay(305-Y);
  digitalWrite(stp2,LOW); // Pull step pin low so it can be triggered again
  delay(305-Y);
    }
}

void res()
 {
   if(Serial.available())
  {
   ser_1[i]=Serial.read();
   char ch = Serial.read();
   if(ch ==’T’)
      {
       FLG=0;
       Serial.println(“stop is pressed”);
      }
   }
}

It will be better if you also explain about what you are trying to achieve.

You need to be more specific.What aspect of the line of code don't you understand? What other lines of code are you having trouble with?

this is C code and you need to look into declaring variables and functions in C to understand the syntax

unsigned, short, int etc are variable types, words with the format name(..., ...) are functions, int ser_1[3]; is an array of size 3, #define is not called a "function" and is more like automated copy-paste; for instance, #define stp 22 replaces all the instances of the word "stp" by the number "22" when compiling

I am having problems with some statements such as
  "unsigned short FLG = 0;"

This is the C and C++ syntax for declaring a variable. The statement
means “Let FLG be an unsigned short integer and let it's initial value
be zero”. An unsigned short can hold any integer value between 0 and
65535 inclusive.
The Arduino language reference documents the types
short and
unsigned int but,
for a mysterious reason, it does not document unsigned short.

I cannot make out at all the timer interrupts part.

Nobody can unless they know the internals of the AVR timers, which are
non trivial but are well covered in the
datasheet.
It's a thick document, but you only need to study chapters 14:
Interrupts and 17: 16-bit Timer/Counter (Timer/Counter 1, 3, 4, and
5).
I recommend you first read the Timers and counters
tutorial by Nick Gammon, then go to the
datasheet for the most authoritative information.
Edit: Just a comment... I find the program you have posted to be
written with poor programming style. More specifically, the section
setting the Timer 1 registers would be better written as follows:
TCCR1A = bit(COM1A1);  // set OC1A to LOW on compare match
TCCR1B = bit(WGM12)    // CTC mode, TOP = OCR1A
       | bit(CS11);    // clock at F_CPU / 8
OCR1A  = 40000 - 1;    // period = 40000 prescaled clock cycles
TIMSK1 = bit(OCIE1A);  // enable COMPA interrupt

It is still obscure if you don't know the timer, but using explicit bit
names instead of pure numbers makes things a lot easier when you refer
to the datasheet. Also, there is no point in setting each byte of
OCR1A in a different statement: it only makes things harder to read.

Hi, I have edited the question and added the entire code. Could you kindly have a look and suggest improvements?

Actually, I am trying to control two stepper motors. One motor is connected to a crank slider mechanism and the other to a belt-pulley mechanism. So when the motors are going to operate, the respective mechanisms will create a compression-elongation and twisting force on the test material. I have a picture here : https://drive.google.com/open?id=0B7174vajmpNUXzcycVQ2clRVZms

@AyanPaul: Lots of issues: overlong lines, inconsistent indenting, missing } at the end of loop(), missing definition of StepForwardDefault(), use of non-ASCII quotes ‘’“” instead of '", two Serial.read() following a single Serial.available(), storage of incoming serial bytes in an array that is never used, three almost identical functions that should be factored into a single one, tons of useless comments that only paraphrase the code, missing comments for the things that are really non obvious (e.g. the meaning of all the global variables)...

I'm assuming you don't mean "all" when you ask "what does it all mean?"
I also assume that the comments are from you - in which case you've done reasonably well!
/* The “define” function is NOT A PROGRAMMING STATEMENT... */

True, #define isn't a programming statement that produces code: it's a way of defining a symbol that you can use in the rest of the code, both for explanation purposes and ease of changing: without having to search for all copies of 22 - and then decide if this particular 22 is for that pin or not.
unsigned short FLG=0;

int is 16 bits in the Arduino, but in some systems it's 32 (and in others 64). short is (practically) always 16 bits regardless of system, so many programmers use short when they know they definitely want a 16-bit integer. unsigned merely means that it can never go negative - which allows the variable to hold higher values (0 to 65,535 instead of -32,768 to 32,767).
int ser_1[3];

This is an array of 3 ints called ser_1, which can be accessed as ser_1[0], ser_1[1] and ser_1[2]. In C, all arrays start at 0. Why use an array? It makes it possible to use another variabe to say which ser_1 you want: e.g. ser_1[i]. If i is 2, you get the last one.
int po(int,int);

This says that there will be a function called po that takes two int values, processes them, and returns an int result.
noInterrupts(); // to prevent disruption of timing of codes, disables some functions in the background

Pretty much. An interrupt can happen at any time: the CPU will stop executing the main program, execute the interrupt code, then resume where it left off in the main program. Sometimes that's a bad thing! If the interrupt code is going to change something that this code needs to stay the same (or vice versa!), then Bad Things can happen. To prevent that, you can turn off interrupts temporarily with this function, and turn them on again later with interrupts() (which you'll see below).
/* To use timers, the built-in timer registers on the AVR chip that store timer settings need to be configured.  There are a number of registers per timer.  Two of these registers –the Timer/Counter Control Registers- hold setup values, and are called TCCRxA and TCCRxB, where x is the timer number (TCCR1A and TCCR1B, etc.).   Each register holds 8 bits, and each bit stores a configuration value. */

 TCCR1A = 0x80; //
 TCCR1B = 0x0A; // Enable reset on compare match, 1:8 clock. don’t understand

OK, this is complicated:

By default, a timer simply counts from 0 to 65,535 (maximum 16 bit value), then resets and starts again.
How quickly? One 'tick' is the system clock, so very quickly! But you can "pre-scale" that with a divisor. In this case, they're using a divisor of 8, so the timer will "tick" an eighth as fast.
You can configure the timer to interrupt when it resets, so that special code will execute on a timed basis.
You can also tell it that if at any time it hits a certain number to also interrupt (Compare Match) - that's two different interrupts.
You can also tell it that when it hits that Compare number, to reset back to 0 and start counting again. That means that the timer will interrupt more often.

OCR1AH = 0x9C;
OCR1AL = 0x3F;
These stand for "Output Compare Register 1A High" and "Output Compare Register 1A Low" - a 16 bit value that is 0x9C3F (37839 decimal). If you divide the system clock by that number, (and a further 8 for the pre-scaler), you'll find out how often it interrupts.
interrupts();

This turns on interrupts again.
ISR(TIMER1_COMPA_vect)   // timer compare interrupt service routine
{
res();
}

This is the code that executes every timer interrupt. I don't know what res() does.

Hi, I have edited the question and added the entire code. Could you kindly have a look and suggest improvements?

Here is some explanation :
TCCR1A = 0x80; //OC1 will cleared on compare match
TCCR1B = 0x0A; //Turn on CTC mode --> it means the interrupt counter will reset to 0, and causing the interrupt happen again and again.
               //Divide clock 1:8 (prescaler)
OCR1AH = 0x9C;
OCR1AL = 0x3F; //compare value = 0x9C3F = 39999
TIMSK1 = (1<<OCIE1A); // the micro will jump to the Output Compare A Interrupt vetor upon compare match.

Overall, this setup will make your program do whatever you put in the Interrupt Service Routine ISR(TIMER1_COMPA_vect){...do whatever here...}
The interrupt interval is =

(OCR1A+1) × prescaler ÷ F_CPU
(39999+1) × 8 ÷ 16.000.000 = 0.02 sec

as for res(); and unsigned short FLG; I dont know what that is, since its probably your own creation (not from arduino libs)
You can found more detailed explanation here and here

The interval is (OCR1A+1) × prescaler ÷ F_CPU = 2 ms.

@EdgarBonet - Did you mean 20 ms or 2 ms? The calculation, with the numbers supplied, gives 20ms.

@Greenonline: My mistake: I typed 3999 instead of 39999 in my calculator. The correct value is indeed 20 ms.

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


text:
Why am I not receiving codes from IR receiver over the serial monitor?
I'm using the Keyes Infrared Receiver Module on an Arduino Uno R3 with the IRemote library included and running the IRrecvDemo example sketch included in the library.
I wired the IR receiver incorrectly the first time I ran the program. I wired the data pin to 5V and wired the Vcc pin on the module to the digital I/O pin. The ground was wired correctly.
Did I destroy the IR receiver by doing this? There was no noticeable overheating.
I corrected the wiring and tried again but still nothing over the serial monitor while pushing buttons on the IR remote that came with it. I wondered if the issue was with the remote so I hooked up a IR LED to flash using the following code:
#include <IRremote.h>

int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

IRsend irsend;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop()
{
  for (int i = 0; i < 3; i++) {   //// for statement controls IR LED
    irsend.sendSony(0xa90, 12);
    delay(40);
    if (irrecv.decode(&results))    //// if statement controls the receiver
    {
     Serial.println(results.value, HEX);
     irrecv.resume(); // Receive the next value
    }
  }
}

Nothing showed up on the serial monitor. However, the LED on the IR receiver module began flashing when the receiver was exposed to the IR LED, leading me to believe that I did not destroy the module when I wired it incorrectly.
Update:
I took the IR led and simply lit it with a coin cell battery and the IR receiver detected it and sent data over serial monitor. The remote powered by that same coin cell battery will not trigger the IR receiver. Can I conclude that this is a problem with the remote?

What is transmitting here? Are you sending from a remote?

@Nick Gammon Yes,the IR receiver came with a remote. I also have a simple IR LED that I set up just to see if the receiver would recognize it and send data over serial monitor. Neither worked.

I'm just wondering why your posted sketch has an irsend in it. What is the point of that?

Just shining an IR led on the module, shouldn't trigger the receiver, as it requires 38kHz modulated IR-light. So that's very suspicious.  I'd also check the remote by shining it towards a camera (e.g. the iPhone front camera, as it doesn't have an IR filter). Or just use the remote from your TV.

@Nick Gammon The posted code both sends IR signals using the IR led and receives the signals. The posted code is was for testing the receiver with the IR led. The code that I'd like to ultimately use is the IRrecvDemo sketch from the library to be used with a remote.

First, you can harvest this IR ASK receiver from almost any discarded entertainment equipment.  Second, as @Gerben said, you need a modulated signal.  A constant IR source (like the sun for example) should do nothing. Next, there are many ASK code variations.  Try several remotes.  Lastly, the camera trick should work with almost any CCD type camera.  I use my phone for this all the time.


text:
Read string from DigiUSB
I wrote simple code for my Digispark (Attiny85 with Micronucleus bootloader) in Arduino IDE:
#include <DigiUSB.h>

String inst;

void setup() {
  DigiUSB.begin();
  pinMode(1, OUTPUT);
}

void loop() {
  if (DigiUSB.available()) {

    char inp = DigiUSB.read();

    if (inp == '\n') {
      DigiUSB.println(inst);
      DigiUSB.println(inst.length());
      inst = "";

    }
    else {
      inst += inp;
      }
  }

  DigiUSB.delay(1);
}

DigiUSB works just like Serial communication in classic boards
If i send string and newline char i expect it to output this string back and print its length, but instead i receiving null string and 0 in any case
Is it problem with code or microcontroller itself?

EDIT:
Its seems to be digispark library problem itself:
DigiUSB.println() and DigiUSB.print() accept only char arrays
Also, there is no toCharArray() from classic arduino lib and no c_str() so i cant use atoi()

At DigiBlink example DigiUSB.refresh(); calls first at "loop()".
Maybe it could solve issue. https://github.com/digistump/DigisparkArduinoIntegration/blob/master/libraries/DigisparkUSB/examples/DigiBlink/DigiBlink.ino


text:
Does an 5V 2.1 A will fit for this Led Schema?
Hello I would like to create an Arduino protoype with Led WS2182B.
I currently have
Arduino NANO (not UNO, like in this schema)
65 Led WS2182B = Which gives me 3.9 Amp of suply for full brighness (65*60mAmp)
Power supply of a movil charge wich have 5V 2.1 A
I am currently working with this schema from this website

I have a few questions

Does this battery will work for this schema replacing the usb conector?
Can I use the 68 leds at a medium energy, to make it suitable wih the power supply? Can this damage any device (Because in theory I believe it needs more than 2.1 Amps)
3)If this battery will not be appropiate to this schema. What could I do?

Thank you very much!

Are you using a battery or a wallwart power suppy? What exactly are you using? 2. When you already calculated that you need 4.68A and your supply gives you up to 2.1A, does this sound like it would fit?

@chrisl hello Chris, I am using an portable battery for smarthphone. The amount of Ampers used is at the maximun capacity, my doubt is if I can use at a medium capacity or so

Do you mean a standard USB power bank? You can get max 2.1A/3.9A =  53,8% intensity. Though you should go considerably lower. With your current supply you should always plan with some headroom, like 50% more than you need (especially since power supplies of all kind can get rather inefficient near their maximum rating)

@chrisl yes, indeed a USB power bank, thank you Chris, I think that I get the point, you reccomend me that I use those leds lets say into a 25% of the intensity so it will peak at the full capacity, right? Do you know what I can use to replace this power bank, or from an existing tutorial to work in this type of cases (a portable device which lighlty exceed the capacity of an USB power bank)?

You are using a standard USB power bank. It should be possible to power your project as long as you stay below the current limit (2.1A). Probably you should keep the intensity small enough to not exceed 1.9A in normal operation. That should be enough for about half intensity. You really don't want to exceed the current limit. And you should measure the actual current draw and then approach your own current limit (like 1.9A) from below. Calculations are good, but when operating like this you should look at the real values.
If you exceed the current limit of the power bank it depends on the implementation of the power bank what will happen. Most likely the power bank will cut the power but still work. Though it is also possible, that you fry some electronics inside the power bank and kill it this way.
Note:

While you experiment with your code you can use fewer LEDs, so that they would be able to light up at full intensity. That makes sure, that you don't damage anything from a small programming error. If you write your code in the correct way (for example defining the number of LEDs at exactly one code line and reusing that name everywhere), then it will be easy to increase the number of LEDs to the target and also be sure, that you are staying within your limits.
You already have it in your wiring diagram, but nonetheless I want to emphasize, that you must not power the LEDs through the Arduino. You need to connect them directly to the USB cable to the power bank. The Arduino cannot withstand such currents.
USB power banks often cut power, when not enough current is being drawn from them (and for mine the current of an Arduino Nano wasn't enough to hold it active). If in your project the LEDs get turned of at some time, while the Arduino should keep running, the power bank might cut the power, thus turning off the Arduino. In my experience the bigger, more expensive power banks will do that, while small, cheap ones will just keep outputting the power. If this scenario is relevant for you, you need to test this yourself with your specific power bank.

If this battery will not be appropiate to this schema. What could I do?

You could use multiple of these power banks, each of them powering its own part of the LED strip. One of them can also power the Arduino. Just make sure to connect all grounds together.

Thank you, Chris!


text:
HTTPClient works with localhost but not server
I started to work with HTTPClient and the WiFly library to connect to an SSID and then send POST data to a server. When I was sending the data to my localhost, it was working on localhost, but when changing the URL to a server I am getting this response:

<title>400 Bad Request</title>

400 Bad Request

openresty

My code is the following:
#define HTTP_POST_URL "http://URL/insert.php"
#define HTTP_POST_DATA "181"
SoftwareSerial uart(2, 3);
WiFly wifly(uart);
HTTPClient client;
char get;

while (client.post(HTTP_POST_URL, HTTP_POST_DATA, 10000) < 0) {}

Looking at the constructor of POST in the HTTPClient library it is possible to use POST without defining the header and it will automatically create a default header:
int HTTPClient::post(const char *url, const char *data, int timeout)
{
  return connect(url, "POST", NULL, data, timeout);
}

int HTTPClient::post(const char *url, const char *headers, const char *data, int timeout)
{
  return connect(url, "POST", headers, data, timeout);
}

int HTTPClient::connect(const char *url, const char *method, const char *data, int timeout)
{
  return connect(url, method, NULL, data, timeout);
}

int HTTPClient::connect(const char *url, const char *method, const char *headers, const char *data, int timeout)
{
  char host[HTTP_MAX_HOST_LEN];
  uint16_t port;
  char path[HTTP_MAX_PATH_LEN];

  if (parseURL(url, host, sizeof(host), &port, path, sizeof(path)) != 0) {
    DBG("Failed to parse URL.\r\n");
    return -1;
  }

  if (!wifly->connect(host, port, timeout)) {
    DBG("Failed to connect.\r\n");
    return -2;
  }

  // Send request
  char buf[HTTP_MAX_BUF_LEN];
  snprintf(buf, sizeof(buf), "%s %s HTTP/1.1\r\n", method, path);
  wifly->send(buf);

  // Send all headers
  snprintf(buf, sizeof(buf), "Host: %s\r\nConnection: close\r\n", host);
  wifly->send(buf);

  if (data != NULL) {
    snprintf(buf, sizeof(buf), "Content-Length: %d\r\nContent-Type: text/plain\r\n", strlen(data));
    wifly->send(buf);
  }

  if (headers != NULL) {
    wifly->send(headers);
  }

  // Close headers
  wifly->send("\r\n");

  // Send body
  if (data != NULL) {
    wifly->send(data);
  }

  return 0;
}

So I am not sure why it worked on localhost but on the hosting.
EDIT:
after logging it to console, this is the request I am sending:
POST /insert_gsr.php HTTP/1.1

Host: www.mywebsite.com
Connection: close

Content-Length: 3
Content-Type: text/plain

EDIT 2:
The example code:
https://github.com/Seeed-Studio/WiFi_Shield/blob/master/Examples/wifly_http/wifly_http.ino
is also throwing the same error.

When you get a code 400 that means that you are reaching the server, but your request format is not correct. Without providing information about that endpoint we cannot say how the request has to look like. And what do you mean with sending to my localhost? Do you have code on that mimics the actual servers function? Or do you mean that you just get a code 200 with "it works"? Currently I don't see why localhost should be relevant here

first I tested out the PHP script where I want to send my POST data on localhost using XAMPP, then I uploaded the same script to my server where it no longer works after I change the URL I am connecting to that of the server. You can see the request I am sending at the bottom of my question. I also used an online API tester tool where I sent the same format of the request as from the Arduino, where it works.

Since the code you posted works in 2 out of 3 cases, I would ask about the server code which it doesn’t work with and not the code you posted. I would also perform a test using curl against the script which your code can’t talk to.

So with localhost you mean your PC? Have you tested the PHP script on your server (without the Arduino; connecting from your PC to your server)? Did that work?

Yes the localhost was an apache server running on my PC on the same WiFi the Arduino connected to. And yes, the script works when calling directly from the browser. My theory is that it worked local, because the request didn´t leave the gateway and the format request gets validated when talking to a remote server. Neverthless, the logged request looks valid to me.

The new link in your edit 2 doesn't work for me. Are you sure it is correct?

Can you show us how you tested the php script with the request from your PC to your server? The error is definitely that the request is not correct and that might show us, what the difference is.

I´ve have updated the link for the example. The example is also not working and getting the same errror, therefore it is not my PHP script that is not working.
I think the library: https://github.com/Seeed-Studio/WiFi_Shield/blob/master/Examples/wifly_http/HTTPClient.cpp is not setting the correct headers, I tried to send more header details, like accept or user-agent but still getting incorrect request

if we can make the example from github work from edit 2, it will also work for my code, the library is quite old and I think its not setting headers according to today's standards and in my opinion, needs modification

Do the headers really have blank lines in there, or is that just an artefact of logging?

its just the log. Each line ends with \r\n

Please show us how exactly you have done the successful test from your PC. You obviously don't build the correct request, but we cannot really help you unless we know how exactly the request has to look. If we got the request that works and the one that doesn't work side by side we would look for differences. And what headers are needed depends on your server setup (which you didn't show) and not on the Arduino code.

The request is built here: https://github.com/Seeed-Studio/WiFi_Shield/blob/master/Examples/wifly_http/HTTPClient.cpp and I believe if we can make the example code work in edit 2 (a request for HTTP bin site), it will also work for my server, as it seems to be the common problem. The entire project can be downloaded and tested from the linked GitHub repository.  So if you can make the code work from EDIT 2, it will also work for me as only the destination URL was changed in my code. I tried it with no luck.

@chrisfodor Did you get this to work? I had a similar problem with httpclient due to the target URL being out on the internet and I had not told httpclient the gateway IP, umask etc.

@kiwiron no, I did not get this to work, I turned my attention away from the problem and I will be using localhost, but communicating with a server would be better.


text:
How do I "conditionally" include libraries and declare global objects of them?
I'm trying to write a generic "Test Bench" type of sketch using booleans to indicate whether or not to include specific libraries.  After those are defined, I'm attempting to use preprocessor #if statements to determine if the libraries need to be included and create the objects if need be.
Example:
const bool useLCD = true;

...

#if (useLCD)
  #include "NHD_4x20.h"
  NHD_4x20 lcd(9);
#endif

These statements are before the setup() and loop() functions.  This in itself doesn't generate compiler errors, however I get "lcd has not been defined in this scope" when trying to use the object in the setup() and loop() functions.
Is there some simple trick to accomplish this that I'm overlooking here ?
Thanks in advance !

Please take also note before version 1.6.6/1.6.7 preprocessor conditionals were very sketchy.

const bool useLCD = true;

should be:
#define useLCD 1

Here is a complete working example of how to use preprocessor macros for conditional compilation:
#define USE_A 1
// #define USE_B 1

#if (USE_A)
int a = 4;
#endif

#if (USE_B)
int b = 6;
#endif

void setup() {
    Serial.begin(115200);
    Serial.print(F("The result is: "));
#if (USE_A)
    Serial.println(a * 2);
#endif
#if (USE_B)
    Serial.println(b * 2);
#endif
}

void loop() {
}

Thanks, Majenko.
Just tried it...  Same "has not been defined" error.

Sorry, Manjenko !  Had a typo !!  Worked !!  Thanks a lot !!

That's OK then :) I just posted an example as well.


text:
Clamping 9-volt input to 8-volt?
Have a DFRobot Arduino Pro Mini.
Seems odd to me, but according to their specs the voltage regulator on board cannot handle more than 8-volt input. I can find no documentation, or have they answered me concerning what specific regulator they use on the board.
I would like to be able to run this board from a 9-volt battery. What is the best / most eloquent way to do this, keeping the smallest component footprint for a home etched board ?
An additional regulator ?? Could a diode clamp the voltage down ?
Many thanks in advance.

The schematic tells you exactly which regulator they use. They also have a (broken) link to its datasheet on the page.

And the regulator's a piece of crap. I'd be embarrassed to spec a part like that for a project.

Thank you, Ignacio.  This is the 1st one I've purchased.  It seems (at least so far) it works OK on USB power...  But why a regulator that can't at least handle a 9-volt battery ??
But, again...  What is the best way to clamp a 9-volt battery to 8-volt ?

Haven't found that schematic...  Exactly what regulator are they using ?

You're almost better off getting a small 1S Li-ion/Lipo battery and strapping it to a boost regulator and stuffing it into the 5V connection.

https://www.dfrobot.com/product-696.html

So...  Can I assume by your comments that their design has a lot to be desired ??

Their design is bog-standard '328P stuff, except for that awful, awful regulator.

i would use a cheap (~$1) DC-DC buck converter from ebay to drop it to 5v for max battery life. voltages above the minimum input for the regulator are wasted as heat at the same rate as your real parts.

I second dandavis; use a buck converter (not a linear one). Like the MP1584 based boards. Very small and cheap

I would make sure first that their claim ofb8v max is right. Look up the datasheet for the regulator and go from there.
If you have to go with 8v max, put a diode or two, or an led in serial should work most of the time.
For those where such an approach doesn't work, wire up an external regulator.


text:
Parse the data incoming from the buffer of Serial.readBytes()
I want to parse the data of the incoming buffer from the serial read bytes, but I don't really know how to get the data out of the array and save it to different variables.
This is my code:
void setup() {
  Serial.begin(9600);
}

struct buf {
  byte FunctionCode;
  byte Length;
  byte Message;
  byte Checksum;
} data;

void loop() {
  int Length = Serial.available();
  byte Buffer[Length];
  byte IncomingData[Length];
  if (Length >= 0)
  {
    Serial.readBytes(Buffer, Length);
    data.FunctionCode = Buffer[0 - 1];
  }
}

What data? How is it formatted? Look at strtok() to do the heavy work for you.

@Majenko this is the incoming data: |61|191|16|0|61|191|100|23|0|0|0|0|0|0|131|2| (without the "|"), I can't use strtok because I'm not using string, they're just bytes

A string is just bytes...

@Majenko Yeah, btw I fixed everything just by using a for loop and some if statements

@alessandromrc, is it fair to say that you don't control for the format of the data being sent to you?

@timemagei I just send raw bytes to the Arduino

That sounds like "yes."  Part of what I'm getting at is you have could use any number of libraries for existing protocols.  Just from your FunctionCode mention alone, it's reminding me of MODBUS.

@timemage haha, It's a MODBUS emulation for real ... If I have to be really honest I'm not a fan of libraries, I prefer learning how to do everything by myself so I can understand how it really works and not by just hearing that by somebody else


text:
Avoid using delay with the HR-S04 ultrasonic sensor
How can I measure the distance of an HR-S04 ultrasonic sensor with millis and micros?

I'd use the Input Capture ability of Timer1, but that's beyond the scope of this site - maybe you can find a library that does that for you.

@Majenko, did you see the self-answer?

@Juraj I did. Looks fine to me.

@Majenko, most ultrasonic code I saw activated trig for some microseconds and then used pulseIn to catch the echo. but the code in answer triggers for 10 milliseconds using states

The falling edge is what matters. It still uses pulseIn.

In response to @Majenko comment on the original question, here is some code that I use which uses the Timer1 input capture function to read an ultrasonic sensor.  It also uses the Timer1 PWM generator to create the trigger pulses.  The entire code is interrupt driven and nothing blocks the main program.
It's not built as an official style library with all the extra parts, but the .h and .cpp can be put into a folder in the libraries folder as in the manual installation process.  It's really just a personal library that I use on some of my robots, but I'm happy to share.
The code as written supports the ATMEGA1284P and ATMEGA328P chips.  There are a couple of lines to comment and un-comment to change between the two.
It exposes a singleton instance much like the Serial class, so there's nothing to instantiate.  The pins are all set by hardware, you can't change them.
Depending on how much total range you want, you can set the prescaler to a much lower value.  If you run with no prescaler then the resolution would be something on the order of nearly 100 times what you can get with micros (62.5ns vs 4us resolution).  But that would be shorter distances like 1.2m and less.
https://github.com/delta-G/PingTimer
#include "PingTimer.h"

int distance;

void setup() {

  Serial.begin(9600);
  ping.begin();
  ping.sendPing();

}

void loop() {

  //  if the ping sensor has new data save it to distance and print it.
  if(ping.hasNewData()){
    distance = ping.getDistanceMM();
    Serial.print("Current Distance: ");
    Serial.println(distance);
    ping.sendPing();
  }

  //  Do other things not blocked by ping sensor

}

PingTimer.h
/*

PingTimer  --  uses Timer1 Input Capture to read a HC-SR04
     Copyright (C) 2019  David C.

     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.

     */

#ifndef PINGTIMER_H_
#define PINGTIMER_H_

#include "Arduino.h"

// Ping pin on OC1A -- PB1 on 328P.  (UNO pin 9)
                    //-- PD5 on 1284P  (pin 13)
#define PING_PIN_MASK (1 << 5)
#define PING_PIN_PORT PORTD

// Echo pin on ICP1 -- PB0 on 328P  (UNO pin 8)
                    //-- PD6 on 1284P  (pin 14)
#define ECHO_PIN_MASK (1 << 6)
#define ECHO_PIN_PORT PIND

class PingTimer {
private:
    volatile uint16_t timerVal;
    volatile boolean overflowed;
    volatile boolean newData;

    void initTimer();

    void startPulse();

public:
    PingTimer();
    void begin();

    void sendPing();
    void echoHandler();
    void overflowHandler();

    boolean hasNewData();
    boolean hasOverflowed();
    uint16_t getTimerVal();

    int16_t getDistanceMM();

};

extern PingTimer ping;

#endif /* PINGTIMER_H_ */

And the PingTimer.cpp
/*

PingTimer  --  uses Timer1 Input Capture to read a HC-SR04
     Copyright (C) 2019  David C.

     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.

     */

#include "PingTimer.h"

PingTimer ping;

PingTimer::PingTimer(){
    newData = false;
    overflowed = false;
    timerVal = 0;
}

void PingTimer::begin() {
    initTimer();
    // ATMEGA328P
//  pinMode(8, INPUT);
//  pinMode(9, OUTPUT);
    // ATMEGA1284P
    pinMode(14, INPUT);
    pinMode(13, OUTPUT);
}

void PingTimer::initTimer(){
    cli();
    TCCR1A = 0;  // no PWM
    // Noise Cancel On, RISING Edge , No prescaler, 4ms range.
    TCCR1B |= ((1 << ICNC1) | (1 << ICES1) | (1 << CS11) | (0 << CS10));
    // make sure analog comparator isn't selected as capture input
    ACSR &= ~(1 << ACIC);
    //  Turn off Timer interrupts
    TIMSK1 = 0;
    // setup COMPA for 10us to time the trigger pulse
    // and COMPB for 12ms for out of range signal (a little over 4 meters)
    OCR1AH = 0;
    OCR1AL = 20;  // With prescaler at 8 each tick is 0.5 us.
    OCR1BH = 0xB5;
    OCR1BL = 0xB0; // 0xB5B0 is 46512.  That's a little over 4 meters with prescaler at 8.
    sei();
}

//  This is a public facing function to call the startPulse so it can stay private
//  since it twiddles registers
void PingTimer::sendPing() {
    startPulse();
}

void PingTimer::startPulse(){
    // set pin high and setup PWM unit to
    // turn the pin off 10us later
    cli();
    TCNT1H = 0x00;
    TCNT1L = 0x00;
    //Set up to get one pulse of PWM
    // Clear OC1A on compare match.  10bit fast PWM
    TCCR1A = ((1 << COM1A1) | (1 << WGM11) | (1 << WGM10));
    // Setup input capture interrupt to catch the rising
    // of the echo pin and start the timer
    // Noise Cancel On, RISING Edge ,prescaler at 8 gives a 32ms timer = 5.5 meter range
    TCCR1B = ((1 << ICNC1) | (1 << ICES1) | (1 << CS11) | (0 << CS10) | (1 << WGM12));
    //  Turn on interrupt Input Capture
    TIFR1 = ((1 << ICF1) | (1 << TOV1));
    TIMSK1 = ((1 << ICIE1));
    overflowed = false;
    newData = false;
    sei();
}

// Called from ISR
void PingTimer::echoHandler() {
    if (ECHO_PIN_PORT & ECHO_PIN_MASK) {  //Rising Pin
        // Kill the OC1A PWM unit and return to normal mode
        TCCR1A = 0;
        // Noise Cancel On, FALLING Edge ,prescaler at 8 gives a 32ms timer = 5.5 meter range
        TCCR1B = (1 << ICNC1) | (0 << ICES1) | (1 << CS11) | (0 << CS10);
        // Reset Timer1
        TCNT1H = 0;
        TCNT1L = 0;
        //  Reset Input Capture and Timer Overflow Interrupts
        TIFR1 = (1 << ICF1) | (1 << TOV1);
        //  Turn on interrupts Input Capture and Timer Overflow
        TIMSK1 = (1 << ICIE1) | (1 << TOIE1);
    } else {  // Falling pin
        // Read the ICR1 Register
        uint8_t low = ICR1L;
        uint8_t high = ICR1H;
        timerVal = ((high << 8) | low) - 4; // Noise canceler adds 4 clock cycles

        //  turn off the timer interrupts
        TIMSK1 = 0;
        newData = true;
    }
}

// Called from ISR  Timer 1 OVF
void PingTimer::overflowHandler(){
    //turn off timer interrupts
    TIMSK1 = 0;
    newData = true;
    overflowed = true;
}

boolean PingTimer::hasNewData(){
    cli();
    boolean retval = newData;
    newData = false;
    sei();

    return retval;
}

boolean PingTimer::hasOverflowed(){
    cli();
    boolean retval = overflowed;
    overflowed = false;
    sei();

    return retval;
}

uint16_t PingTimer::getTimerVal() {
    uint16_t retval = 0;
    cli();
    if (overflowed) {
        retval = -1;
    } else {
        uint16_t copy = timerVal;
        retval = copy;
    }
    sei();
    return retval;
}

int16_t PingTimer::getDistanceMM() {

    int16_t retval = 0;
    uint16_t copy = getTimerVal();
    if (copy == (uint16_t) -1) {
        retval = -1;
    } else {
        // 16Mhz is 62.5 ns/clock
        // We've got the prescaler dividing by 8
        uint32_t nanoSecs = copy * 62.5 * 8;
        //speed of sound in mm/ns
        uint16_t mm = nanoSecs * 0.000344;
        retval = mm / 2;  // half a round trip
    }
    return retval;
}

ISR(TIMER1_CAPT_vect){
    ping.echoHandler();
}

ISR(TIMER1_OVF_vect){
    ping.overflowHandler();
}

ISR(TIMER1_COMPB_vect){
    ping.overflowHandler();
}

Many years ago, it was recommended to access 16-bit I/O registers one byte at a time, reading LSB-first and writing MSB-first. This is ancient history. As gcc has since learned how to access those registers, you can now simply write OCR1B = 46512 and timerVal = ICR1.

I think I sorta knew that and wasn't sure I remembered right so I just went with what the datasheet said to do.  If I update this later I'll add that change.

I have noticed that many people on the net have problems using millis with the sensor to take measurements etc. so I created this sketch to help anyone.
You are free to ask for any clarification about it!
/*
 *  HC-SR04 sensor measuring
 *
 *  Non-blocking HC-SR04 sensor measuring
 *
 *  The circuit:
 *  - Echo pin connected to pin 2
 *  - Trigger pin connected to pin 3
 *  - VCC pin connected to VCC (5v)
 *  - GND gger pin connected to GND
 *
 *  created 3 Jul 2021
 *  by alessandromrc
 */

#define trigPin 3
#define echoPin 2

unsigned long timerStart = 0;
unsigned long StartTime = micros();
bool timer = false;
const unsigned long HIGH_TRIGGER = 10;
const unsigned long LOW_TRIGGER = 2;

float timeDuration, distance;

enum SensorStatus {
  TRIG_LOW,
  TRIG_HIGH,
  ECHO_HIGH
};

SensorStatus sensorStatus = TRIG_LOW;

bool isTimerReady(const unsigned long Sec) {
  return (micros() - timerStart) < Sec;
}

void setup(void) {
  Serial.begin(9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop(void) {
  switch (sensorStatus) {
  case TRIG_LOW: {
    digitalWrite(trigPin, LOW);
    timerStart = micros();
    if (isTimerReady(LOW_TRIGGER)) {
      sensorStatus = TRIG_HIGH;
    }
  }
  break;

  case TRIG_HIGH: {
    digitalWrite(trigPin, HIGH);
    timerStart = micros();
    if (isTimerReady(HIGH_TRIGGER)) {
      sensorStatus = ECHO_HIGH;
    }
  }
  break;

  case ECHO_HIGH: {
    if (!timer) {
      Serial.print("Microseconds Passed in initialization: ");
      Serial.println(micros() - StartTime);
      timer = !timer;
      Serial.println("Starting to Measure");
    }
    digitalWrite(trigPin, LOW);
    timeDuration = pulseIn(echoPin, HIGH);
    Serial.print("Measured: ");
    Serial.print(timeDuration * 0.034 / 2);
    Serial.println(" cm");
    sensorStatus = TRIG_LOW;
  }
  break;
  }
}

Github Repository

it is enough to trigger for 5 microseconds. why do you use a separate state to trigger for 10 milliseconds?

@Juraj I didn't knew about this, thanks for letting me know!


text:
DC Motor not running with the L298N (Green) card
I have a DC motor connected to a L298N (Green) controller. The controller is receiving  electricity but the motors aren't. This is how we wired everything

Our code:
#include <SoftwareSerial.h>

int IN1 = 13;
int IN2 = 12;

int IN3 = 8;
int IN4 = 9;

void setup(){
  Serial.begin(9600);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);

}

void loop(){
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  delay(2000);
}

The DC motor is not responding at all
Edit: Why is the motor not receiving electricity? How can we connect the card to the Arduino UNO correctly and get the motors running?

How exactly are you powering the Arduino? Over USB? Or over the 5V pin of the L298N? Has your L298N board a 5V voltage regulator? If you are trying to power the Arduino from the 5V pin of the L298N, you should use the 5V pin of the Arduino instead of the Vin pin (since that is connected to the linear voltage regulator)

And are you really using a single 3.7V battery to power it all?

@chrisl The arduino is powered by USB and L298N is connected to a 9V battery via VCC.

Then please remove the connection to Arduino Vin. It is not needed (since you power over USB), neither does it work (on Vin you need about 7V to get it working reliably). 2. Are you using one of these standard 9V block batteries? If yes, then this is a problem. They are not build for providing enough current (like for motors). They are made for low current applications (like smoke alarms).

Please also provide a link to the exact L298N board, that you have.

This is the board we use: https://www.robotistan.com/l298-cift-motor-surucu-karti-dual-motor-driver-yesil-pcb. Also yes, we are using those standart 9V block batteries

@chrisl Also what type of battery is good for DC motors?

start at your motor specs.  if the battery matches the specs, attach to battery in forward, then reverse.  once that works, connect to driver.  instead of using arduino output pins, manually connect and disconnect to/from arduino ground and 5V.  if that works, then you need to figure out what's up with your arduino output ports using a multimeter.

First: The connection between the 5V pin of the L298N and Arduino Vin is not correct here. The L298N 5V pin is an output. You could use it to power the Arduino. But then you would have to connect it to the 5V pin of the Arduino. Vin is connected to the linear voltage regulator. You need about 7V here to get the Arduino running reliably, because the regulator needs some headroom for regulating it down to 5V and the battery deplets over time a bit. Since you are powering the Arduino over USB you can remove this connection.
Second: The standard 9V block batteries, that you use, are not meant for providing the power for something like a motor. They are made for low power applications (like smoke detectors). So you will need a different battery type. Which exactly is dependent on further factors. You could start with putting AA batteries in series (enough to get to the voltage, that you need for your motors). Or you can buy a LiIon or LiPo battery (including the corresponding charging board). I'm not enough of a battery expert myself to go more detailed with the recommendations on direct batteries.
If you want it easy you might want to use a standard USB power bank. These give you 5V and (depending on the product) about 1 or 2A of current. Using a standard power bank has the advantage, that you get well regulated voltage, relatively high current and it already has the correct charging electronics.
With a USB-C power bank a corresponding PD board (Power Delivery) you can even get up to 12V from the power bank. Haven't tried this myself yet. Have a look at this video from GreatScott on Youtube. Looking at a standard online marketplace (we all know which one) and searching for "USB-C PD board" gave some promising results.


text:
Why can't an Arduino/ATmega328 act as an SPI slave at anywhere approaching the maximum speed claimed in the datasheet?
The ATmega328 datasheet claims a maximum SPI slave speed of Fosc/4. For a chip clocked at 20MHz, that would be 5Mbps.
However, my tests show that even with no processing whatsoever in the interrupt (other than setting the response), any speed over 128Kbps results in corrupted data. I have no idea why this should be the case.
In my setup, the master runs at 3.3V and 12MHz; and the slave at 5V and 20MHz.

Master code:
#include <SPI.h>
#include "pins_arduino.h"

unsigned int successcount = 0;

void setup(void) {
  Serial.begin(9600);
  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV4);   // 3Mbps
}

void print_successful_transfers() {
  if (successcount > 0) {
    Serial.print("(");
    Serial.print(successcount);
    Serial.println(" successful transfers.)");
    successcount = 0;
  }
}

void loop(void) {
  unsigned char n = 0;
  unsigned char received;
  unsigned int failurecount = 0;

  delay(500);       // wait for the slave to be ready

  digitalWrite(SS, LOW);    // SS is pin 10

  while (failurecount < 10) {
    for (unsigned int count = 0; count < 10000; count++) {
      received = SPI.transfer(n+1);
      if (received != n) {
        print_successful_transfers();
        Serial.print("MISMATCH: sent ");
        Serial.print(n+1);
        Serial.print(", received ");
        Serial.print(received);
        Serial.println(".");
        failurecount++;
        if (failurecount == 10) break;
      } else
        successcount++;
      ++n;
    }
    print_successful_transfers();
  }
  while(true);
}

Slave code:
#include "pins_arduino.h"

volatile char n = 0;

void setup (void) {
  pinMode(MISO, OUTPUT);
  SPCR |= _BV(SPE);
  SPCR |= _BV(SPIE);
}

ISR (SPI_STC_vect) {
  n = SPDR;
  SPDR = n;
}

void loop (void) { }

Sample output:
MISMATCH: sent 1, received 245.
(1290 successful transfers.)
MISMATCH: sent 12, received 5.
MISMATCH: sent 13, received 140.
(1350 successful transfers.)
MISMATCH: sent 84, received 41.
MISMATCH: sent 85, received 212.
(996 successful transfers.)
MISMATCH: sent 58, received 28.
MISMATCH: sent 59, received 186.
(5455 successful transfers.)
MISMATCH: sent 139, received 197.
MISMATCH: sent 140, received 11.
(900 successful transfers.)
(114 successful transfers.)
MISMATCH: sent 131, received 193.

Here is my schematic. I am using bare ATmega328 chips rather than Arduinos, but the situation would be the same if I were using a 5V Arduino Nano and a 3.3V Arduino Nano.
(Except the slave would run at 16MHz instead of 20MHz.)

I also tried with the following level shifter on the MOSI, SCK and SS lines:

EDIT:
To rule out voltage as the possible cause, I ran both ATmega328s at 3.3V and 12MHz. Same problem.

EDIT: I connected two Arduino Nanos together and got different - but still erroneous - behaviour.
The SS pin, despite being set to LOW at the start of the program and never touched again - goes briefly high every so often, corrupting the communication:

(If I use a different pin for slave select, I get the same behavior.)
Note that this is NOT the issue I experienced with my bare ATmega328 circuit.

3.3 V is small and easy to corrupt in wiring.  throw that in with a 5V device and you need some pretty noise resistant wiring

Can you monitor the SPI lines with a scope? That'd be interesting.

There doesn't seem to be anything wrong with the wiring or the signals themselves. I tested with a logic analyser and a scope. Besides, shouldn't 3.3V at the very least be able to cope with 256Kbit?

I'd rather use 1k instead of 4k7 on that level shifter, slowly rising edge will be bottleneck. And also ISR is taking some time too (it could be up to 20 instructions).
And also SS is used for synchronization, so it won't be a bad idea to set it high after the transfer and low before it

At 20MHz, 20 instructions shouldn't be a significant bottleneck.

I tried changing the resistor. Sadly it didn't help.

3.3V output high is only guaranteed to be about 2.7V (from memory, check the datasheet). 5V input high min is 3V (again from memory). If the lines have any length at all, you're in trouble.

A good point. However, one of my previous designs had level shifters on all SPI lines; and I tested that this evening. No dice. I will update the question to show the level shifter circuit I used.

Besides, if it were a voltage issue, then why would it work perfectly at 128KHz? Without even a single glitch?

You need to break down the big problem into smaller steps, so first you can examine if the ISR is fast enough. Add a port pin toggler in the ISR of the slave, to see how the timings are. Don't use digitalWrite() due to its overhead, set/reset the pin directly for optimum speed.

I have reproduced the problem with two standard Nanos running at 5V. I will update my question.

Odd. The problem presents the same with the Nanos, but is actually caused by a completely different issue. Specifically, the SS pin. I have amended the question.

The original problem still happens if I run both chips at 3.3V. So voltage is not the issue here.


text:
failed log in attempts on softAP
I would like to setup an access point using the esp32 that logs any/failed access attempts
i have looked through some source files, and came across esp_event.h, which seems to allow registering an event handler, i wonder if this could be used to do the logging.
#include <WiFi.h>

const char* ssid     = "tmp-AP";
const char* password = "123456789";

static void all_event_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data){

    Serial.println("all_event_handler");

}

void setup() {

  delay(3000);
  Serial.begin(9600);
  Serial.println("test started...");

  auto result = esp_event_handler_register(ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, all_event_handler,NULL);

  Serial.print("result : ");
  Serial.printf("result : %d - 0x%04x\n",result,result);

  Serial.println("Setting up AP ...");
  WiFi.softAP(ssid, password);

  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);

}

void loop(){
}

the code compiles
esp_event_handler_register returns 259 for me, the handler is never called
i have cobbled together this code from :
Event Loop Library
arduino-esp32/libraries/WiFi/src/
default_event_loop
i guess i would like to hook into at least NOT_AUTHED,  802_1X_AUTH_FAILED  from
WiFi Driver

You sure the return value was 429 (in decimal)? Don't think that maps to anything, whether esp_err_t or errno.

well now im getting 259 printed to serial, using codes from error codes

Print the value in HEX

259 == ESP_ERR_INVALID_STATE according to this. Your error likely came from here:
esp_err_t esp_event_handler_instance_unregister(esp_event_base_t event_base,
                                                int32_t event_id,
                                                esp_event_handler_instance_t context)
{
    if (s_default_loop == NULL) {
        return ESP_ERR_INVALID_STATE;
    }
...

You're perhaps calling the function too early, before a default event loop even exists. I'm guessing that usually this event loop gets created by the WiFi libs when you start WiFi-related calls -- such as here:
static bool _start_network_event_task(){
...
esp_err_t err = esp_event_loop_create_default();

If you try moving your registration to after the softAP() call, you risk missing events, depending on how synchronous that call is. So you can try creating the event loop yourself explicitly:
// Create the default event loop
ESP_ERROR_CHECK(esp_event_loop_create_default());

...before you register the handler. That should be harmless -- anything else that tries to create this same loop later should cleanly handle the returned error that indicates the loop already exists.
EDIT
So I tried out your sketch and met the same issue. After spending more time than should've been needed, the issue boils down to one of compatibility.
My ESP32-Arduino core 1.0.6 (and likely yours as well) is based on the ESP-IDF/SDK 3.3.5 release -- a release that contains some pretty old code, despite being the latest that the Arduino Boards Manager has to offer. So, esp_event_loop_init() looked like this:
esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx)
{
    if (s_event_init_flag) {
        return ESP_FAIL;
    }
    s_event_handler_cb = cb;
    s_event_ctx = ctx;
    s_event_queue = xQueueCreate(CONFIG_SYSTEM_EVENT_QUEUE_SIZE, sizeof(system_event_t));

    xTaskCreatePinnedToCore(esp_event_loop_task, "eventTask",
            ESP_TASKD_EVENT_STACK, NULL, ESP_TASKD_EVENT_PRIO, NULL, 0);

    s_event_init_flag = true;
    return ESP_OK;
}

and WiFiGeneric.cpp looked like this:
static bool _start_network_event_task(){
...
    return esp_event_loop_init(&_network_event_cb, NULL) == ESP_OK;

As you can see, there's no mention of the default loop being created, which is why you get *INVALID_STATE for any registrations.
Even if you went and created the default loop yourself, you'd receive no events in your handler because the system events, as of this IDF version, aren't passing through the official esp_event loop pipeline -- esp_event_loop_init() just creates a Task and this task receives events from some external caller as they happen, forwarding them to one application task alone.
If you still want to receive events through this way, you'd need to download/install the very latest ESP32 Arduino core from Github, rather than through the Boards Manager. This core should have a more recent version of the SDK, along with a compatible Arduino HAL.
Alternatively, you can just use the more public API, WiFi.onEvent(). It should cover all the events you're interested in, as well as include any relevant reason codes.
EDIT 2
Yeah, it turns out the SYSTEM_EVENT_AP_STADISCONNECTED reason codes you're looking for, just aren't exposed by the Espressif API, at any layer of the stack. Nor is there any other event which would give you this info AFAICT. You can try raising an issue on the ESP-IDF Github page to see if they can help you there, but chances aren't looking great.

i moved esp_event_handler_register after the call to softAP, same result 259 (0x103)

i kept esp_event_handler_register where it is and added esp_event_loop_create_default before it, both function calls return 0 (0x0) - ESP_OK, but the handler is never called

@mattrichards Did you actually try to do something that would cause the handler to be called -- like connecting a device to the AP?

yes of course, i tried with correct password and incorrect

@mattrichards updated the answer.

i drew the same conclusions, so i decided to order some new boards amazon esp32 devkitc, i'll post my results back here at some point

the wifi.onevent was a no go, i produced two sketches attempting to detail the limitations of this approach, wif ap test, it seems the reason code isnt supplied for SYSTEM_EVENT_AP_STADISCONNECTED, wifi sta test

@mattrichards Yeah, edited the answer, don't think there's any way to get those reason codes.


text:
I need to run 2 for() loops simultaneously but I cant seem to do it without one executing, then the other after it
I'm controlling 2 servo motors but would like to adjust their variables separately, specifically  their upper and lower values, and their speeds. This code is one that I had found online then separated, since the original code didn't have adjustable variables for both. I'm using an adafruit servo
controller
for (uint16_t microsecL = mainServoClosedL; microsecL < mainServoOpenL; microsecL +=5)
for (uint16_t microsecR = mainServoClosedR; microsecR < mainServoOpenR; microsecR -=5) {
        pwm.writeMicroseconds(mainServoL, microsecL);
        pwm.writeMicroseconds(mainServoR, microsecR);
      }

"I need to do something. This is some code I found." isn't a question. What is your question?

I need to run 2 for() loops simultaneously .... why do you need to have two for() loops?

You didn't specify which chip ur using.  Arduino doesn't like multi-threading (proto).  And since arduino chips only have 1 core they only have 1 thread.
Switch over to ESP32 dual-core chips, they have FreeRTOS that has Tasks.  What your trying to do would be easily achievable with an ESP32 microcontroller.

The answer is simple, but the solution isn't.
The simple part: don't use for loops.
The harder part: you have one loop() function which runs repeatedly. For each iteration of that function you make decisions about what to do during that loop and act on them. Decisions like "Is it time to increase this PWM value?" or "Has this value reached the limit I want for it?" etc.

The micro-controller can't do any more than one thing at a time. What it can do is do that one thing way faster than your servos need it to. So it has (more than) enough time to evaluate each motor's condition and needs and to do it fast enough that you won't notice and they won't be affected by the difference.
The one thing your code mustn't do is to wait for a single something to happen, unless that is absolutely the only thing of interest that could possibly happen next. That is seldom the case in the real world, so the controller must check for all possible events of interest, over and over again, to be able to respond to whichever one does happen next.
In your code snippet, you increase microsecL and decrease microsecR, but not at any particular rate(s). Your loop code probably needs to look at the execution-time clock (the functions `millis()' and 'micros()' will read that for you), and when a suitable interval has passed, adjust one or both of those values and do anything else that might need doing, such as stopping a motor when a time has elapsed or it has reached a final position.


text:
No GPS data Neo 6M DFRduino Nano
I checked several answers for same question but none of them help.
I also changed the nano board and GPS module but without luck. I ran it outdoor.
This post question had same issue except my date does not display the correct date and time.
My connection:
vcc->5V
rxd->d4
txd->d3
gnd->gnd

FullExample program from TinyGPS++, I get following types of entries
Sats HDOP  Latitude   Longitude   Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum
           (deg)      (deg)       Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail
----------------------------------------------------------------------------------------------------------------------------------------
0    100.0  ********** *********** **** 00/00/2000 00:00:00 152  ****** ****** ***** ***   ******** ****** ***   324   0         0
0    100.0  ********** *********** **** 00/00/2000 00:00:00 230  ****** ****** ***** ***   ******** ****** ***   486   0         0
0    100.0  ********** *********** **** 00/00/2000 00:00:00 308  ****** ****** ***** ***   ******** ****** ***   648   0         0
0    100.0  ********** *********** **** 00/00/2000 00:00:00 384  ****** ****** ***** ***   ******** ****** ***   810   0         0
0    100.0  ********** *********** **** 00/00/2000 00:00:00 463  ****** ****** ***** ***   ******** ****** ***   972   0         0
0    100.0  ********** *********** **** 00/00/2000 00:00:00 541  ****** ****** ***** ***   ******** ****** ***   1134  0         0

NMEA read from serial
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,1,1,01,05,,,20*7F
$GPGLL,,,,,,V,N*64
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30

$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,1,1,01,14,,,29*76
$GPGLL,,,,,,V,N*64
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30

UPDATE:
I change the antenna. At some time I got this. From the GPGSV sentence I know that there are about 15 16 satellites in view but the FullExample only show 0.
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,4,1,15,04,,,31,07,,,33,09,,,34,11,,,30*74
$GPGSV,4,2,15,12,,,33,13,,,30,14,,,33,15,,,27*7D
$GPGSV,4,3,15,16,,,33,19,,,34,20,,,30,21,,,33*70
$GPGSV,4,4,15,22,,,32,23,,,33,33,,,35*7B
$GPGLL,,,,,,V,N*64

$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,4,1,16,04,,,32,07,,,33,08,,,31,09,,,33*7A
$GPGSV,4,2,16,11,,,29,12,,,33,13,,,30,14,,,34*73
$GPGSV,4,3,16,15,,,32,16,,,33,19,,,33,20,,,31*73
$GPGSV,4,4,16,21,,,33,22,,,33,23,,,34,33,,,35*7D
$GPGLL,,,,,,V,N*64

My idea now is to supply external power for the DFRduino Nano
Any idea how I can continue. Should I changed to other type of gps module?

"I ran it outdoor" Under a clear sky and for some number of minutes, right?

@timemage yes. From this post, it takes 1 or 2 hours to charge EEPROM and the onboard RTC. Without RTC syc time, it cannot get correct date time in my case

You just have made some interpretation with with my name. I wasn't asking about time/RTC output at all. Only that you had it where we could be certain that you would get a fix at the end of so many minutes if everything were correct. So many avoid this. With your update it seems whatever software is involved is correct so far as it goes. Check your antenna connections, that nothing (including the Arduino) near is injecting interference, and try powering it from different sources.

@timemage With 5V power supply from Nano I got the module damaged (Rx Tx get shorten), do you have any idea?

A short has nothing to do with the problem here. Besides that shortening RX and TX doesn't damage anything (unless you connect two TX pins)

If I had to guess you're referring to getting the directions incorrect when trying to use a Nano as only a transceiver. The Nano's RX and TX are labeled from the perspective of the AVR and are 5V (most GPS are 3.3V). The 1K series resistors on the Nano's RX/TX limit the trouble you can get into here if the AVR was in reset. But I don't really understand what you're saying. You should edit any new information directly into the question.

@timemage I connected as mention above. For a while ( 5 6 hours running) the RX TX do not working any more. They got shorten. From this forum, power supply for NEO 6M should typically be 3.0V and range: 2.7V to 3.6V while I supplied 5V

Glad you got it working. I dunno that I've heard someone use "short" in the way that you are.

The ceramic antenna is the issue. I changed to the external 1.5GHz one. It got fix under 5 seconds


text:
State machine controlling dc motor/ buzzer/ lcd / ultrasonic
I ran into some problems here with programming. I am trying to put together a code for 4dc motors, buzzer, ultrasonic and lcd to work together,. they will together make up a small car. when the distance to the ultrasonic is smaller than 10cm, the buzzer makes a random sound, and a funny face. Meanwhile the motors will stop for 2 seconds, goes back for 2 seconds and do a turning motion for 8 seconds. However. I do not want to use the delay function for the motors since it will cause the buzzer to sound too slowly. I was directed from an earlier thread that I should use a state machine,but when I tried to put the motor controls in, my motors does not turn, can someone help me with spotting what is the problem here?
Thank you!
#define HALT_TIME 2000
#define BACK_TIME 2000
#define TURN_TIME 8000
#define trigPin A1
#define echoPin A0
#include <LiquidCrystal.h>
#include <NewTone.h>
#include<AFMotor.h>

long duration;
int distance;
int distanceUltra;
int maximum = 100;
int buzzerPin = A2;
int dur = 100;

LiquidCrystal lcd(8, 9, 4, 7, 12, 13);
AF_DCMotor motor1(1,MOTOR34_1KHZ);
AF_DCMotor motor2(2,MOTOR34_1KHZ);
AF_DCMotor motor3(3,MOTOR34_1KHZ);
AF_DCMotor motor4(4,MOTOR34_1KHZ);

enum ApplicationState {
  BeginDrive,
  Drive,
  BeginHalt,
  Halt,
  BeginBack,
  Back,
  BeginTurn,
  Turn
};

static enum ApplicationState currentApplicationState = BeginDrive;

static unsigned long t = 0;

static bool sensorTriggered() {

  if (distance <= 10){return true;}

  else {return false;}
}

static void funnyFace() {

    lcd.setCursor(6,0);
    lcd.write("x");
    lcd.setCursor(8,0);
    lcd.write("x");
    lcd.setCursor(7,1);
    lcd.write("o");
    randSound(maximum);//random sound for buzzer
}

static void beginDriveHandler() {
    Serial.println(currentApplicationState);

    motor1.setSpeed(100);
    motor1.run(BACKWARD);
    motor2.setSpeed(100);
    motor2.run(BACKWARD);
    motor3.setSpeed(100);
    motor3.run(BACKWARD);
    motor4.setSpeed(100);
    motor4.run(BACKWARD);
  currentApplicationState = Drive;

}

static void driveHandler() {

  if (sensorTriggered()) {
    Serial.println(currentApplicationState);
    t = millis();
    currentApplicationState = BeginHalt;
  }
}

static void beginHaltHandler() {
  Serial.println(currentApplicationState);
    motor1.setSpeed(0);
    motor1.run(RELEASE);
    motor2.setSpeed(0);
    motor2.run(RELEASE);
    motor3.setSpeed(0);
    motor3.run(RELEASE);
    motor4.setSpeed(0);
    motor4.run(RELEASE);

  funnyFace();
  currentApplicationState = Halt;
}

static void haltHandler() {

  if (millis() - t > HALT_TIME) {
    Serial.println(currentApplicationState);
    t = millis();
    currentApplicationState = BeginBack;
  }
}

static void beginBackHandler() {
Serial.println(currentApplicationState);
    motor1.setSpeed(100);
    motor1.run(FORWARD);
    motor2.setSpeed(100);
    motor2.run(FORWARD);
    motor3.setSpeed(100);
    motor3.run(FORWARD);
    motor4.setSpeed(100);
    motor4.run(FORWARD);
  currentApplicationState = Back;
}

static void backHandler() {

  if (millis() - t > BACK_TIME) {
    Serial.println(currentApplicationState);
    t = millis();
    currentApplicationState = BeginTurn;
  }
}

static void beginTurnHandler() {
Serial.println(currentApplicationState);
    motor1.setSpeed(100);
    motor1.run(FORWARD);
    motor2.setSpeed(100);
    motor2.run(FORWARD);
    motor3.setSpeed(100);
    motor3.run(BACKWARD);
    motor4.setSpeed(100);
    motor4.run(BACKWARD);
  currentApplicationState = Turn;
}

static void turnHandler() {

  if (millis() - t > TURN_TIME) {
    Serial.println(currentApplicationState);
    currentApplicationState = BeginDrive;
  }
}

void setup() {
  Serial.begin(9600);
  lcd.begin(16,2);
  pinMode (trigPin, OUTPUT);
  pinMode (echoPin, INPUT);
  pinMode(buzzerPin, OUTPUT);
}

void loop() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  //Serial.println(sensorTriggered());
  duration = pulseIn(echoPin, HIGH);
  distance = duration*0.034/2;
  switch (currentApplicationState) {

    case BeginDrive:
    beginDriveHandler();
    break;

    case Drive:
    driveHandler();
    break;

    case BeginHalt:
    beginHaltHandler();
    break;

    case Halt:
    haltHandler();
    break;

    case BeginBack:
    beginBackHandler();
    break;

    case Back:
    backHandler();
    break;

    case BeginTurn:
    beginTurnHandler();
    break;

    case Turn:
    turnHandler();
    break;
  }

  //Serial.println(currentApplicationState);
}

void randSound(int maximum){
  NewTone(buzzerPin, random(maximum, 10*maximum),dur);
  delay(maximum);
  noNewTone(buzzerPin);
}

If you are really using a 9 volt battery you are very likely under powering your project.  While the voltage may work, the amount of current such a battery can produce is likely way below what your project needs to operate as expected.

Those little yellow gearmotors are typically around 200mA each with no load. You'd be far better off powering at least the motors w/ a bank of AAs.

You need to set t to millis() before reaching the handler with the if millis statement, so in the Begin... Handlers. Otherwise most likely t has such an old value, that the state will change immediately.

start motors and store the value of millis() for the 2 second timer in beginDriveHandler ... watch the time and sensor in driveHandler