text:
Arduino IDE on Fedora
I'm using Fedora_21_MATE.img on a Raspberry Pi. Installing the Arduino IDE 1.0.6 using these commands, taken from Arduino On Pi. Those instructions are for Raspbian, I assume, so changing for Fedora, apt-get to yum:
sudo yum install arduino

One waits and arduino installs. One can then run the Arduino IDE from the Fedora GUI menu, and it loads - after moaning about the user has to be a member of the dialout and lock groups. This is easily resolved by adding the user to the required groups, using the control panel.
However, trying to compile anything, i.e. blink, in the IDE, gives me the following error:
avr-g++: error trying to exec cc1plus: execvp: No such file or directory

In verbose mode, little additional information is offered.
Arduino: 1.0.6 (Linux), Board: "Arduino Uno"
avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=106 -I/usr/share/arduino/hardware/arduino/cores/arduino -I/usr/share/arduino/hardware/arduino/variants/standard /tmp/build6314348775898760987.tmp/Blink.cpp -o /tmp/build6314348775898760987.tmp/Blink.cpp.o
avr-g++: error trying to exec 'cc1plus': execvp: No such file or directory

The file in question, cc1plus, is actually present in the filesystem:
[piebody@berrybody ~]$ locate cc1plus
/usr/libexec/gcc/armv7hl-redhat-linux-gnueabi/4.9.2/cc1plus
/usr/libexec/gcc/avr/4.9.2/cc1plus
[piebody@berrybody ~]$

Does anyone know why it doesn't run "out of the box"? Do I need to modify any environment variables, and if so, which ones and with what exactly? I assume my PATH environment variable needs fixing, but is there any environment variable specific to avr-g++ that needs changing?
I appreciate that this is probably a simple UNIX paths issue, and that the question may be more suited to SE: Unix & Linux.

Can you post the verbose build output?

Could you try this again with Fedora 23? I just tested it, and it works for me out of the box.

There seem to be two issues:

Getting the IDE to fully function when launched from the command
line, and;
Getting the IDE to fully function (i.e. compile) when launched from
the Fedora GUI menu.

I have found a solution if I run the Arduino IDE from the command line, by adding the path to  one of the cc1plus binaries to the PATH environment variable:
[piebody@berrybody ~]$ PATH=${PATH}:/usr/libexec/gcc/avr/4.9.2
[piebody@berrybody ~]$ export PATH
[piebody@berrybody ~]$ arduino&

However, if I launch the Arduino IDE from the Fedora application menu, and then try to compile a sketch, it still can't locate cc1plus. Maybe the PATH needs to be added in my .profile, or some other mechanism, to get an application launched from the Fedora menu to see the path?1
Yet, even with the command line launch, it still does not finish compiling.  I now get the following error when the IDE attempts to compile:
In file included from Blink.ino:18:0:
/usr/share/arduino/hardware/arduino/cores/arduino/Arduino.h:23:20: fatal error: stdlib.h: No such file or directory
 #include <stdlib.h>
                    ^
compilation terminated.

In verbose mode
Arduino: 1.0.6 (Linux), Board: "Arduino Uno"
avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=106 -I/usr/share/arduino/hardware/arduino/cores/arduino -I/usr/share/arduino/hardware/arduino/variants/standard /tmp/build1210300884764677972.tmp/Blink.cpp -o /tmp/build1210300884764677972.tmp/Blink.cpp.o
In file included from Blink.ino:18:0:
/usr/share/arduino/hardware/arduino/cores/arduino/Arduino.h:23:20: fatal error: stdlib.h: No such file or directory
 #include <stdlib.h>
                    ^
compilation terminated.

I assume that this is another PATH issue. One that relates to the path to the Arduino libraries, or libc libraries.
After reading can't locate avr libraries2, I can't see why avr-g++ is not picking up the avr directory in the /usr directory.
The actual path to stdlib.h is /usr/avr/include/stdlib.h
The output of avr-gcc (and avr-g++) shows --prefix=/usr
The Arduino IDE preference file (~/.arduino/preference.txt) shows the line
last.ide.1.0.6.hardwarepath=/usr/share/arduino/hardware

Linking the includes
If I manually link some header files to where the compiler actually is looking, then it works (until avr-gcc needs a header that I have not linked to):
cd /usr/share/arduino/hardware/arduino/cores/arduino
sudo ln -s /usr/avr/include/stdlib.h stdlib.h
sudo ln -s /usr/avr/include/string.h string.h
sudo ln -s /usr/avr/include/math.h math.h

but I can not do this for every header file, it is ridiculous. There must be a way of linking to /usr/avr from /usr/share/arduino/hardware/arduino/cores/arduino. I have tried linking the parent directories /usr/avr and /usr/avr/include, at various points along the directory hierarchy of /usr/share/arduino/hardware/arduino/cores/arduino, but none of those seem to work.
Copying the include directory
After reading default include file path?, and running avr-cpp -v I saw that the default #include search path was
#include <...> search starts here:
 /bin/../lib/gcc/avr/4.9.2/include
 /bin/../lib/gcc/avr/4.9.2/include-fixed
End of search list.

From this, I could see that avr-cpp was searching in /lib/gcc/avr/4.9.2/include. I examined, and compared, the contents of /lib/gcc/avr/4.9.2/include with /usr/avr/include and they held similar (the same) files, except /lib/gcc/avr/4.9.2/include was a subset, that is to say that it was missing the required files.
I ended up copying the /usr/avr/include directory, which contains the required header files (stdlid.h etc., to which I had linked previously), and replacing the original include directory, in the directory where avr-gcc seemed to be looking, which was in its own directory location /lib/gcc/avr/4.9.2/.
cd /lib/gcc/avr/4.9.2/
mv include include.old
cp -r /usr/avr/include .

Then the Arduino compiler seemed to work, until it then gave an assembler error:
Assembler messages
Error: unrecognized option -mmcu=avr5

This is an issue with avr-as.
I will update as I resolve these issues.

1 I eventually resolved this by creating a script in /usr/bin (where the arduino binary was located) called arduino.launch which contains the PATH settings and a call to arduino:
#!/bin/sh
PATH=${PATH}:/usr/libexec/gcc/avr/4.9.2
export PATH
arduino

setting it to be executable with chmod +x arduino.launch. Then I edited the properties of the Fedora Arduino launch icon, by right-clicking on the icon and selecting Properties, and changed the Command entry from arduino to arduino.launch.
However, there must be a better way of doing this, as this seems to be a bit of a hack.
2 Other posts 1, 2 and 3) that I have read, apart from providing useful paths to investigate, merely suggest reinstalling. However, as bone headed as I may seem, there must be a way of linking up what is already on the file system (everything is there - just in the "wrong" place), such that compiles work as they should.


text:
LED blinking issue
i made a distance measuring circuit with different led for different distance ranges
#define trigPin 13
#define echoPin 12
#define BPin 7
#define piezoPin 9
#define RPin 4
#define GPin 8

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

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

  if (distance >= 200 || distance <= 0) {
    Serial.println("Out of range");
  }
  else {
    Serial.print(distance);
    Serial.println(" cm");
  }
  delay(1000);
  {
    if (distance <= 25 || distance <= 0) {
      digitalWrite(RPin, HIGH);
    }
    else {
      digitalWrite(RPin, LOW);
    }
  }

  {
    if (distance >= 25 && distance <= 50) {
      digitalWrite(GPin, HIGH);
    }
    else {
      digitalWrite(GPin, LOW);
    }

    {
      if (distance >= 50 && distance <= 75) {
        digitalWrite(GPin, HIGH);
      }
      else {
        digitalWrite(BPin, LOW);
      }

      {
        if (distance >= 75 && distance <= 100) {
          digitalWrite(BPin, HIGH);
        }
        else {
          digitalWrite(GPin, LOW);
          {
            {
              if (distance >= 100 && distance <= 200) {
                digitalWrite(piezoPin, HIGH);
              }
              else {
                digitalWrite(piezoPin, LOW);
              }
            }
          }
        }
      }
    }
  }
}

everything is working fine except Gpin it is blinking please  help me
i am also uploading link to download my .ino file
link; https://www.datafilehost.com/d/e19b35d5

First align your code (put { and } nicely under each other which belong together, also remove unneeded { and } (like around if statements). Also do not indent when it's not needed (e.g. the pin mode settings).

I formatted your code, and your logic is extremely convoluted, and I suspect also incorrect in several places. I counted at least 5 unnecessary brackets, and inconsistent if/else structure. Also if something is lower then 25 it's already lower then 0.

I guess it should be if(distance blabla) digitalWrite(pinX,HIGH); else digitalWrite(pinX,LOW); (you have different pins in if/else case). Also two leds will be on when distance==50, distance==75 or distance==100 which I would consider a mistake.

This is your code without unnecessary brackets:
#define trigPin 13
#define echoPin 12
#define BPin 7
#define piezoPin 9
#define RPin 4
#define GPin 8

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

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

  if (distance >= 200 || distance <= 0) {
    Serial.println("Out of range");
  }
  else {
    Serial.print(distance);
    Serial.println(" cm");
  }
  delay(1000);

  if (distance <= 25 || distance <= 0) {
    digitalWrite(RPin, HIGH);
  }
  else {
    digitalWrite(RPin, LOW);
  }

  if (distance >= 25 && distance <= 50) {
    digitalWrite(GPin, HIGH);
  }
  else {
    digitalWrite(GPin, LOW);
  }

  if (distance >= 50 && distance <= 75) {
    digitalWrite(GPin, HIGH);
  }
  else {
    digitalWrite(BPin, LOW);
  }

  if (distance >= 75 && distance <= 100) {
    digitalWrite(BPin, HIGH);
  }
  else {
    digitalWrite(GPin, LOW);
    if (distance >= 100 && distance <= 200) {
      digitalWrite(piezoPin, HIGH);
    }
    else {
      digitalWrite(piezoPin, LOW);
    }
  }
}

Using the ternary operator you can write some if statements easier:
#define trigPin 13
#define echoPin 12
#define BPin 7
#define piezoPin 9
#define RPin 4
#define GPin 8

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

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

  if (distance >= 200 || distance <= 0) {
    Serial.println("Out of range");
  }
  else {
    Serial.print(distance);
    Serial.println(" cm");
  }
  delay(1000);

  digitalWrite(RPin, (distance <= 25 || distance <= 0) ? HIGH : LOW);
  digitalWrite(GPin, (distance >= 25 && distance <= 50) ? HIGH : LOW);

  if (distance >= 50 && distance <= 75) {
    digitalWrite(GPin, HIGH);
  }
  else {
    digitalWrite(BPin, LOW);
  }

  if (distance >= 75 && distance <= 100) {
    digitalWrite(BPin, HIGH);
  }
  else {
    digitalWrite(GPin, LOW);
    digitalWrite(piezoPin, (distance >= 100 && distance <= 200) ? HIGH : LOW);
  }
}

Some remarks to think about that helps you solve your sketch (and is the reason why your GPin may blink):

The line part (distance <= 25 || distance <= 0) can be rewritten to (distance <= 25) since if a value is less/equal than 0, it automatically is less/equal than 25.
You set based one a condition a pin to HIGH or another pin to LOW, I would expect both pins to change, or the same pin. But I don't know your requirements.
The 'edge' values (e.g. 25, 50, 75) fall in multiple conditions, you probably want to exclude the end edge. It is a sort of guideline to include the start and exclude the end, e.g. if (distance >= 50) && (distance < 75).

In your case you probably are best of checking the distance like this:
if (distance < 0)
{
   ...
}
else if (distance < 25)
{
   // 0 <= distance < 25)
   ...
}
else if (distance < 50)
{
   // 25 <= distance < 50)
}
...

or do it the other way around:
digitalWrite(GPin, 'condition in which GPin should be on' ? HIGH : LOW);
digitalWrite(BPin, 'condition in which BPin should be on' ? HIGH : LOW);

e.g. when you want the GPin to be on when between 0 and 25:
digitalWrite(GPin, ((distance >=0) && (distance < 25) ? HIGH : LOW);

I'm afraid your conclusion of point 1. is not correct. The first line is OK. But if a value is less or equal than 25 it is not automatically less then 0. e.g. the value 25 is less or equal then 25 but greater than 0. But the other direction is correct. I know, I count peas, it's my hobby ;-).

@PeterPaulKiefer I think I'm correct. If the distance is smaller than 0 it is always smaller than 25, thus the sub expression distance < 0 is unnecessary, as the range (-inifinit,0) is within the range of (-infinit, 25). If the operator would be an &&, than you would be correct.

Yes the formula you derived is correct, but you had written "since if a value is less/equal than 25, it automatically is less/equal than 0." And that is not correct.

Sorry perhaps the word "conclusion" irritates you, but I'm not a native English speaker. Perhaps I've misused it.

@PeterPaulKiefer No need to sorry, I just completely missed your point, I was focused on the formula, not the text. And you were right, so I fixed the answer. You didn't  irritate me at all, I just misinterpreted your text (I'm also not a native speaker). Thanks for your improvement, and I adapted my answer accordingly.

source: Stack Exchange

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

sort: votes


text:
exit status 1, cant compile , please help
/***************************************************
  This is our GFX example for the Adafruit ILI9341 Breakout and Shield
  ----> http://www.adafruit.com/products/1651

  Check out the links above for our tutorials and wiring diagrams
  These displays use SPI to communicate, 4 or 5 pins are required to
  interface (RST is optional)
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  MIT license, all text above must be included in any redistribution
 ****************************************************/
#define ILI9341_BLACK       0x0000  ///<   0,   0,   0
#define ILI9341_NAVY        0x000F  ///<   0,   0, 123
#define ILI9341_DARKGREEN   0x03E0  ///<   0, 125,   0
#define ILI9341_DARKCYAN    0x03EF  ///<   0, 125, 123
#define ILI9341_MAROON      0x7800  ///< 123,   0,   0
#define ILI9341_PURPLE      0x780F  ///< 123,   0, 123
#define ILI9341_OLIVE       0x7BE0  ///< 123, 125,   0
#define ILI9341_LIGHTGREY   0xC618  ///< 198, 195, 198
#define ILI9341_DARKGREY    0x7BEF  ///< 123, 125, 123
#define ILI9341_BLUE        0x001F  ///<   0,   0, 255
#define ILI9341_GREEN       0x07E0  ///<   0, 255,   0
#define ILI9341_CYAN        0x07FF  ///<   0, 255, 255
#define ILI9341_RED         0xF800  ///< 255,   0,   0
#define ILI9341_MAGENTA     0xF81F  ///< 255,   0, 255
#define ILI9341_YELLOW      0xFFE0  ///< 255, 255,   0
#define ILI9341_WHITE       0xFFFF  ///< 255, 255, 255
#define ILI9341_ORANGE      0xFD20  ///< 255, 165,   0
#define ILI9341_GREENYELLOW 0xAFE5  ///< 173, 255,  41
#define ILI9341_PINK        0xFC18  ///< 255, 130, 198

#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"

// For the Adafruit shield, these are the default.
#define TFT_CLK 13
#define TFT_MISO 12
#define TFT_MOSI 11
#define TFT_DC 9
#define TFT_CS 10
#define TFT_RST 8
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// If using the breakout, change pins as desired
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);

void setup() {
  Serial.begin(9600);
  Serial.println("ILI9341 Test!");

  tft.begin();

  // read diagnostics (optional but can help debug problems)
  uint8_t x = tft.readcommand8(ILI9341_RDMODE);
  Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDMADCTL);
  Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDPIXFMT);
  Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDIMGFMT);
  Serial.print("Image Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDSELFDIAG);
  Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX);
  /*
  Serial.println(F("Benchmark                Time (microseconds)"));
  delay(10);
  Serial.print(F("Screen fill              "));
  Serial.println(testFillScreen());
  delay(500);

  Serial.print(F("Text                     "));
  Serial.println(testText());
  delay(3000);

  Serial.print(F("Lines                    "));
  Serial.println(testLines(ILI9341_CYAN));
  delay(500);

  Serial.print(F("Horiz/Vert Lines         "));
  Serial.println(testFastLines(ILI9341_RED, ILI9341_BLUE));
  delay(500);

  Serial.print(F("Rectangles (outline)     "));
  Serial.println(testRects(ILI9341_GREEN));
  delay(500);

  Serial.print(F("Rectangles (filled)      "));
  Serial.println(testFilledRects(ILI9341_YELLOW, ILI9341_MAGENTA));
  delay(500);

  Serial.print(F("Circles (filled)         "));
  Serial.println(testFilledCircles(10, ILI9341_MAGENTA));

  Serial.print(F("Circles (outline)        "));
  Serial.println(testCircles(10, ILI9341_WHITE));
  delay(500);

  Serial.print(F("Triangles (outline)      "));
  Serial.println(testTriangles());
  delay(500);

  Serial.print(F("Triangles (filled)       "));
  Serial.println(testFilledTriangles());
  delay(500);

  Serial.print(F("Rounded rects (outline)  "));
  Serial.println(testRoundRects());
  delay(500);

  Serial.print(F("Rounded rects (filled)   "));
  Serial.println(testFilledRoundRects());
  delay(500);

  Serial.println(F("Done!"));
*/
}

void loop(void) {
  tft.fillScreen(ILI9341_NAVY);
  tft.setCursor(0, 0);
  tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2);
  tft.println(1234.56);
  tft.setTextColor(ILI9341_RED);    tft.setTextSize(3);
  tft.println(0xDEADBEEF, HEX);
  tft.println();
  tft.setTextColor(ILI9341_GREEN);
  tft.setTextSize(5);
  tft.println("Groop");
  tft.setTextSize(2);
  tft.println("I implore thee,");
  tft.setTextSize(1);
  tft.println("my foonting turlingdromes.");
  tft.println("And hooptiously drangle me");
  tft.println("with crinkly bindlewurdles,");
  tft.println("Or I will rend thee");
  tft.println("in the gobberwarts");
  tft.println("with my blurglecruncheon,");
  tft.println("see if I don't!");
  delay(5000);

}

unsigned long testFillScreen() {
  unsigned long start = micros();
  tft.fillScreen(ILI9341_BLACK);
  yield();
  tft.fillScreen(ILI9341_RED);
  yield();
  tft.fillScreen(ILI9341_GREEN);
  yield();
  tft.fillScreen(ILI9341_BLUE);
  yield();
  tft.fillScreen(ILI9341_BLACK);
  yield();
  return micros() - start;
}

unsigned long testText() {
  tft.fillScreen(ILI9341_BLACK);
  unsigned long start = micros();
  tft.setCursor(0, 0);
  tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2);
  tft.println(1234.56);
  tft.setTextColor(ILI9341_RED);    tft.setTextSize(3);
  tft.println(0xDEADBEEF, HEX);
  tft.println();
  tft.setTextColor(ILI9341_GREEN);
  tft.setTextSize(5);
  tft.println("Groop");
  tft.setTextSize(2);
  tft.println("I implore thee,");
  tft.setTextSize(1);
  tft.println("my foonting turlingdromes.");
  tft.println("And hooptiously drangle me");
  tft.println("with crinkly bindlewurdles,");
  tft.println("Or I will rend thee");
  tft.println("in the gobberwarts");
  tft.println("with my blurglecruncheon,");
  tft.println("see if I don't!");
  return micros() - start;
}

unsigned long testLines(uint16_t color) {
  unsigned long start, t;
  int           x1, y1, x2, y2,
                w = tft.width(),
                h = tft.height();

  tft.fillScreen(ILI9341_BLACK);
  yield();

  x1 = y1 = 0;
  y2    = h - 1;
  start = micros();
  for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
  x2    = w - 1;
  for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
  t     = micros() - start; // fillScreen doesn't count against timing

  yield();
  tft.fillScreen(ILI9341_BLACK);
  yield();

  x1    = w - 1;
  y1    = 0;
  y2    = h - 1;
  start = micros();
  for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
  x2    = 0;
  for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
  t    += micros() - start;

  yield();
  tft.fillScreen(ILI9341_BLACK);
  yield();

  x1    = 0;
  y1    = h - 1;
  y2    = 0;
  start = micros();
  for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
  x2    = w - 1;
  for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
  t    += micros() - start;

  yield();
  tft.fillScreen(ILI9341_BLACK);
  yield();

  x1    = w - 1;
  y1    = h - 1;
  y2    = 0;
  start = micros();
  for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
  x2    = 0;
  for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);

  yield();
  return micros() - start;
}

unsigned long testFastLines(uint16_t color1, uint16_t color2) {
  unsigned long start;
  int           x, y, w = tft.width(), h = tft.height();

  tft.fillScreen(ILI9341_BLACK);
  start = micros();
  for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1);
  for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2);

  return micros() - start;
}

unsigned long testRects(uint16_t color) {
  unsigned long start;
  int           n, i, i2,
                cx = tft.width()  / 2,
                cy = tft.height() / 2;

  tft.fillScreen(ILI9341_BLACK);
  n     = min(tft.width(), tft.height());
  start = micros();
  for(i=2; i<n; i+=6) {
    i2 = i / 2;
    tft.drawRect(cx-i2, cy-i2, i, i, color);
  }

  return micros() - start;
}

unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
  unsigned long start, t = 0;
  int           n, i, i2,
                cx = tft.width()  / 2 - 1,
                cy = tft.height() / 2 - 1;

  tft.fillScreen(ILI9341_BLACK);
  n = min(tft.width(), tft.height());
  for(i=n; i>0; i-=6) {
    i2    = i / 2;
    start = micros();
    tft.fillRect(cx-i2, cy-i2, i, i, color1);
    t    += micros() - start;
    // Outlines are not included in timing results
    tft.drawRect(cx-i2, cy-i2, i, i, color2);
    yield();
  }

  return t;
}

unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
  unsigned long start;
  int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;

  tft.fillScreen(ILI9341_BLACK);
  start = micros();
  for(x=radius; x<w; x+=r2) {
    for(y=radius; y<h; y+=r2) {
      tft.fillCircle(x, y, radius, color);
    }
  }

  return micros() - start;
}

unsigned long testCircles(uint8_t radius, uint16_t color) {
  unsigned long start;
  int           x, y, r2 = radius * 2,
                w = tft.width()  + radius,
                h = tft.height() + radius;

  // Screen is not cleared for this one -- this is
  // intentional and does not affect the reported time.
  start = micros();
  for(x=0; x<w; x+=r2) {
    for(y=0; y<h; y+=r2) {
      tft.drawCircle(x, y, radius, color);
    }
  }

  return micros() - start;
}

unsigned long testTriangles() {
  unsigned long start;
  int           n, i, cx = tft.width()  / 2 - 1,
                      cy = tft.height() / 2 - 1;

  tft.fillScreen(ILI9341_BLACK);
  n     = min(cx, cy);
  start = micros();
  for(i=0; i<n; i+=5) {
    tft.drawTriangle(
      cx    , cy - i, // peak
      cx - i, cy + i, // bottom left
      cx + i, cy + i, // bottom right
      tft.color565(i, i, i));
  }

  return micros() - start;
}

unsigned long testFilledTriangles() {
  unsigned long start, t = 0;
  int           i, cx = tft.width()  / 2 - 1,
                   cy = tft.height() / 2 - 1;

  tft.fillScreen(ILI9341_BLACK);
  start = micros();
  for(i=min(cx,cy); i>10; i-=5) {
    start = micros();
    tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
      tft.color565(0, i*10, i*10));
    t += micros() - start;
    tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
      tft.color565(i*10, i*10, 0));
    yield();
  }

  return t;
}

unsigned long testRoundRects() {
  unsigned long start;
  int           w, i, i2,
                cx = tft.width()  / 2 - 1,
                cy = tft.height() / 2 - 1;

  tft.fillScreen(ILI9341_BLACK);
  w     = min(tft.width(), tft.height());
  start = micros();
  for(i=0; i<w; i+=6) {
    i2 = i / 2;
    tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0));
  }

  return micros() - start;
}

unsigned long testFilledRoundRects() {
  unsigned long start;
  int           i, i2,
                cx = tft.width()  / 2 - 1,
                cy = tft.height() / 2 - 1;

  tft.fillScreen(ILI9341_BLACK);
  start = micros();
  for(i=min(tft.width(), tft.height()); i>20; i-=6) {
    i2 = i / 2;
    tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
    yield();
  }

  return micros() - start;
}

Did you install these libraries in the same folder that your sketch is in?
include "SPI.h"
include "Adafruit_GFX.h"
include "Adafruit_ILI9341.h"

yes but still i am getting the same error i am just a beginner please help

What's the exact text that compiler displays?

exit status 1
Error compiling for board Arduino/Genuino Uno.

@prashant And rest of the error message? Add it to the question and not to the comment. Example here: https://arduino.stackexchange.com/questions/45860/error-compiling-code-for-arduino-genuino-uno

that issue is fixed thanks for your help, but now the problem is my LCD has white light only no display please help.

Did yoy try to change co trast with potentiometer?

yes did that already but still white screen only, even i am using the program code of graphics test still white display please help

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


text:
Adding esp32_komoot_ble library to Arduino IDE
I am an absolute beginner with Arduino IDE and I want to build an interesting device I stumbled upon on github
https://github.com/jstiefel/esp32_komoot_ble
Problem is I really can not add it to Arduino IDE. I did the wiring for the lcd and all, but please bear in mind i'm an electrician, with a very basic understanding of arduino/ absolute beginner.
What i'm asking is which is  the "main file" in the src folder so i can rename it 'ino' to work with the arduino IDE  and upload it to the esp32 board?
I downloaded the esp32 library and all the dependencies that says in the readme.md file. I download the esp32_komoot_ble.zip file. Now how do I get the  .cpp and .h files on the arduino IDE and finally my esp32 device. I have been watching tutorial for 1 week now  but could not figure it out yet!
Thank you for everything guys!

The file, that you are searching, is the one, which contains the setup() and loop functions: esp32_komoot_ble.cpp
These functions are part of the Arduino framework and wrap the classic main() function. setup() is called once at startup, loop() after it repeating forever.

Tank you so much mate! I'm waiting for 'arduino for dummies' book ordered from amazon. Gotta start somewhere, right? Thank you again!


text:
Arduino security
My question is how secure can I make an Arduino? The project I am working on would put the Arduino out in the public (school campus inside a trash can to sense how much trash is in it) and I want to make sure random people can't access it and mess/change the code. Any suggestions would be helpful.
It will also be connected to the network and be sending data to a database.

Define "secure". Put in it a safe and it's "secure".

I'm voting to close this question as off-topic because it is about physical security, not Arduino.

I think the OP was asking about software security. That seems like a valid topic.

Software-wise, and Arduino is completely insecure. There is no login, there are no passwords, nothing. You just need a computer and access to the USB port. You will need to use physical security to protect it.

@DuncanC yes I want to know about password protection and other software protections and can i add them

No. If somebody has access to the USB port, there is no security.

@Majenko the OP clarified to indicate that they are asking about software security, so this seems like a valid question.

If the sketch (web-server part) does support data update the access can be restricted to specific MAC addresses. If the sketch uses Serial for configuration, etc, a password/encryption might be needed. In other cases, if the sketch only sends data to a server (database) there is not much to secure other than environment (tampering) of the device.

If I understand your question, then you want ensure, that nobody is able read and change your code to see, what are you doing and to send you fake data from that Arduino.
What are problems here:

It can be stolen (eventually with the entire trash bin) - means no fake data and no data
It can be vandalised/destroyed in matter of minutes (max) - again no (real/fake) data
The arduino can be reprogrammed by normal way (via bootloader) and send fake data - you can prevent that by changing the bootloader
Arduino can be read and reprogrammed by ISP and send fake data - you can lock it (by setting SPIEN) to prevent both reading its memory and to reprogramming it this way
the lock can be cleaned and chip erased and reprogrammed (but not read) by Chip Erase command from High Voltage programming. You can make it more difficult, if needed pins are attached to some devices or ground/power.
the chip can be desoldered, reprogrammed and soldered back to avoid problems with connected devices.
also the whole Arduino can be swapped with already tampered Arduino
another Arduino can be atached to the net to inject fake data (and maybe prevent the original from normal transfers by interference)
(so it have problems with physical security)

To mess with your data (send fake) such program need to be able send data in (somehow) correct format over the net. Without source code or at least the code in Arduino the format of the data could still be sniffed from transmissions and deciphered (but it is difficult task to do) and you can employ some crytography to make it even harder (but it would eat a lot of memory and computing power from your code).

Well, in practical life your problem is stolen/vandalised arduino and simple attacks, which can be blocked by locking the Arduino fuses and bootloader (but you would have hard time put update there after locking it) and using some cryptography.

thank you for the response it was very helpful

Software security features are not available in Arduino. However if you want to prevent people from flashing a new code to some extent, you can desolder the USB pins or use a version of Arduino like ProMini, that requires external USB connector for coding.

yes, just to some extent.


text:
please help with my arduino
My problem is when I run code like this:
char directioN;

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

void loop()
{
  if (Serial.available())
  {
    directioN = Serial.read();

    switch (directioN)
    {
      case 'F':
        break;

      case 'B':
        break;

      case 'R':
        break;

      case 'L':
        break;

      default :
        break;
    }

    Serial.print("direction is:");
    Serial.println(directioN);
  }
}

My serial monitor add another input, but the second one is empty; this happened here with char both as with int.
But when i tried the same code in tinkercad it worked fine.
So do I really need a new ATMEGA328 or it can be done by software or something?
**I use an Arduino Uno

what have you set in Serial Monitor as line ending to send?

So why you don't just ignore it?
if(directionN >= 32){   //check if char is readable ascii character
  Serial.print("direction is:");
  Serial.println(directioN);
}

How i ignore. it affect how my code run cause a specific input do a specific function so the following zero or null input which im talking about here cause the wanted function to end

@nouralbrmky Like in the code i posted, null input is probably newline.

It worked fine thank you .do u have any idea what may cause some thing like that to happen and i 'll be more thankful

@nouralbrmky It's probably caused by newline character which is sent after text. Newline decimal value in ascii table is smaller than 32 and that's why this code ignores it.


text:
Connecting NodeMCU through internet
I have a NodeMCU and a website (free website domain provided by http://www.hpage.com) and I have to send and receive some data (suppose a 8bit number) from the website to the NodeMCU via internet. The NodeMCU is connected to internet through WiFi hotspot of an Android phone.

Can anyone provide an example code? How can I address the NodeMCU from the website?
Does the NodeMCU need to be a server or just a client?

Thanks in advance for kind help.

How can I address the NodeMCU from the website?

You can't. The NodeMcu is behind the phone, behind a router, behind a gateway of the operator etc. It can access the Internet over the infrastructure routing it out, but is not visible from the Internet.

Does the NodeMCU need to be a server or just a client?

The device should be a client and open the communication to the server by sending a request and renewing the connection if it times out. You can use WebSockets or MQTT or similar framework.

Well, I have seen people address devices connected to router by the name of service port. Isn't it possible for Android? Some apps use this service port address to share data over wifi. Anyway, thanks for mentioning. I'll try MQTT.

to setup port forwarding  you must have a public IP address and control over router/gateaway. other option is to use a VPN set on a server in Internet

@Shounak, did the answer help?


text:
RF Rx with NodeMCU error
I am using RF Tx with Arduino Uno and Rx with NodeMCU. I use RF switch library. At the recipient side if I use an Arduino Uno MCU. I can receive the output, but with NodeMCU I have a blank serial monitor; no output is shown. RF.enable (0) is used in my code and pin D2 is connected to data of RF module.
Some one help me please.

why not RF.enable(D2)?

The RF.enable(0) is the actual code line given in the example section .. will try what you have suggested.

Pin D2 is GPIO4 ... does the (0) specify the GPIO pin the RF module is connected to - if so, that's the problem ... either use (4) or (D2)


text:
Send files via network
I want to send a file from an Arduino to the server or another Arduino.
I wrote a code that's open the file then write the content of the text on an array and then send it.
That would work if the data is small, but when i try to send, .wav it will takes lots of time if i do it that why (storing each byte in array).
I want to send the whole file at on time.
Is there a way or a library helps ?
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SD.h>

const int push1 = 2;

File myFile;
char a[400];
int c= 0;

// network parameters
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0E, 0x05, 0x02 };  // ethernet interface MAC address
IPAddress localIp(10,131,41,72);    // local ip address
IPAddress destIp(10,131,41,74);      // destination ip address
unsigned int port = 9631;               // destination port

// EthernetUDP to send and receive messages.
EthernetUDP Udp;

// timing

// setup the arduino and shields
void setup() {

    pinMode(push1, INPUT);

  //Initialize serial and wait for port to open:
  Serial.begin(9600); // 19200
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

  // start ethernet and udp
  Ethernet.begin(mac, localIp);   // static ip version
  //if(Ethernet.begin(mac) == 0) {     // dhcp version
  // report failure to obtain network parameters
  // Serial.println("DHCP error");

  // no point in carrying on, loop indefinitely:
  // while(true)
  // ;
  //}

  // open UDP port
  Udp.begin(port);

  // show the local ip address (useful for dhcp)
  Serial.print("Local IP: ");
  Serial.println(Ethernet.localIP());

  // initialize previous millis variables

}

// do tasks
void loop() {

if(digitalRead(push1) == LOW){

   myFile = SD.open("R.wav" , FILE_READ);

  if (myFile) {
    // read from the file until there's nothing else in it:
    Serial.println("i will send now");
    while (myFile.available()) {
        a[i] = myFile.read();
        i++;
        }
      Udp.beginPacket(destIp, port);
     Udp.write(a);
      Udp.endPacket();
      Serial.println("Sending UDP message");
      Serial.println();
    }
    // close the file:
    myFile.close();
  } else {
   // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }  } }

You may try:
Serial.println("Sending UDP message");
Udp.beginPacket(destIp, port);
while (myFile.available()) {
  Udp.write(a);
}
Udp.endPacket();
Serial.println("Message sent!");

Or send the message part by part (for example 100bytes or 500bytes at a time)
Though, what makes you think that Arduino would be a platform that can rapidly send large files over network?
Potentially you are better off with an Raspberry Pi.


text:
Debugging with ISP
I would like to connect the Atmega328p chip to my desktop, through the USB, so I can run teraterm or hyperterminal for debugging purposes.
I have already ordered a USB to TTL serial cable but it won't be arriving for about a week.
I recently bought a usbASP ISP to program the chip on my Arduino.
My question is: can I use the usbASP in place of the TTL cable? or is there some conditioning circuit in the usbASP that won't allow this?
It seems for the usb to ttl, all that is required to interface with the chip is VCC, GRD, RX and TX. So, which pins are the RX and TX?
Hope my question makes sense, they usually don't! thanks in advance!

For simple debugging you could just add a few leds. Optionally make them blink in certain patterns for more complex information.

There is provision in the USBasp specification for a UART connection, however, not all manufacturers copy the original schematic exactly, and no firmware actually contains the appropriate code for CDC/ACM required in order to enable it. And even if they did, technically low-speed CDC/ACM is a violation of the USB protocol and not all operating systems will acknowledge it.
As for your title of "Debugging with ISP", if you have an Atmel programmer and are using Atmel Studio then you can perform debugging over ISP (actually debugWIRE, but they use the same connections).

So i can output messages to Atmel Studio? Say, outputting a voltage as a turn a pot, from the adc?

No. But you can use debugWIRE to inspect the register contents when the code hits a breakpoint.

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


text:
Understanding the contents of a library in C
So this is a question not just about the #include  but most all includes you find while programming in C.
So I understand a library is prewritten code and when you include that library are you able to used certain function that are included in that library.
What I have always wanted to know is: where can you find the "instruction set", in C, for these libraries?
How can I find out what commands are available for me to use with this library?
hope this makes sense.
thank you everyone.

A library provides an Application Program Interface (API) and the API should be documented with the library somewhere, but the quality of that documentation varies depending on the library.  Maybe https://www.arduino.cc/en/Reference/Libraries is a place to start?

where can you find the "instruction set", in C, for these libraries? Libraries come with either binary or source files. You should include the header file (.h or .hpp) in this file you can find the function definitions along with (usually) comments.
If you have a implementation file (.c or .cpp) these will have the (C/C++) source code available.

What I have always wanted to know is: where can you find the "instruction set", inc C, for these libraries?

The libraries are usually found in the libraries sub-folder under your sketchbook folder (wherever that is). There is also another libraries folder inside the IDE install folder for the "official libraries".

How can I find out what commands are available for me to use with this library?

Usually the library documents them in one way or another. Try looking inside the .h file used by the library to see what functions are exposed.

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


text:
How to save data to SD card using Memory Shield Module SPI
I am trying to save some data to the SD card using the memory shield module that I read from HC-SR04 Ultrasonic Module. The data that gets printed indicates error. This is how my SD card module is connected.

SD card attached to SPI bus as
  VCC -Arduino 5v
  GND- Arduino GND
  MOSI - pin 11
  MISO - pin 12
  CLK - pin 13
  CS - pin 4

Still, Arduino complains that there was an error opening the file in SD card. My sketch is this:
#include <SPI.h>
#include <SD.h>
#define echoPin 6 // Echo Pin
#define trigPin 7 // Trigger Pin

int maximumRange = 250; // Maximum range needed
int minimumRange = 1; // Minimum range needed
long duration, distance; // Duration used to calculate distance
const int chipSelect = 4;

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

  Serial.print("Initializing SD card...");
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
}

void loop() {
  readDistance();
  if(distance>minimumRange && distance < maximumRange){
    String string = "distance is" + distance;
    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    File dataFile = SD.open("datalog.txt", FILE_WRITE);
    // if the file is available, write to it:
    if( dataFile ){
      dataFile.println(string);
      dataFile.close();
      Serial.println( string );
    }else{
      // if the file isn't open, pop up an error:
      Serial.println("error opening datalog.txt");
      dataFile.close();
    }
  }else{
    Serial.println("Out of range...");
  }
  delay(50);
}

int readDistance(){
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = duration/58.2;
}

Output:
rror opening datalog.txt
rror opening datalog.txt
error opening datalog.txt
rror opening datalog.txt
error opening datalog.txt
error opening datalog.txt
error opening datalog.txt
error opening datalog.txt
error opening datalog.txt

How do I solve this to save the readings to SD card?

Re-opening the file each time through the loop seems like a bad idea.  Unfortunately file system abstractions don't map very well to what you want to do.  You may want to write a number of readings, then re-open a file, perhaps with a different name in an incrementing pattern.  Or you could skip the filesystem and write to raw blocks.  Most practically, have a look at the code typically used with Arduino-based uSD data loggers and see what you can learn from how they handle it.

I think you have fried your SD card. Those cards operate at 3.3V and may not be 5V tolerant.

Is there any print out based on this;
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
  Serial.println("Card failed, or not present");
  // don't do anything more:
  return;
}
Serial.println("card initialized.");

Solution;
Try change
const int chipSelect = 4; // change value to 10

If not, try change the above code to;
Serial.print("Initializing SD card...");
if (!SD.begin(10)) {
  Serial.println("Initialization failed!");
  while (1);
}
Serial.println("Initialization done.");


text:
Making three LED's blink at given times
I have a breadboard connected to an Arduino Uno, 220k resistors connected to an led, of course it has a common ground and a pin connected to 5v. All pins are digital.
Now, I want led 1 to turn on for one second, the next led for two seconds and the next for three seconds, but that means, when the second led which has to be on for two seconds then the first led will come back on after one second has past on the second led, the third led would be on for three seconds, so the second led will also be on when two seconds pass and the first would be on when one second passes. So basically, all leds are on for their given duration.
How do I do this? I have been trying to do this since three days. It would be a pleasure if someone helps me out. Thanks.
int ledPin1= 2;
int ledPin2 = 4;
int ledPin3 = 7;

void setup(){
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  }

  void loop(){
  digitalWrite(ledPin1, HIGH);
  delay(500);
  digitalWrite(ledPin1, LOW);
  delay(500);

  digitalWrite(ledPin2, HIGH);
  delay(1000);
  digitalWrite(ledPin2, LOW);
  delay(1000);

  digitalWrite(ledPin3, HIGH);
  delay(1500);
  digitalWrite(ledPin3, LOW);
  delay(1500);
    }

So far this is the code. But it delays the whole program. Need leds on at given times.

You could start by drawing a time graph, like this:
LED 1   # # # # # # # # # # # # # # # # # #
LED 2    ##  ##  ##  ##  ##  ##  ##  ##  ##
LED 3      ###   ###   ###   ###   ###   ###
        <-period 1-><-period 2-><-period 3->

As you see on the graph, the whole sequence repeats itself every
12 seconds. Then, you can just write down all the pin toggles for
12 seconds and let the loop repeat itself:
void loop() {
    digitalWrite(ledPin1, HIGH);
    digitalWrite(ledPin3, LOW);
    delay(1000);
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, HIGH);
    delay(1000);
    digitalWrite(ledPin1, HIGH);
    delay(1000);
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, LOW);
    digitalWrite(ledPin3, HIGH);
    delay(1000);
    digitalWrite(ledPin1, HIGH);
    delay(1000);
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, HIGH);
    delay(1000);
    digitalWrite(ledPin1, HIGH);
    digitalWrite(ledPin3, LOW);
    delay(1000);
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, LOW);
    delay(1000);
    digitalWrite(ledPin1, HIGH);
    delay(1000);
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, HIGH);
    digitalWrite(ledPin3, HIGH);
    delay(1000);
    digitalWrite(ledPin1, HIGH);
    delay(1000);
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, LOW);
    delay(1000);
}

This was the simple, albeit tedious solution.
The smart solution is to go through the Blink Without Delay Arduino
tutorial. You will see that, once you start using millis() instead of
delay() for managing your timings, blinking three LEDs instead of one
is completely trivial.

EDIT: I just love Finit State Machines and templates to do some simple tasks:
class FSM {
  public:
    using Handler = void(*)(FSM &);

    FSM(Handler hnd) : m_func{hnd} {}

    void check(uint32_t ts = millis()) {
      if (m_next < ts) {
        m_func(*this);
      }
    }

    void delay(uint32_t _delay) {
      m_next += _delay;
    }

    void nextState(uint8_t state) {
      m_state = state;
    }

    uint8_t state() { return m_state; }

  protected:
    Handler   m_func;
    uint8_t  m_state = 0;
    uint32_t  m_next = 0;
};

template <uint8_t PIN, uint32_t HIGH_DELAY, uint32_t LOW_DELAY> void pin_fsm(FSM & fsm) {
  switch (fsm.state()) {
    case 0:
      pinMode(PIN, OUTPUT);
      // fall through
    case 1:
      digitalWrite(PIN, HIGH);
      fsm.delay(HIGH_DELAY);
      fsm.nextState(2);
      break;
    case 2:
      digitalWrite(PIN, LOW);
      fsm.delay(LOW_DELAY);
      fsm.nextState(1);
      break;
  }
}

FSM fsms[] = {{&pin_fsm<2,500,500>}, {&pin_fsm<4,1000,1000>}, {&pin_fsm<7,1500,1500>}};

void setup() {

}

void loop() {
  auto ts = millis();
  for (FSM& fsm : fsms) fsm.check(ts);
  delay(1);
}

The code should be working, so as mentioned before in that duplicate thread, 220k is far bigger than it should be. So just use 220R (= 220 Ohms) instead of 220k Ohms (= 220000 Ohms).
And if it's not working even with correct resistor, your LED is connected in reversed direction. Try the builtin LED on pin 13. That one must be working. Anyway you should read something about LEDs.

How about this? Basically each loop is 1sec, and each LED has it's own counter which increases. If the counter is higher than the LED number/onTime, the LED is off for that loop and the conter reset, otherwise LED is on.
uint8_t LED[3] = { 2, 4, 7 };
uint8_t LED_COUNTER[3] = { 0, 0, 0 };

void setup() {
  for (int i = 0; i < 3; i++) {
    pinMode(LED[i], OUTPUT);
  }
}

void loop() {
  for (int i = 0; i < 3; i++) {
    if (LED_COUNT[i] = i) { LED_COUNT[i] = 0; }
    else {
      digitalWrite(LED[i], 1);
      LED_COUNT[i] += 1;
    }
  }
  delay(1000);
}

You are never switching the LEDs off.

There is a problem with the led count

Yes sorry it was mainly intended to explain the concept, I didn't go much in detail. Either way I see on the duplicate of this question there is a far better solution...


text:
Connecting Peltier module to Arduino Nano
I am a beginner to Arduino programming and started working on my first Arduino project recently to power a Peltier cooling pad. Below is the code I used and in the circuit,
I connected the positive (red wire) end of the Peltier to D12 of Nano Arduino board and the negative end( black wire) to the negative end of the 6V battery. Then I powered the Arduino board by connecting Vin(Arduino) and battery(+) using a jumper wire. The GND pin of the Arduino was connected to the battery(-) using a jumper wire.
The Peltier is not working and it would be a great help if someone can help me to understand what I did wrong.
int p=12;

void setup() {
   pinMode(p,OUTPUT);
}

void loop() {
   digitalWrite(p,HIGH);
   delay(2000);
}

Note that you set pin 12 to HIGH, but you never change it (is that intentionally?) .. In this case you could have set it high in setup and remove the delay (meaning the loop will stay empty).

Arduino cannot provide the amount of current that Peltier needs to heat up. Arduino cannot power devices it can only steer something that powers them. Try checking out a relay shield or read about MOSFET.

Hi Michel and Flip, Thank you very much for the responses. I am a beginner to electronics and Arduino and your support is highly appreciated. I found below example online, which is powering a Peltier using an Arduino and wanted to build a simple circuit with the same principle using Nano Arduino board. If I connect a resistor to the circuit will it function?

https://www.instructables.com/id/How-to-Set-Up-a-Peltier-Module/

Find a different tutorial, cause that one is terrible. I you read the comments for that tutorial, you see that they point to the same problem Michel and Filip told about.

Hi Filip and Gerben, Thank you very much for the comments. I tried making the circuit, and the Peltier is not functioning. As suggested in the comments of that tutorial, I thought of using a motor driver for the Peltier and found below article, which is a bit complicated for a beginner like me. However, I made the circuit following instructions, but the Peltier and the circuit are still not working. Please tell me whether the instructions and circuit in this article are correct?

Is there a simple method to connect Peltier to Arduino using a Motor driver.?  As suggested by Filip, I read about MOSFET, but couldn't figure out how to connect it to the circuit. It would be a great support if you guys could assist me.

https://www.instructables.com/id/Smartphone-Operated-Smart-Wristband-for-Personal-A/

I'm in a helpless situation now due to lack of my knowledge in this domain. I did a lot of reading also bit still couldn't figure out the solution. I was continuously working on this circuit and determined to find a solution and your help will be a great support for me.

You could use a motor driver, but it's overkill. See Filip's answer, using a single MOSFET transistor and a pull-down resistor. That's all you need. (Note that you may have fried the pin on your Arduino by trying to push too much current through it. An Arduino pin can only put out ≈20mA, and your peltier junction probably draws a couple of amps (100X more than the max).

Note that you COULD use a motor driver to drive the Peltier junction in both cooling and heating mode (motor drivers have "H Bridge" circuits that let you push current in either direction. If you power a Peltier junction the opposite way, it heats instead of cools.)

I prepared a little circuit that should help you safely connect the Peltier module to Arduino. It uses a single n-channel MOSFET and 1K resistor.
I couldn't find any Peltier in Tinkercad so instead I used a simple light bulb. (In previous version of this answer I used a DC motor, but it was not a good replacement for Peltier module)
When Arduino Pin12 is HIGH light is bright (high current flows through it just like it should through the Peltier) when Pin12 is LOW light bulb goes dark (no current is flowing)

One note to other readers: Don't wire a motor that way. It will fry the transistor. If you're going to power a motor you need a flyback diode to protect the transistor from back EMF from the motor's inductive coils.

Hi Filip,  Thank you very much for guiding me and the circuit diagram is very helpful. I will make the circuit and will check the functionality.  Really appreciate your help. :)

Hi Duncan,  Thank you very much for guiding me.
Regarding your last comment on ' motor', does that apply to Peltier circuit as well as I am planning on making the circuit following the diagram proposed by Filip.      Well noted your suggestion to use a motor drive to make a circuit to get both heating and cooling effect from Peltier. I will try working on that circuit after finalizing the circuit with MOSFET( proposed by Filip).

@DuncanC I changed DC motor to a light bulb. No extra circuitry is required for light bulb and Peltier module.

Filip, good idea. Indee, A Peltier junction and a  light bulb are both simple resistive loads, and don't require flyback diodes. That's only needed for inductive loads like motors and relay coils.

Indee, you could also rig 2 MOSFET transistors to run your peltier junction as either a heater or a cooler. (You'd make one MOSET feed current in one direction when it was energized, and wire the other one to feed current in the opposite direction. You'd either have to make certain that you'd never turn on both transistors at the same time, or add a high current diode to avoid a short circuit if both transistors are turned on at the same time (which would likely destroy the transistors)

Hi Filip and Duncan, I made the circuit and it worked well with the Peltier. But I had to connect the system into 1.5x4 V battery. Thank you very much for your guidance and really appreciate your support. Now I will try the circuit with 2 MOSFET transistors to get both heating and cooling.


text:
Measuring time between two photoresistors and printing time on lcd
I am working on a project that is supposed to record the time difference between two photoresistors that are 4in apart. The photoresistors are sensing the passing of water or other liquids on a chute/ramp.
The liquids range from water to milkshakes so the time difference shouldn't be more than 2 or 3 seconds at most (I would think). I'm okay with the accuracy being off by a a few tenths of a second.
I am using Photo cell (CdS photoresistor) for my project.
I have looked online and haven't seen a similar project. I want to be able to display the time difference on a lcd.
I have my lcd up and running but I'm not sure how to code the time difference. My photoresistors are connected to A0 and A1 and I am using digital pins 7-12 for the lcd. If anyone has any advice that would be very appreciated!
I'm sure I missed something so ask any clarifying questions

Please edit your question (click "edit") to answer the following:  Is the time difference a few tenths of seconds, milliseconds, or what?  How accurate does your measurement need to be?  What is your photoresistor part number?  Can you read it via a digital comparison, or does it need to be analog input for some reason?  How frequently do measurements need to be made?

You are asking about

the time difference between two photoresistors

This, to start with, makes little sense. Photoresistors are analog
devices. Their resistance, and thus the voltage you measure, is a
continuously varying quantity. The first thing you have to do is to turn
them into logic (i.e. either “off” or “on”) devices. The simplest
approach is to compare your analog reading to a threshold:

if the reading is above the threshold, you will say LDR is in the
HIGH state
if it is below the threshold, the LDR is in the LOW state.

There is a problem with this simple approach though: when the reading is
close to the threshold, the ambient noise can make many spurious
transitions between LOW and HIGH. The simplest solution is to have
not one, but two thresholds. This is called “hysteresis” and is
something you definitely should have whenever you are using thresholds
against analog readings. This can be coded as follows:
const int THRESHOLD_LOW  = 400;  // dummy value
const int THRESHOLD_HIGH = 600;  // dummy value

int HystereticRead(uint8_t pin, int previousState)
{
    int reading = analogRead(pin);
    if (previousState == LOW && reading >= THRESHOLD_HIGH) {
        return HIGH;
    } else if (previousState == HIGH && reading < THRESHOLD_LOW) {
        return LOW;
    } else {
        return previousState;
    }
}

Obviously, the thresholds you will use will not be these dummy values:
you will determine them from experiment.
Next thing is to record transitions. You do not want to look for a
particular state of the LDR, but for the moment it moves from one state
(say LOW) to the other. This is done by comparing the new state you
read to the previous one, as in:
static int state0;  // state of the LDR 0
int new_state = HystereticRead(A0, state0);
if (state0 == LOW && new_state == HIGH) {
    // LDR 0 went from LOW to HIGH.
}
state0 = new_state;  // save for next time

Last thing, and really the simplest, is to record times. You just have
to call millis() to get a timestamp, and compute a difference between
timestamps to get a duration in milliseconds. Here is how you could
write it:
void loop()
{
    static int state0, state1;  // states of the LDRs
    static uint32_t time0;      // last time LDR 0 went HIGH

    // Check for LDR 0 going HIGH.
    int new_state = HystereticRead(A0, state0);
    if (state0 == LOW && new_state == HIGH) {
        time0 = millis();
    }
    state0 = new_state;

    // Check for LDR 1 going HIGH.
    new_state = HystereticRead(A1, state1);
    if (state1 == LOW && new_state == HIGH) {
        uint32_t time1 = millis();
        Serial.print(time1 - time0);
        Serial.println(" ms");
    }
    state1 = new_state;
}

Thank you, Edgar! This was very comprehensive and, better yet, worked!

The most accurate approach is via In out capture on your timer.
Alternatively you can use an interrupt to start and stop the timer.
The worst approach is to poll
However, phtoresistors are slow and generally inconsistent. This can lead to errors in reading. S phototransistor or diode works better.
Edit: it is crazy to try to read the signal in analog. Instead design the circuitry so that it breaches the digital low or high thresholds so you can use digitalRead instead.
You can simply use millis or micros to time stamp the events and calculate the difference.
If you want more precise timing measurements, Google ticks implementation.
edit 2:
here is what I tried:
if (dtime_running==0) {             //event 1 has not arrived
    if (EVENT_ON(EVENT1_PIN)) {     //event 1 has arrived
        dtime = time_now();         //time stamp the event
        dtime_available = 0;        //data not yet available
        dtime_running = 1;          //time measurement running
    }
} else {                            //event 1 has arrived and now wait for event 2
    if (EVENT_ON(EVENT2_PIN)) {     //and event 2 has arrived
        dtime = time_now() - dtime; //calculate the timing difference
        dtime_available = 1;        //data now available
        dtime_running = 0;          //stop taking measurement
    }
}

On two pulses that are 500ms apart, here is the measurement:

Notice that in the box on the upper right, dtime has a value of 500, just as we expected.
the risk with this approach is that if the loop has other tasks, jitters to the measurement will show up. but for slow events, or long time measurements, it may not matter that much.

Polling is more than fine if you are after a resolution in the 100 ms range.

+1 for highly relevant point about CdS response times.

I assume you want to measure the difference in time between drops or a change in the resistance of the photo resistors?
Measure every x ms the values of the photo resistors. You can use a sleep for this (or maybe you can just continuously measure).
You have to store the measurements probably, to calculate, when a signal is changing. Also you have to store the times.
E.g.
      Resistor 1    Resistor 2
 0 ms          10            20
10 ms          10            20
20 ms          30           600     Drop at resistor 2
30 ms          30           620     Drop at resistor 2
40 ms          45            20     Drop passed resistor 2
50 ms         400            20     Drop arrived at resistor 1

So you know that the drop (delay) is 50 - 20 = 30 ms
You have to make an algorithm that will see this change, and also you might have to take into account multiple drops (so counting of drops/signal changes).


text:
Issue with code for SDA/SCL TC9548A Multiplexer and HMC5883L sensors
This is my first time posting on this forum, so I hope my question is appropriate here. My team is working with the Adafruit TCA9548A 1-to-8 I2C Multiplexer Breakout board to try and read from six HMC5883L Breakout sensors, and I am in the process of trying to look at their code to solve a problem. For some reason, code does not run at all unless you comment out a certain line in the code. Once it is commented out, the code runs as expected.
Now, we have to initialize it in setup(), but the statement tcaselect(0) statement was commented out so it doesn't initialize the 0th sensor in setup(). We can keep the other part, the if(mag0.begin()) statement, and it works as expected. However, if we uncomment out tcaselect(0) in setup, the entire code crashes, and all we see are 'HM' in the display window. A very basic schematic is shown below:

simulate this circuit – Schematic created using CircuitLab
I ran some tests with my team, and when all six HMC5883Ls and the single TCA9548 multiplexer were connected on the same breadboard according to the schematic, they worked when tcaselect(0) in setup() was not commented out. Next, we had an apparatus to hold the six sensors, and we had it connected with long lengths of wire, the same as the schematic. We hooked it up to the same breadboard, and the code would not run unless tcaselect(0) in setup was commented out. This seems strange to me that they would work when connected on the breadboard, but when spread out and connected to the breadboard via long wires, they would not work unless that code was commented out.
https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout?view=all
https://learn.adafruit.com/adafruit-hmc5883l-breakout-triple-axis-magnetometer-compass-sensor/overview
EDIT: Someone mentioned that wires might have problems with the SDA/SCL bus, so the wires that we're using are 4-pin ribbon cables, 2.54 mm pitch. A very rough schematic of the container that we're using is shown below:

simulate this circuit
Sorry for the roughness. It's the best I can do to show how the container is assembled. There's an 8x8 in. box where the components are stored, so the sensors go from various locations in the apparatus to the center box where the Pi, Arduino, and breadboard are placed. The nodes in the schematic represent the locations of the sensors. Given the rough dimensions, the longest distance for one of the sensors is around 56.8 inches (or approx. 1.45 meters) accounting for some extra wiring.
Code:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>

#define TCAADDR 0x70

/* Assign a unique ID to this sensor at the same time */
Adafruit_HMC5883_Unified mag0 = Adafruit_HMC5883_Unified(0);
Adafruit_HMC5883_Unified mag1 = Adafruit_HMC5883_Unified(1);
Adafruit_HMC5883_Unified mag2 = Adafruit_HMC5883_Unified(2);
Adafruit_HMC5883_Unified mag3 = Adafruit_HMC5883_Unified(3);
Adafruit_HMC5883_Unified mag4 = Adafruit_HMC5883_Unified(4);
Adafruit_HMC5883_Unified mag5 = Adafruit_HMC5883_Unified(5);

//Display details of sensor here
void displaySensorDetails(Adafruit_HMC5883_Unified *mag){
  sensor_t sensor;
  mag->getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value);         Serial.println(" uT");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" uT");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" uT");
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}

//Given sensor i, select and write to it
void tcaselect(uint8_t i) {
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}

    void setup() {
  Serial.begin(9600);
  /* Initialise the 0st sensor */
   //tcaselect(0);
   if(!mag0.begin())  {
    /* There was a problem detecting the HMC5883 ... check your connections */
    Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
   }

  /* Initialise Sensors 1-6 */
  tcaselect(1);  if(!mag1.begin())  {  Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");  }
  tcaselect(2);  if(!mag2.begin())  {  Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");  }
  tcaselect(3);  if(!mag3.begin())  {  Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");  }
  tcaselect(4);  if(!mag4.begin())  {  Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");  }
  tcaselect(5);  if(!mag5.begin())  {  Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");  }

}

void loop() {
  /* Get a new sensor event */
  sensors_event_t event0;  sensors_event_t event1;
  sensors_event_t event2;  sensors_event_t event3;
  sensors_event_t event4;  sensors_event_t event5;

  tcaselect(0);  mag0.getEvent(&event0);  tcaselect(1);  mag1.getEvent(&event1);
  tcaselect(2);  mag2.getEvent(&event2);  tcaselect(3);  mag3.getEvent(&event3);
  tcaselect(4);  mag4.getEvent(&event4);  tcaselect(5);  mag5.getEvent(&event5);

  /* Display the results (magnetic vector values are in micro-Tesla (uT)) */
  Serial.print(event1.magnetic.x); Serial.print("  ");
  Serial.print(event1.magnetic.y); Serial.print("  ");
  Serial.print(event1.magnetic.z); Serial.print("  ");

  Serial.print(event2.magnetic.x);      Serial.print("  ");
  Serial.print(event2.magnetic.y);      Serial.print("  ");
  Serial.print(event2.magnetic.z + 37); Serial.print("  ");

  Serial.print(event3.magnetic.x); Serial.print("  ");
  Serial.print(event3.magnetic.y); Serial.print("  ");
  Serial.print(event3.magnetic.z); Serial.print("  ");

  Serial.print(event4.magnetic.x); Serial.print("  ");
  Serial.print(event4.magnetic.y); Serial.print("  ");
  Serial.print(event4.magnetic.z + 37); Serial.print("  ");

  Serial.print(event5.magnetic.x); Serial.print("  ");
  Serial.print(event5.magnetic.y); Serial.print("  ");
  Serial.print(event5.magnetic.z); Serial.print("  ");

  delay(500);
}

EDIT: Big news, I tried using only two sensors and 1.5m cables and adding 10k pullup resistors from VCC to SDL/SCA on the respective sensors; with these changes, they seem to work even with tcaselect(0) not commented out in setup, though I only used two sensors rather than six. The HMC5883L sensor breakout board contains 10k pullup resistors already, so with another 10k resistor per line, it would make it 5k. Would this value be too much, or is it fine? I looked at the datasheet of the sensor itself, but I can't find anything on what value the input impedance would be for SCL/SDA.
Also, on another related note, one of my sensors had wires crossed deliberately, so SCL and SDA are separated by GND and VCC in the cable. I'm still running tests to see if I need to do this, but is it recommended to do so even if it is not necessary for correct operation? Someone mentioned that having SCL/SDA next to each other would be bad if they cause problems with crosstalk/interference.

You could follow that tutorial from start to finish. There is a I2C scanner for each of the 8 channels. You could run that to see what it finds. How many pullup resistors did you add. I think that you need 2 pullup resistors that are on the multiplexer module, and 16 more pullup resistors. Did you read the note about the pullups in the "I2C Multiplexed-Side pins" paragraph ? Don't select a channel without pullups, when SDA or SCL is low, the Arduino I2C scanner stops working.

It stops at your dummy sensor ? What is a hardware dummy I2C sensor ? I have never heard of it before. Did you ask patent for it ? You might be the only one in the world that has one.

Thanks for your replies. Sorry, I use the term dummy sensor to denote a sensor that is attached to the setup, but we don't use it. It's just another HMC5883L, but we don't use it.

The HMC5883L breakout board has 10k pullup resistors from the SCL/SDA pins to VCC, so there's no problems there. For the multiplexer itself, we didn't add any pull up resistors. I saw the paragraph, but with the pull ups on the sensor, it should be fine, right?

Yes, pullup resistors on the HMC5883L module are fine. Select only the channels that have the pullup resistors. When nothing is running and Wire.begin() has been called, all SDA and SCL pins on both sides of the multiplexer should be high.

I apologize, but this doesn't exactly help with my problem. All of the sensors that we are using contain pullup resistors. It's just that something seems to happen when we don't have a sensor connected to SD/SC0 on the multiplexer, so we can't read from the other sensors as well. Looking at tcaselect, it seems to write an 8-bit signal to TCAADDR, but with a '1' bit depending on the device. If that's the case, then TCAADDR should be no problem.

@user101402 did you try with just one sensor?

Yes, I tried it with one sensor on a breadboard. Then I moved up to two, three, and then seven sensors. After that, I hooked up the sensors to sections of an apparatus and connected them to the breadboard with long wires. The wires were properly connected according to my new schematic, but it wouldn't work unless that line of code was not commented out.

How long are the wires ? what kind of wires ? Putting SDA and SCL in a ribbon cable is very bad for the signals. The Adafruit multiplexer has 10k pullup resistors for the signals to the Arduino. That means it might work up to 50 cm. Try to add pullup resistors at the Arduino, perhaps 3k3 or 4k7. They will be parallel the 10k and parallel the internal 50k pullup resistors of the Arduino board. You might want to try Wire.setClock(50000L) to lower the I2C clock.

The bus capacity seems okay, as it handled 7 sensors when all on a breadboard. The wires are 4-pin ribbon cables, and length varies depending on the location. I'll edit my post once I get the measurements, but for the pullup resistors, would they be placed on the A4/A5 lines to +5V? I'm looking at the schematic (Uno Rev 3), but I don't see where the 50k/10k resistors are. The sensors and the multiplexer already have pull up resistors on them. Also, how would lowering the I2C clock help with tcaselect(0)? It doesn't explain how this line works with sensors on the breadboard but not with wires.

A flat ribbon cable with SDA and SCL next to each other is the worst possible wiring for a I2C bus. The SDA and SCL should have minimal capacitance to GND and VCC and they should not interfere with each other. If a pulse from SCL appears on SDA (or the other way around) that will make it impossible to make the I2C bus work. Capacitance to GND and VCC can be solved (for a part) by lowering the value of the pullup resistors and by lowering the I2C clock. But crosstalk between SDA and SCL can not be prevented that way. You have not told us yet how long the wires are.

I put down the distance from the center box to the farthest placed sensor, being around 1.45m, so that's approximately how long the wires are. The shortest distance is around 10 inches or so. I understand what you're saying about the I2C bus and the wire placements, but this is what I have to work with. I can add another resistor in parallel to reduce pull up value, Nevertheless, the strange issue still remains that with tcaselect(0) commented out in setup, all sensors were able to be read from. It's strange that this line of code is commented; kind of feels like it shouldn't be.

I'm sorry, but SDA and SCL next to each other in a flat ribbon cable is wrong, you should refuse to work with that. You can split the wires over the complete length of the ribbon cable, all of them. That will improve the signals. Did you forget the Wire.begin ? Perhaps some hardware needs time to power up. You could add a delay of 500ms before starting to use the I2C bus.

Jot, Thanks for your comment. I think that one of my issues is that I needed pull-up resistors. I used 10k resistors for the SDA/SCL lines on the sensors, so that worked with the cable. In regards to your comment on the cable, rather than having SDA and SCL next to each other, I moved the soldered wires around at the sensor so along the cable, SCL was on one side, SDA was on the other, with GND and VCC in between the two. That seems to work alongside the additional pull up resistors to get everything working, though I only tested it with two sensors.

I'm sure you have, but have you connected the grounds together?
Have you tried 1 sensor on SD/C0 and then moving it to SD/C1 it should stop working, so the fault has to be with SD/C0.
Looking at your code, is there a reason you haven't initialised sensor 0?
 /* Initialise Sensors 1-6 */

So it looks to me as the fault is caused by you not calling begin() on mag0

We connected the grounds together; they all lead to a node on the breadboard which feeds back to the Arduino. We tried your suggestion with SD/C0 and SD/C1, but the results were the same. I'll ask the team to try again since I can't exactly test it because I'm not on site with the device. The reason why we haven't initialized sensor 0 with tcaselect(0) was that it was causing our code to hang. Once we commented it out, the code continued, and we could read from all sensors. The guy in charge tested it, commented out stuff, and found that this was the issue, though we still don't know why.

Try bumping the empty to the last slot and changing your for loop to only iterate the first 7.
Serial prints along the way help debugging


text:
Connecting an Arduino Nano to a Raspberry Pi Zero
I'm working with an Arduino Nano Every, and I'm trying to connect it to the Raspberry Pi Zero for data collection from I2C sensors and writing/program code from the Pi to the Arduino. Typically, I would use a USB cable to connect from the Pi to the Arduino. However, this is going to be in an area where space is limited, so I'm looking for ways to connect the Arduino to the Pi that does not involve a USB cable. Are there other ways for the Pi and the Arduino to communicate the same way as if they were connected together via USB cable, perhaps through the Raspberry Pi's GPIO pins? What are some advantages/disadvantages of doing it in other ways?
EDIT: Something that also occurred to me: When connecting the Arduino to the Pi, to ensure that the Arduino has enough power, is there no choice but to use USB?

You can connect via:

UART
I2C
SPI

All are available on the Pi's GPIO header and on the Arduino. You will of course need logic level translation for a 5V Arduino.
Using UART is probably simplest for you since that is identical to using the USB - you just use /dev/ttyS0 (or /dev/ttyAMA0 on older Raspberries) instead of /dev/ttyUSB0 or /dev/ttyACM0.  Just connect the Pi TX to the Arduino RX, and the Arduino TX to the Pi RX through logic level translation (voltage divider is a possibility).

Thanks for your comment. There was one other concern that just came to me. Previously, when I connected my Pi to the Arduino Uno via USB (I used an Uno as a prototype before), it powered the Arduino through USB. If I were to use UART as you suggested, how can I power the Arduino? If I can power it through the GPIO pins, would that ensure that the Arduino+sensors have enough current, or would the best way to ensure adequate power is through USB?

Use the 5V pin of the Pi to power the Arduino through it's 5V pin.

Thanks again for your reply. If I use it with other devices, such as this Ethernet/USB Hub Hat, I just have to make sure that there's no contention with the UART pins in order for this to work? Are there any good tutorials that you can link to? https://www.amazon.com/Ethernet-USB-HUB-HAT-Compatible/dp/B07T16RSFM/ref=sr_1_4?keywords=raspberry+pi+zero+ethernet&qid=1578611146&sr=8-4

@user101402 It's unlikely you'd get contention with the UART. There's not many hats that would use it, instead using I2C and SPI for preference.

The pi zero w has micro usb and the arduino nano has mini usb.
Can we use mini-micro usb cable to connect them?

"I'm looking for ways to connect the Arduino to the Pi that does not involve a USB cable"


text:
How to keep a pin LOW for a small amount of time after pushing a button and while device is booting?
Context
I keep the board in deepsleep mode and want to wake it with different buttons. I need to know which button has been pushed on boot. The board is immediately put back in deepsleep mode afterward.
I've been able to reset the board and pull a pin LOW at the same time. (see circuit below). The reset pin is momentarily pulled low so it reset the board effectively.
I'm not an electronic engineer, just a hobbyist, so any other method to do something are always welcome.
Problem
With the actual code/circuit, I need to hold the button until the device boot up so it can detect button was pushed but I would like to be able to just push the button quickly instead of having to hold it.
Question
How to add some sort of delay that will "hold" the SW-D5 button until the board boot?
Or anything that keep my D5 pin LOW for a short amount of time after the button has been pushed?
I think something in the range of 500 to 1000 milliseconds would be enough.
My actual circuit

simulate this circuit – Schematic created using CircuitLab
My code
#include <Spi.h>
#include <Arduino.h>
#include <ESP8266WiFi.h>

int buttonPin = D5;

void setup() {
  // Read pin value as soon as possible after boot
  pinMode(buttonPin, INPUT_PULLUP);
  int buttonValueAtBoot = digitalRead(buttonPin);

  pinMode(BUILTIN_LED, OUTPUT);
  Serial.begin(115200);
  Serial.println();

  if (buttonValueAtBoot == LOW) {
    Serial.println("D5 was pressed");

    // Do something useful here like making an HTTP request.
    digitalWrite(BUILTIN_LED, LOW);
  }

  // Avoid problem when the button is being hold
  while (digitalRead(buttonPin) == LOW) {
    // wait before going to deepsleep
    // or the capacitor will be drained
    delay(1);
  }

  Serial.println("going to sleep");
  ESP.deepSleep(0);
}

void loop() {
}

write a pin to hold it down; pinMode() in setup() kicks in in about  200ms

@dandavis the problem is that the pin already changed its state back to normal once in setup().Push SW-D5 -> trigger reboot -> release SW-D5 -> few hundreds of milliseconds later -> setup()

A simple RC network should do the job.

simulate this circuit – Schematic created using CircuitLab
Ok. A quick explanation of what we have here.  C1 and R1 are the same as you have at the moment for your reset circuit. R1 is the existing pullup resistor in the Wemos. R3 recharges the C1 when the button is released. It's effectively the pullup for the button.
D2 is to separate the two parts of the circuit. It prevents R3 from charging the capacitor C2.
The magic happens with C2 and R2. Pressing SW1 discharges C2, and the GPIO goes low.  When you release SW1 C2 charges up again through R2.  When the voltage across C2 rises to the VIH of the GPIO the GPIO will go high.
D1 is to protect the GPIO from the negative pulse you can get from C2 as it discharges.
Here's a simulation. Top line is the GPIO, bottom is RESET.

VIH for the ESP8266 is 0.75VIO, so 75% of 3.3V, or 2.475V.
The charge time of the capacitor C2 is calculated as T=RC, where T is the time taken to charge up to 63% of the supply voltage (2.08V)
With the shown values the time taken to rise to 63% of 3.3V will be 10,000 x 0.0001 seconds, or 1 second.  So to get to 75% it will take a little longer than 1 second.  75% is about 1.4T, so if T is 1 as in the above equation then it will take 1.4 seconds (1 * 1.4) to rise enough for the GPIO to register as HIGH.
Note these times are all from the moment you release the button. Reset has already happened before that time.
Also the internal pullup of the GPIO should be disabled otherwise it will also charge the capacitor and the charge time will be reduced. Since you don't know that resistor value it then becomes impossible to calculate what the charge time will be. Simplest to just disable it and only use the external resistor R2.

If the button is pressed twice, C1 will still be charged after the first press. Reset does not work. When and how can C1 be discharged?

Good point. It wants a pullup - and maybe a diode to isolate the two signals. I'll tweak it.

@majenko thanks for the time you took for all those very appreciated explanations. Will it work if I use diode instead of Schottky diode? I will try your suggested circuit as soon as I receive bigger capacitor this week

Yes it should work with a silicon diode.

The use of a schottky for D2 is to keep the LOW voltage as low as possible. As long as it's below the VIL of the ESP8266 then it doesn't matter what the diode is. D1 is to try and match the ESD diode in the chip itself. If it's forward voltage is above the ESD diode's forward voltage the ESD diode will conduct instead of D1 - both making D1 pointless and possibly (though highly unlikely) endangering the ESD diode in the chip.

@Majenko I've disabled the pullup of the GPIO and everything start working as expected using the circuit you designed except that it reset as soon as I push the button, not when I release it. But it's not a big deal tho.. I've even been able to add a second button duplicating the circuit before D2 and adding diodes between the buttons and R3, C1 junction. Your help and explanations were really appreciated! Now I'll investigate to find why it's not working properly when battery powered. Thanks again

@Majenko how did you generate your simulation image?

@Remi Yes, reset as you press the button is normal. It's a low-going pulse. I use Falstad to do my simple simulations. http://www.falstad.com/circuit/

This is amazing. I've been trying to figure this out for a week, trying everything from latch to 555 timers to get this to work and you've done it with a simple capacitor. Thanks!!

@Majenko How would you modify this if you want multiple buttons to reset the same device but track them on different gpios?

You should be able to pretty much duplicate the entire circuit and connect multiple copies to the RESET pin.

You may want to separate the circuits out with a Wired AND connection (a diode for each circuit).


text:
WiFi problem on Mega + WiFi R3 ATmega2560 + ESP8266
I've got 2 "Mega + WiFi R3 ATmega2560 + ESP8266" (link) and both have same issue when trying to use the ESP chip.
Hope someone can point me toward something else to try in order to get them working properly.
Context
I'm able to flash the ESP chip using Arduino IDE or PlatformIO.
Dip switch need to be : 5, 6 and 7 ON to flash, and only 5 and 6 to debug through serial.
I've tried using different boards (Generic ESP8266 module, Wemos D1 R2 & mini, Node MCU) as well as different flash mode (DIO, QIO), crystal frequency (26 Mhz, 40 Mhz), CPU frequency (80 Mhz, 160 Mhz)
They all flash correctly without any error and I can get my serial output.
It's written ESP8266EX on the ESP chip. And I've tried with or without an antenna plugged on the board.
Problem
The problem I got on both of them is huge instability when using wifi. I cannot connect to them when they are in AP mode, they drop immediately.. And I cannot connect to or see my own wifi network from the Mega's ESP.
The same script and flashing config used on other ESPs devices work as expected (see [output other ESP board] below). I've tried on WeMos and NodeMCU devices.
But with the mega+wifi, it only see between 0 and 2 access point that are at a greater distance and weaker signal than my own wifi ([output mega+wifi] below).
Question
I don't have any clue on what can cause such a different result on device from same family (ESP/espressif). As if there was some sort of setting that need to be changed on those ESPs.
Any help or insight would be truly appreciated.
[code]
#include "ESP8266WiFi.h"

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

  // Set WiFi to station mode and disconnect from an AP if it was previously connected
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);

  Serial.println("Setup done");
}

void loop() {
  Serial.println("scan start");

  // WiFi.scanNetworks will return the number of networks found
  int n = WiFi.scanNetworks();
  Serial.println("scan done");
  if (n == 0)
    Serial.println("no networks found");
  else
  {
    Serial.print(n);
    Serial.println(" networks found");
    for (int i = 0; i < n; ++i)
    {
      // Print SSID and RSSI for each network found
      Serial.print(i + 1);
      Serial.print(": ");
      Serial.print(WiFi.SSID(i));
      Serial.print(" (");
      Serial.print(WiFi.RSSI(i));
      Serial.print(")");
      Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*");
      delay(10);
    }
  }
  Serial.println("");

  // Wait a bit before scanning again
  delay(5000);
}

[output other ESP board]
scandone
scan done
8 networks found
1: 412 Precondition Failed (-67)*
2: VIDEOTRON1547 (-90)*
3: BELL275 (-94)*
4: BELL558 (-72)*
5: C-PC_Network (-88)*
6: BELL387 (-90)*
7: EBOX-4229 (-94)*
8: VIDEOTRON6825 (-80)*

scan start
scandone
scan done
11 networks found
1: 412 Precondition Failed (-63)*
2: VIDEOTRON1547 (-88)*
3: BELL681 (-90)*
4: BELL275 (-90)*
5: VIDEOTRON0442 (-90)*
6: BELL558 (-71)*
7: BELL602 (-90)*
8: IKA COIFFURE (-90)*
9: C-PC_Network (-87)*
10: EBOX-4229 (-87)*
11: BELL387 (-90)*

scan start
scandone
scan done
7 networks found
1: 412 Precondition Failed (-65)*
2: BELL681 (-88)*
3: VIDEOTRON1547 (-88)*
4: EBOX-4229 (-88)*
5: BELL387 (-87)*
6: BELL558 (-71)*
7: dlink-Ares (-75)*

[output mega+wifi]
SDK:2.2.1(cfd48f3)/Core:2.4.1/lwIP:2.0.3(STABLE-2_0_3_RELEASE/glue:arduino-2.4.1)
bcn 0
del if1
usl
mode : sta(2c:3a:e8:26:36:13)
add if0
wifi evt: 8
Setup done
scan start
scandone
scan done
1 networks found
1: BELL558 (-69)*

scan start
scandone
scan done
1 networks found
1: BELL387 (-88)*

scan start
scandone
scan done
no networks found

scan start
scandone
scan done
1 networks found
1: BELL387 (-87)*

[erasing flash]
PS \tool-esptoolpy> python .\esptool.py -p COM10 erase_flash
esptool.py v2.3.1
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 14.2s
Hard resetting via RTS pin...

try to erase the flash of the esp8266 with esptool and then upload a sketch from IDE. choose Generic esp8266 as a board

I did it using python .\esptool.py -p COM10 erase_flash and that didn't changed anything. Output added to the question.

I had this problem. On Robotdyn D1 mini the esp8266 flash erase did help. On Robotdyn D1 R2 only the flashing of the AT firmware with Espressif Flash Download Tool restored the esp8266. After then the sketches from IDE had working WiFi.
There are some settings of the Espressif basic esp8266 libraries (SDK) saved on flash and there is some incompatibility between SDK versions. The Flash Download Tool creates right esp settings binary and flashes it to right address on flash.

ESP8266_AT_Bin_V1.6.2 ? and then at or at_sdio ? and how do I know the right addresses to use?

"at". addresses depend on the size of the flash and are listed in the readme file

Thanks. Just flashed it and even with direct AT command, on only sees very few wifi network
AT+CWMODE?
+CWMODE:2

OK
AT+CWMODE=3

OK
AT+CWMODE?
+CWMODE:3

OK
AT+CWLAP
+CWLAP:(2,"CHANTAL-PC-Network",-77,"00:26:5a:d1:c9:96",11,162,0,5,3,7,1)

AT+GMR
AT version:1.6.2.0(Apr 13 2018 11:10:59)
SDK version:2.2.1(6ab97e9)
compile time:Jun  7 2018 19:34:26
Bin version(Wroom 02):1.6.2

and can you connect to your network (CWJAP) ?

No..
AT+CWMODE=3
OK
AT+CWJAP_DEF="412 Precondition Failed","my pass"
+CWJAP:3
FAIL

and CWJAP:3 means "cannot find the target AP"

I also changed the country to US as it was to "CN" in case that could help but that changed nothing even after a reset

ideas: is the WiFi AP you try to connect 2,4 GHz? is it listed in scan? try to start AP with AT commands and connect to it.

Yes, it is 2,4 Ghz and no, it does not appear in scan on those devices. But it is visible (and connectable) from any other ESP board I have + computer + phone.

Let us continue this discussion in chat.

You state you "cannot connect to them when they are in AP mode" but I do not see AP configured in your code.
// ESP AP Server
// password can be blank
// must be min 8 chars or will not work
const char *APName = "MYESP8266";
const char *APPass = "MYPASS123";
// start the access point server
WiFi.softAP(APName, APPass);
// define web link functions
webServer.on("/", doRoot);
// start server
webServer.begin();

// In LOOP
// keep checking to see if someone connects to device
webServer.handleClient();

Regarding the mega-wifi-r3-atmega2560-esp8266
I am unsure how these work, is the code being flashed to the ESP chip or to the Arduino chip and ESP is in AT mode?

For the AP mode, I tried with the example provided here : http://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/soft-access-point-examples.html
I simply cannot connect to the AP (when I'm able to see it) even if I'm only 1 foot away from the board.

Do you get an error after typing in the password?

Try making the password all caps

No, from computer is says "can't connect to network" and from my phone the AP simply disappear. The same code work perfectly on other boards. Seems more like core firmware issue.

If it goes off then most likely the code is crashing and ESP rebooting

Strangely it's not.. nothing in the serial debug even if debug level include almost everything

If you've come upon this page because the ESP8266 on your (WeMos) Mega wifi won't connect to your router (etc), check the age/security of your router:
Wifi stopped connecting (Wemos D1 Mini)
This line of code that allowed connecting with my old router:
  WiFi.enableInsecureWEP();
which also highlights that I should upgrade it...


text:
How to reset an arduino while being able to know which button has been pressed?
Context
I keep the board in sleep mode and want to wake it with different buttons. I need to know which button has been pushed on boot.
In the following schematic, SW-R is actually used to reset the board.
If I hold SW-D5 or SW-D6 while pushing SW-R, the code can detect which button I pushed.
Problem
I don't want to have to push 2 buttons at the same time and, being new to electronic, I don't know how to wires things up so it reset and set a pin to HIGH simultaneously.
Question
How can I reset the board and trigger a HIGH on an IO corresponding to a button while it boot?
Considering the HIGH only need to be hold for less than a second, can it be simply achieved with capacitors and/or transistors? If so, how? Or any other suggestion?

simulate this circuit – Schematic created using CircuitLab
The actual code example only contain 1 button but I'll have many.
#include <Spi.h>
#include <Arduino.h>
#include <ESP8266WiFi.h>

int buttonPin = D5;

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(BUILTIN_LED, OUTPUT);

  int buttonValueAtBoot = digitalRead(buttonPin);
  Serial.begin(115200);
  Serial.println();

  if (buttonValueAtBoot == HIGH) {
    // I want to trigger this code pushing only 1 button
    // should also work with many buttons
    Serial.println("button was pressed");
  }

  digitalWrite(BUILTIN_LED, HIGH);
}

void loop() {
  delay(5000);
  ESP.deepSleep(0);
}

Things would be simpler if your used a "shallower" sleep mode permitting wake on a pin change interrupt.  If you want to actually reset the processor, you may need to find a way to activate the reset and the input pin from the same button, apparently in a way that supports multiple buttons, and perhaps also locks out generating additional resets once the chip is awake..

just use a pin that's high during reset, then you don't need to switch anything.

@dandavis can you please be more explicit? Use it in which way?

feed a pin that's high during reset (0,2,3,16) to the input that needs to be high during reset .

@dandavis oh got it! you suggest to use/route a pin that is HIGH at boot time as a source to my button pin. Seems like a good idea, but how to wire that up in a way that is temporary and that will be compatible with multiple buttons? Each button needs to trigger the reset and keep it's pin high at least for the boot delay.

Just found that I can change pins behavior. Inverting things a little bit, I can get my pins to work as LOW instead of as HIGH.
That way, I only need 1 button to trigger a reset and change pin status. Plus, grounding the reset is done temporarily because of the capacitor, which is what I need.
Here is the new schema

simulate this circuit – Schematic created using CircuitLab
New code
#include <Spi.h>
#include <Arduino.h>
#include <ESP8266WiFi.h>

int buttonPin = D5;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(BUILTIN_LED, OUTPUT);

  int buttonValueAtBoot = digitalRead(buttonPin);
  Serial.begin(115200);
  Serial.println();

  if (buttonValueAtBoot == LOW) {
    Serial.println("button was pressed");
    digitalWrite(BUILTIN_LED, HIGH);
  }

  // Avoid problem when the button is hold
  while (digitalRead(buttonPin) == LOW) {
    // wait before going to deepsleep
    // or the capacitor will be drained
    delay(1);
  }

  Serial.println("going to sleep");
  ESP.deepSleep(0);
}

void loop() {
}