text:
error: espcomm_upload_mem failed when uploading a sketch
I am new to the whole arduino scene. I have connected my wifi module (esp8266 v01) to my arduino Uno like this:
http://www.teomaragakis.com/hardware/electronics/how-to-connect-an-esp8266-to-an-arduino-uno/
And have downloaded the arduino ide framework so that I may be able to use the arduino IDE as opposed to sending AT commands through the serial monitor.
When trying to upload an example sketch that sends a http request that I found on github, I get the following error:
    Arduino: 1.8.4 (Windows 8.1), Board: "Generic ESP8266 Module, 80 MHz, 40MHz, DIO, 115200, 512K (64K SPIFFS), ck, Disabled, None"

Archiving built core (caching) in: C:\Users\Yasmeen\AppData\Local\Temp\arduino_cache_354217\core\core_esp8266_esp8266_generic_CpuFrequency_80,FlashFreq_40,FlashMode_dio,UploadSpeed_115200,FlashSize_512K64,ResetMethod_ck,Debug_Disabled,DebugLevel_None_____9d1d735445f8d7bf19746e2177d24e71.a
Sketch uses 285417 bytes (65%) of program storage space. Maximum is 434160 bytes.
Global variables use 38688 bytes (47%) of dynamic memory, leaving 43232 bytes for local variables. Maximum is 81920 bytes.
error: failed reading byte
warning: espcomm_send_command: cant receive slip payload data
error: failed reading byte
warning: espcomm_send_command: cant receive slip payload data
error: failed reading byte
warning: espcomm_send_command: cant receive slip payload data
error: failed reading byte
warning: espcomm_send_command: cant receive slip payload data
error: failed reading byte
warning: espcomm_send_command: cant receive slip payload data
error: failed reading byte
warning: espcomm_send_command: cant receive slip payload data
error: failed reading byte
warning: espcomm_send_command: cant receive slip payload data
error: failed reading byte
warning: espcomm_send_command: cant receive slip payload data
error: failed reading byte
warning: espcomm_send_command: cant receive slip payload data
warning: espcomm_sync failed
error: espcomm_open failed
error: espcomm_upload_mem failed
error: espcomm_upload_mem failed

After looking online and researching, I can see that it has something got to do with flashing the firmware or something. I came across this question:
ESP8266 error: espcomm_upload_mem failed while uploading sketch
and the answer did say that he bought a converter.. what does this mean? Does it mean buying this?:
https://www.amazon.co.uk/gp/product/B06Y3FNGJF/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1
I really need help, been stuck on this for the past few days now and seriously contemplating whether to get the arduino wifi shield since it comes prebuilt with wifi.. even though it costs quite a lot!

Did you take note of the paragraph in your first link that reads And since we talked about the CH_PD pin, remember that if you want to flash the ESP8266 you should connect the GPIO0 pin to GND (blue line), which puts the ESP into flash mode.

@Majenko I am able to send AT commands with the module so should I not be in flash mode when trying to send a http request? Also, does flashing mean upgrading the firmware in the esp2866?

To solve the issue,do this
short the pin GPIO 0(D3) to ground using a jumper wire.
press reset button
upload the sketch
remove the jumper wire . Done!!!! Thanks for this note that solved my problem

The ESP8266 has two "modes". "Run" mode and "Flash" mode.  In "Run" mode the firmware installed onto the ESP8266 executes. The default firmware is the AT firmware that allows you to control the device with AT commands through serial.
Note that the site you link to has erroneous information about CH_PD that should be talking about GPIO0.
In "Flash" mode you get to upload new firmware (AKA a "sketch") to make the device do something different.
The basic programming sequence is:

Switch the device to Flash mode (connect GPIO0 to GND)
Upload the sketch using the IDE
Switch the device to Run mode (connect GPIO0 to 3.3V).

Because of these extra steps many people choose to invest in a small USB interface board designed specifically for programming the ESP8266 to make their life easier. These generally have a switch on them to set whether GPIO0 is connected to GND or 3.3V.

Thank you for the clarification. Really helps. I have connected the CH_PD to GND, I try to run the sketch but still pretty much get the same error: warning: espcomm_sync failed error: espcomm_open failed error: espcomm_upload_mem failed error: espcomm_upload_mem failed Not sure whats going wrong

Get an adaptor. It makes everything so much simpler. They're dirt cheap on eBay.

Would this adapter work?: https://www.amazon.co.uk/gp/product/B06Y3FNGJF/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1

This is incorrect. CH_PD turns the chip on or off. I think you mean GPIO0

@tttapa I thought it was GPIO0 too, but the site linked to in the question says CH_PD.

@dfqupwndguerrillamailde Errr... no? That's not an ESP8266 USB adaptor. That's a logic level translator. What you are looking for has a USB plug on one end and a header for an ESP8266 on the other, with a switch in the middle.

@dfqupwndguerrillamailde It looks like the one in the picture in the answer you linked to.

@Majenko Am I right in thinking that the by switching the GPIO0 to GND and VCC is equivalent to getting that USB adapter? Also, I just changed the GPIO0 to GND, uploaded a blank sketch and it uploaded fine.. now I'm trying to upload the example code on github but now I'm getting the same error. I'll play around and try and upload it back

CHPD needs hard-wired to VCC, not ground. on ESP-01S modules, it's pre-wired for you.

By default, the ESP8266 runs the program in flash memory.
To upload new firmware over UART, you have to change the boot mode by connecting GPIO0 to ground during reset.
GPIO15 should be low and GPIO2 should be high during boot in both cases. GPIO needs an external pull-down resistor, the internal pull-up resistor for GPIO2 is enabled during boot, so you don't need to add an external one.
To prevent from shorting GPIO0 if it's used as an output in your sketch, it's recommended to add a series resistor to limit the current.

To upload a sketch:
1. press and hold the reset button
2. press and hold the program button
3. release the reset button, the ESP will boot in program mode
4. release the program button
5. upload the sketch
If your USB-to-Serial breaks out the RTS and/or DTR lines, you can automate the reset and programming mode procedures.

I had the same issue while uploading to the NodeMCU.
The issue was that the mode was not selected to program mode even after doing the below steps:

press and hold the reset button
press and hold the program button
release the reset button, the ESP will boot in program mode
release the program button
upload the sketch

To solve the issue, do this:

short the pin GPIO 0(D3) to ground using a jumper wire.
press reset button
upload the sketch
remove the jumper wire

Done!!!!

This is one of the simple solutions that worked for me:

Plug out the USB connection with the computer;
Hold the flash button on the nodemcu/esp8266;
Plug in the usb connection and quickly release the flash button;
Now try uploading the sketch.

Thank you.

depending on the USB speed cable that you are using, sometimes this problem often occurs if I use a cable that is not suitable. if your com setting is 9600 then you have to set up upload speed in the tools menu -> upload speed faster than 9600 ... for exp: 57600.
this is should be work!!

at 9600 baud the upload starts but fails in the middle because of problems with the esptool used in Arduino esp8266 package until version 2.4.1 . starting 2.5.0 esptool.py is used


text:
Attach Interrupt problem
I'm just learning how to use the Arduino Uno and I'm trying to control the speed of an AC fan. I made a sketch of this project on proteus but the triac seems not to be responding. I guess there's a problem with the attachInterrupt part of the code. Here's the code:
#define triacPulse 5
#define interruptPin 2

//button event
#define button1 6

void setup() {
  // put your setup code here, to run once:
  pinMode(button1, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(button1==HIGH){
    attachInterrupt(0, triacControl, FALLING);
  }
}

void triacControl()
{
  delay(5);   //delay for 5 milliseconds
  digitalWrite(triacPulse, HIGH);
  delay(5);

  digitalWrite(triacPulse, LOW);
}

Thanks for the answer in advance

Do not use delay() in an interrupt. Ever.

First of all, please use the code tag to put code here, otherwise it is not readable from the others. Then, as Majenko said, do not use delay() in an interrupt. Ever. And if you ever find an application where you should use delays in an interrupt, you are wrong and you should not use it. As for the program, what do you want to do? In any case the code you wrote is not correct, since it is not the correct way to think interrupts. And finally, what do you expect by turning off and on a triac for 5ms? Usually you turn it on or off for a whole semi-period (but it should be synchronized)

I don't think you should be putting attachInterupt in your loop.  You button may be bouncing so you could be attaching it many times each press.
-- OH BTW Don't take any of these comments as criticism, don't get put off --

First of all your if statement will always be false. You ask if 6 equals 1 (from arduino.h).
It schould be digitalRead(button1) == HIGH. Also it looks like your button should start an impulse of 5ms. Am I right?
In this case you will attach the Interrupt to the Button. Also don't put delays in the Interrupt function. Another thing, that isn't important in small Projects only for you, is to increase the readability by typing "define constants" uppercase, so you know where to find them and that they aren't changeable variables (For this reason HIGH, LOW, INPUT, RISING, ... are all uppercase).
All in all the code should be look like this:
#define BUTTON1PIN          6
#define TRIACPIN            5
#define TRIACPULSE          5                       // [ms]

bool doPulse = false;
long triacStartTime = 0;

void setup(){
  pinMode(BUTTON1PIN, INPUT);
  pinMode(TRIACPIN, OUTPUT);
  attachInterrupt(BUTTON1PIN, pulseISR, RISING);    // attach a Interrupt once!
                                                    // pulseISR is called everytime the button is pressed
                                                    // ISR: Interrupt service Routine (only for Readability)
}

void loop(){
  if(doPulse){
    digitalWrite(TRIACPIN, HIGH);
    triacStartTime = millis();
    doPulse = false;
  }
  if(millis() > triacStartTime + TRIACPULSE){        // Shut down after 5 ms
    digitalWrite(TRIACPIN, LOW);
  }
}

void pulseISR(){
  doPulse = true;                                    // NO delays in ISR! And as short as possible
}

Personally I find it a bit overkill to use an ISR to detect a button. Also, without any debouncing, it will give a lot of troubles. Finally, if he is using a zero-crossing optocoupler (or a solid state relay with a zero crossing optocoupler) he will have problems with 5ms times (remember that a 50Hz wave crosses the zero once per 10ms, while a 60Hz one every 8.3ms). In my opinion, the OP has not clear what he needs to do yet, so better have him figure out what to do rather than providing him solutions that will make things more complicated..

@frarugi87 Of course it is an overkill. But he ask for a solution for his interrupt problem and after seeing his approach i had to show the correct way of using an interrupt. I still think he might want to use some kind of PWM for his speed control, but as you stated, the timing is kind of strange for this purpose.

I'm actually doing a college project on controlling the speed of an AC fan, so the code I uploaded is a form of sketch I wrote to see a prototype simulation on PROTEUS before implementing it. I not going to use a button, but rather a temperature sensor. The button I used is just to force an event. I'm considering a frquency of 50Hz. And of course, the wave crosses the zero once every 10ms. so, I'm tring to achieve a 5ms delay after the crossing to obtain a reduced average power in the end.

source: Stack Exchange

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

sort: votes


text:
Operating system on Atmel 328 Arduino?
Is it possible to use some sort of multitasking OS like ScmRTOS on Arduino based on Atmel 328 chip?

You can use FreeRTOS on the AVR family:

http://www.freertos.org/a00098.html

I tried it and it works. However, it turned out to be not very useful in the end. The Arduino Due or Arduino Zero with the schedular is a lot more fun.

Here is a portable implementation of the Scheduler https://github.com/mikaelpatel/Arduino-Scheduler.

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


text:
Will I be able send a HTTP request using the Arduino Yún?
After spending countless hours trying to get my wifi module to work only to fail, I've decided I might as well get an Arduino with built-in wifi.
Would I be able to send HTTP requests (GET, POST etc) straight out of the box or would I have to configure and connect some additional components/modules to the board?
Also, I plan on connecting a thermistor and a GPS module to the Arduino. When the thermistor reaches a certain level, it sends the GPS coordinates of my server. Is this possible in terms of practicality and voltage? And would I be able to write a sketch using the Arduino board or would I have to switch the board to something like 'Generic ESP8266 Module' (something we have to do if we want to program the ESP8266 using the Arduino IDE).

Never buy the Arduino Yun. The wifi/linux part runs OpenWRT, and you can do a lot with that. OpenWRT is awesome. If you are familiar with linux, then OpenWRT is no problem for you. The Arduino part is just like an Arduino Leonardo. The problem is the serial communication between those two via the 'Bridge'. It causes a lot of troubles. Therefor my advice is to never buy an Arduino Yun. Don't buy it. Just don't. You can stay Arduino compatible with a nodemcu or go for linux with the Raspberry Pi.

just use a dirt-cheap ESP8266/32 devboard instead of forking over a fortune for an undesirable MCU. you need to choose your board type in the IDE no matter what. if you started with a non-devboard, like an 01, you messed up, but don't allow that to poison the well. try a relatively fool-proof nodeMCU before going down the esoteric route...

Looking at your other two questions as well I see you have had limited success with a ESP8266.  I have never used a Yun, but I haven't seen much good stuff about them on here.  If you want a Linux based none real time system then you may as well get a PI.
Most people seem to think the way to use an ESP8266 is to hook it up to an Arduino and use it as a 'serial over wifi' link.  You can do that, but its like owning a Porsche and Kia and always using the Kia on Motorway journeys.  The ESP8266 is an 80MHz chip with 0.5 MByte of RAM, and you could program it in just the same way as an Arduino if you download the board support package.  It does have only 10 Digital pins and 1 Analog (which I think has lower resolution that the Arduino), but that's where the Arduino comes in.  If you need to hook up lots of pins, then stick the Arduino on the I2C bus as a slave to the ESP.
Now I suspect you have an ESP-01 board and are wondering what the [heck] I am talking about, 10 pins.  The number '01' is the number of GPIO pins that are taken to the edge of the board, so really you want to look at ESP-12E or ESP-13E boards (they still cost about the same $1).  You might want to look at a Wemos D1 or a Node MCU.  Both are fully fledge dev boards, jus plug in the USB and away you go.
So to answer your question:
Get a Wemos D1, hook the hardware up like you wood the Arduino (thermistor and GPS - via SoftwareSerial) and then either code a web server to run on the Wemos or Get it to Post message to you favourite server (see examples for details of either approach)

This is exactly what I want. I guess the way I thought the interaction works between the esp8266 and arduino was wrong. Thanks for clearing the space. I'll order a nodemcu and hopefully it'll end all my trouble! I've got this GPS receiver: https://www.amazon.co.uk/gp/aw/d/B015R62YHI/ref=ya_aw_od_pi?ie=UTF8&psc=1, would this be compatible with the nodemcu?

If you thought it was going to be compatible with an Arduino then yes it should be.  You need to remember that the ESPs are 3.3v chips.  In theory they should accept up to 6V on their digital pins before smoking, but they still only put out 3.3v which might not be enough for you GPS.  So you might want to spend an extra $0.1 on a level convertor.


text:
What sensor is used to judge transparency?
I want to create a system to separate between an aluminum can and a plastic bottle.
Both are lightweight, so I'm thinking of using the transparency property, meaning that the can is not transparent, but the plastic bottle is.
Will the light sensor work out?
Or would you suggest me another type of sensor I should use?

A light sensor should work. Another option would be an inductive Sensor to detect the Aluminium Can. And if you need to know if there is a Can in your sensor area you can combine it with an IR (or capacitive) Sensor, which should detect both Can types.
So it would be something like this:
if(IRdetect == true){
  if(inductive == true){
    type = alu;
  }else{
    type = plastic;
  }
}else{
  // no Can
}

Some cheap sensors as Example:

Inductive: Banggood
Infrared: Banggood

It's better never to use == true or == false, omit the true or use !.
This code can be replaced by     type = IRdetect && inductive;

A light sensor should work. If the aluminium can reflect much light, you can consider putting the light and light sensor on the same side, close together.
If not, put the light and light sensor of opposite sides so the light beam goes through the bottle.


text:
Power source for arduino project
The project is to make a 4WD car using arduino uno(clone) and four toy dc motors. I am using a adafruit motor shield v1.2(clone). The car is required to run autonomously, please suggest batteries for the arduino and the shield.
Also when I am using external power connector for arduino, all the motors start at different timing.

You can use anything from a 3V coin cell to a 24V truck battery... And if you want, even generators are fine, even if I'd personally avoid nuclear generators, but that's only because fuel is a bit hard to get (see Doc in Back to the future I). If you want a more precise answer, give more details, such as the power needed, the duration you expect, if you want a "ready to plug" battery or you can add circuitry, what is your experience and so on

5 minutes is the required duration and the motors are 4v each. Ready to plug battrey is required.

4V and.... estimated current consumption?

Sorry I have no idea.

Then, IMHO, it is better if you start thinking at this... Otherwise you'll end up with a heavy oversized battery or a too small battery. In any case, if your motors are pretty small go on with Mikael's solution. If you want a better but harder solution, maybe 2S LiPo batteries are ok for this; just buy a balanced charger for 2S batteries, a LiPo battery big enough to give you enough power (for instance, if your motors draw 1A each and you have two you can get small 1Ah 2S batteries for around 5$ and go for half an hour), then just use a DC/DC circuit to lower the voltage to 5V

Or you can use a 1S cell and a boost DC DC circuit to raise the 3.6V to 5, if you prefer... Cheaper charger, maybe, but some higher currents to deal with

I've been using usb power packs.

Easy to source (can be found in all electronics stores and many general stores).
Come in many sizes (500mAh to 20,000 mAh are common).
Rechargable, usually by using a generic phone changer with a usb micro connector.
Not costly.
Quite roubust.
Most Arduino boards and many motor driver boards are designed to be powered from usb.

Make sure you get one that is rated for enough current for your project.

I usually think about LiPo batteries but I have to admit that USB power packs are usually cheaper and easier to use.. +1

power delivery of the power pack tends to be around 1A or 5W max per pack though (if you are lucky).

It is wonderful to bypass the auto-off circuitry of USB powerbanks.

Car batteries are wonderful, and almost never explode. A badly mistreated Li-{Fe,Po,Ion}, however... ouch. Otherwise use banks of NiMh/NiCd.
If you don’t fear death, use Li-Ion batteries with a TP4056 + DW01A IC, it can handle charging from USB, and provides over-discharge protection, so your batteries don’t die.
https://www.addicore.com/TP4056-Charger-and-Protection-Module-p/ad310.htm
It also has current limiting built-in.


text:
i2c wire length
I have some problems with i2c. I can not use long wires on SDA and SCK bus.
This seems to be the consequence of the capacity between the SDA and SCK wires and not between SDA/SCK and GND.
I figured this out by placing capacitors in a breadboard with a Arduino UNO and some MCP23017's (with 2k2 pull-up resistors).
100pF capacitor between SDA and SCK: No problem.
150pF: The communication stops.
1nF from SDA to GND and/or 1nF from SCK to GND: No problem.
A two wire cable is approx 50pF per meter, so 2 meters seems the limit.
With an ATtiny85 (8MHz clock, 100k i2c speed) as master it is even worse:
With 2k2 pull-up a capacity of 68pF is killing.
By reducing the pull-up resisters to 470E I was able to go up to 200pF  (hurray: 4 meters of wire).
Someone any idea how to increase the distance by tuning the SDA/SCK timing?

I2C is not designed to be used over long wires. What makes you think you can?

A P82B96 Dual bidirectional bus buffer can help you "go the extra mile". See table on page 14, https://www.nxp.com/docs/en/data-sheet/P82B96.pdf

@MikaelPatel add your comment as a answer.

As @majenko wrote, the I2C bus was not designed to go over wires or into a cable. It is ment for components on the same pcb board.
As @mikaelpatel wrote there are bus drives which convert the I2C signal into some kind of RS-485 signal for twisted pair cables.
The crosstalk between SDA and SCL should be avoided at all times. Don't put SDA and SCL into wires that are next to each other. When using twisted pair cable (for example Cat5), then use SDA in a different pair than SCL.
The worst situation is when SDA and SCL are next to each other in a flat ribbon cable.
The capacitance caused by the cable from SDA to GND and from SCL to GND can be compensated some by a lower value of the pullup resistors and by lowering the clock speed.
The maximum current is specified as 3 mA. That means with 5V, the lowest value for the pullup resistor is 1k6.
A little more can be achieved with a current driver of 3 mA instead of the pullup resistors. This is not often done, but it creates a better signal.
The Arduino Wire library for the Arduino Uno can be set to 50 kHz with Wire.setClock. I don't know the lowest value, but there is a limit without warning. I don't know the lowest clock speed for an Attiny microcontroller. A software I2C bus implementation can often go much lower.
Note that some sensors have a minimum clock speed.
The rule of thumb is that 50 cm is the maximum for the I2C wires. However, some say that they are able to use the normal I2C bus over 6 meters cable. My opinion is that the I2C should always work, since it is not very fault tolerant, and the Arduino Wire library for the Arduino Uno is not fault tolerant at all. Therefor, don't go near the limits.
The MultiSpeedI2CScanner (probably only working for Atmega chips) helped me a lot to learn about the I2C limits in different situations.

With 2 shielded cables, separate for SDA, SCL no problem to go several meters.
I just connected 2 I2C devices on common shielded cables 6m long SDA, SCL
3.3V and GND on non-shielded cables
Successfully tried also computer mice shielded cables, it's about 1.5m working no problem
Pull up resistors approx. 4k7

Can you tell us what kind of shielded cable you used?

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


text:
How To Communicate Three NodeMcu In Access Point Mode
I'm working on project which for example 3 nodemcu connected with eachother in a line(1 connected to 2 and 2 connected to 3) and they are all in access-point mode (they are all server) and now my problem is how to communicate between 1 to 2 and 2 to 3 i have tried tcp but its for server-client
any help would be appreciated

Look at the WiFi library. The function WiFi.mode() can set your NodeMCU as access point, station or both access point and station (WIFI_AP, WIFI_STA, WIFI_AP_STA or WIFI_OFF).
In the mode WIFI_AP_STA, your NodeMCU works both as access point and as a station independently; no need for special considerations.
You still need to know the IP address of each NodeMCU to make them to talk to each other. You can configure things to get fixed IP for each NodeMCU as a station.


text:
HC-SR04 calibration conditions
As is known, the speed of sound depends of temperature and Relative Humidity. I'm trying to calibrate HC-SR04 sensor taking account these factors.
In SparkFun page there is no mention about environmental conditions in calibration (only is informed that speed of sound is 340 m/s). I found a paper with some calibration, but again it is no mention of original conditions.
I'm using the time elapsed per response to calculate distance in Arduino with access to a temperature & humidity chamber, so I want to recreate the calibration conditions to probe if the sensor is accurate.
Anyone know the environmental conditions of HC-SR04 calibration?

You are over thinking things. The difference is so small, and the accuracy of the HC-SR04 (especially when coupled with the Arduino) so poor that any "calibration" would be meaningless.

@Majenko Based in this research, difference between raw / temperature calibrated data is significant. My aim is to use it measuring water level in small reservoirs and pan evaporation for agriculture, so outdoor condition can affect significantly the output data and, consequently, farmer decision

How small? You are aware of the range limitation of those units?

@Majenko I'm thinking in a measuring range from 0.05-2.50 meters in a site from 0-35ºC (or even more) and 20-100% HR

The humidity might make like a 0.5% difference in the measurement.  At the range you're talking about I have my doubts that the Arduino would even be able to measure the difference in time.  Even if it could, you're talking about a difference of sub-millimeter proportions.  How accurate does the measurement really need to be?  I don't think the unit itself is that accurate on the timing to begin with.

@Delta_G could be. I will make different tests prior to check the effect of HR. But temperature has a measurable effect tested in fixed distance. At the moment, corrected data has a lower standard deviation

The HC-SR04 is not calibrated, nor does it take any measurements.
All it does is allow software on a connected microcontroller or system like an Arduino to measure the sum of the round trip time delay and some small internal offset delay, and from this calculate distance.
As the timing and calculation are entirely in your program, calibration is entirely up to you.
Under known conditions you could measure both a short and a long distance.  This would give you a slope and intercept - the slope from the speed of sound (which should not depend on the device at all, only on the conditions and your timing reference), and the intercept or offset, having to do with latencies in the system.
You could then cross-check at other distances, but under fixed conditions behavior should be linear.
As there is some initial ringing of the sender which can couple to the receiver and be mistaken for an echo, there will be a minimum distance below which you cannot reliably take a reading - as a guess, this is more than 5 cm, but you'll have to see, and it may even vary a little from unit to unit.
To a degree, it's a little bit amazing that these even work.  They use an RS232 level shifter to generate transmit pulses, and it's been alleged that the receive circuit is horribly mistuned, not really matching the emitted frequency at all... but despite that they do seem to work fairly well.


text:
Arduino with ATmega32U4 low power but keep Serial1 working
I am looking for a low power solution for my ATmega32U4. It uses Serial1 to communicate with Bluetooth, so I need to have it active. When I receive data from Serial1, I want to power up the Arduino, do some magic, and then power it off...

Have you had a chance to look at the ATmega32U4 datasheet yet?

Yes a little bit, I hope You will have more xp and can recommend me some.

Use the UART interrupt to wake the MCU....?

For Power Down/Standby Mode you would have to use an Interrupt Pin to reactive the MCU. If you do not mind possible loss of the first character you could connect an Interrupt Pin to Serial1 RX and wake up on the first start bit.
The startup delay (i.e. time until UART is up and working) may impact the first character received. You could always start off by sending a number of null character as a "wake up call"; classical break sequence.
Cheers!
Ref. ATmega16/32U4, Chap. 7. Power Management and Sleep Modes.


text:
Problem with Dual Safety Switches Initiating Timed Relay
I have been working on an Arduino project that has me kind of stumped. What it needs to achieve is that two momentary safety switches need to be pushed and held within a specified time frame as defined by "PushTimeWindow" then continue to be held as a relay is engaged for the period of time as defined by "RelayOnTime" and at any point if either or both of the momentary switches are released the relay needs to turn off immediately. The number of successful pressed is then displayed on an LCD screen. I have most of that portion of the code working OK so far. It seems to do what I want it to do even if the code could be much more efficient.
I need to figure out a way to ensure the buttons are released first before another successful two hand press can be registered and another cycle initiated and they can't simply be held as the cycles continue. I have been trying to figure out how to place "state change" logic into the code but can't figure out where or how to include it properly. I created a variable called "LastButtonSafeChecked" and one called "ButtonSafeChecked" to act as a comparison but I can't get it to work properly. Where can I include that logic and is a state change the correct way to go about it in this case?
Any suggestions on improving the code and implementing the missing logic are greatly appreciated as I think it is outside the scope of my coding knowledge. I included a lot of serial print lines in order to try and debug what events were happening. Here is the code:
/*
Designed to detect two button presses within specific time gap
Then turn on a relay for a specified time
Then turn it off and look for another press
  */
// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

// this constant won't change:
 const int  ButtonPin1 = 2;   // the pin that pushbutton 1 is attached to
 const int  ButtonPin2 = 3;   // the pin that pushbutton 2 is attached to
 const int  RelayPin = 5;     // the pin that the Relay is attached to

// Variables will change:
int ButtonPushCounter = 0;    // counter for the number of button presses
int ButtonState1 = 0;         // current state of the button1
int ButtonState2 = 0;         // current state of button2
int LastRelayState = 0;     // previous state of relay
int ButtonSafeOn1 = 0;        // button1 time check passed
int ButtonSafeOn2 = 0;        // button2 time check passed
int ButtonSafeChecked = 0;     // Button Check passed flag
int LastButtonSafeChecked = 0;  // Last State of button check
int RelayOn = 0;            // toggles relay on off state
unsigned long RelayMillis = 0;  //on time check for relay
unsigned long Button1Millis = 0;  //on time check for Button1
unsigned long Button2Millis = 0;  //on time check for Button2
const long RelayOnTime = 1000; //Length of time for relay
const long PushTimeWindow = 1000; //Length of time to allow two pushes

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Press Count");
   // initialize the button pins as a inputs:
   pinMode(ButtonPin1, INPUT);
   pinMode(ButtonPin2, INPUT);
   // initialize the Relay Pin as an output:
   pinMode(RelayPin, OUTPUT);
   // initialize serial communication:
   digitalWrite(RelayPin, LOW);
   Serial.begin(9600);
}

void loop() {
unsigned long currentMillis = millis();
   // read the pushbutton input pins:
   ButtonState1 = digitalRead(ButtonPin1);
   ButtonState2 = digitalRead(ButtonPin2);
//check if Button1 is HIGH
    if (ButtonState1 == HIGH) {
        Button1Millis = currentMillis;
        Serial.println("Button1");
     }
//check if Button2 is HIGH
    if (ButtonState2 == HIGH) {
        Button2Millis = currentMillis;
        Serial.println("Button2");
      }
//let program know Button1 is within window
   if (ButtonState1 == HIGH) {
      if (currentMillis - Button1Millis < PushTimeWindow){
        ButtonSafeOn1 = 1;
    } else {
        ButtonSafeOn1 = 0;
    }
   }
//let program know Button2 is within window
   if (ButtonState2 == HIGH) {
      if (currentMillis - Button2Millis < PushTimeWindow){
        ButtonSafeOn2 = 1;
    } else {
        ButtonSafeOn1 = 0;
    }
   }
//Double Check both buttons are still pushed
   if (ButtonState1 == HIGH && ButtonState2 == HIGH) {
//Check to see if both button safetys add up and Change RelayOn to 1
    if (ButtonSafeOn1 + ButtonSafeOn2 == 2){
      ButtonSafeChecked = 1;
      RelayOn = 1;
      Serial.println("Relay On");
      } else {RelayOn = 0;
      ButtonSafeChecked = 0;
     }
    }
//Turn off relay if too much time elapsed
    if (currentMillis - RelayMillis < RelayOnTime) {
      RelayOn = 0;
      ButtonSafeChecked = 0;
    }
//Turn on relay pin if RelayOn is 1
  if (RelayOn == 1) {
       digitalWrite(RelayPin, HIGH);
       Serial.println("Relay Pin should go High");
    } else {digitalWrite(RelayPin, LOW);
    }
//update the RelayMillis if it is still on
  if (RelayOn == 1){
      RelayMillis = currentMillis;
    }
//increment counter to diplay press count
    if (LastRelayState != RelayOn){
      ButtonPushCounter++;
      Serial.println("State of Relay");
      Serial.print(RelayOn);
      Serial.println("  ");
      Serial.println("State of Last Relay State");
      Serial.print(LastRelayState);
    }
     // Delay a little bit to avoid bouncing
     delay(75);
     // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print((ButtonPushCounter/2));
  //Save Current Relay State for Next Loop
   LastRelayState = RelayOn;
  //Save Current Button Safety check for comparison for state change
   LastButtonSafeChecked =  ButtonSafeChecked;
}

update 10/13/17
Here is the current code that includes the Bounce2 library as suggested by user Jot as well as the state machine he created to handle the task. Could I have implemented Bounce2 better?
// A state machine is used, only to make it more clear what is going on.
//
// When a button is pressed, the input turns HIGH.
//
// Normally only one 'enum' is used for the state, that controls the code.
// This sketch has also a 'enum' for the buttons, which is called the input state.

// define the different states for this sketch.
// An 'enum' is like a number of #define with increasing numbers.
// include the library code:
#include <Bounce2.h>
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

enum
{
  WAIT_FOR_BOTH_OFF,
  WAIT_FOR_BOTH_ON,
  SAFETY_WINDOW,
  RELAY_ON,
} state;       // an 'enum' is automatically an integer.

// define the different input states.
enum
{
  BOTH_OFF,        // no buttons are pressed.
  BOTH_ON,         // both buttons are pressed.
  SOMETHING_ELSE,  // probably one of the buttons is pressed.
};

const int ButtonPin1 = 2;
const int ButtonPin2 = 3;
const int RelayPin = 5;

// The previousMillis is used twice for two different things.
// That is okay in this state machine.
unsigned long previousMillis;

const unsigned long RelayOnTime = 1750;    // Length of time for relay
const unsigned long PushTimeWindow = 300; // Length of time to allow two pushes

// Counters for the number of failed relay triggers and successful cycles.
// They can probably be normal integers as well.
unsigned long failed = 0;
unsigned long success = 0;

Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();

void setup()
{
  lcd.begin(16, 2);
  lcd.print("Press Count");
  Serial.begin(9600);
  Serial.println("Unit Online");

// Set up first button
  pinMode(ButtonPin1, INPUT);
  debouncer1.attach(ButtonPin1);
  debouncer1.interval(5); //Debounce time

// Set up second button
  pinMode(ButtonPin2, INPUT);
  debouncer2.attach(ButtonPin2);
  debouncer2.interval(5); //Debounce time

  pinMode(RelayPin, OUTPUT);  // OUTPUT to Relay

  Serial.println("Going to WAIT_FOR_BOTH_OFF state");
  state = WAIT_FOR_BOTH_OFF;
}

void loop()
{

  unsigned long currentMillis = millis();

// Update the bounce instances
  debouncer1.update();
  debouncer2.update();

  int inputState = getInputState();

  // Process the data in a state machine.
  // The output part is also in the state machine.
  switch(state)
  {
    case WAIT_FOR_BOTH_OFF:
      // Both buttons must be released to be able to continue.
      if(inputState == BOTH_OFF)
      {
        // Prepare to go to the next state.
        Serial.println("Going to WAIT_FOR_BOTH_ON state");
        state = WAIT_FOR_BOTH_ON;
      }
      break;
    case WAIT_FOR_BOTH_ON:
      // This is the state when everything is idle and no buttons are pressed.
      // Normally both buttons are released,
      // but when both are pressed, then go to the next state.
      if(inputState == BOTH_ON)
      {
        // Prepare to go to the next state.
        Serial.println("Going to SAFETY_WINDOW state");
        previousMillis = currentMillis;
        state = SAFETY_WINDOW;
      }
      break;
    case SAFETY_WINDOW:
      if(inputState != BOTH_ON)
      {
        // During the safety time window, a button was released.
        // Return to idle.
        Serial.println("Going to WAIT_FOR_BOTH_OFF state");
        state = WAIT_FOR_BOTH_OFF;
      }
      else if(currentMillis - previousMillis <= PushTimeWindow)
      {
        // The buttons are still pressed.
        // The time window has reached the end.
        // Prepare to go to the next state.
        Serial.println("Going to RELAY_ON state");
        previousMillis = currentMillis;
        digitalWrite(RelayPin, HIGH);  // Turn ON RelayPin
        state = RELAY_ON;
      }
      break;
    case RELAY_ON:
      if(inputState != BOTH_ON)
      {
        // One of the buttons was released.
        // Stop the relay and return to idle.
        // Although the relay was triggered, it was not succesful.
        failed++;
        Serial.print("Failed=");
        Serial.println(failed);
        Serial.println("Going to WAIT_FOR_BOTH_OFF state");
        digitalWrite( RelayPin, LOW);  // Turn Off RelayPin
        state = WAIT_FOR_BOTH_OFF;
      }
      else if(currentMillis - previousMillis >= RelayOnTime)
      {
        // Everyting was okay.
        // The buttons are still pressed.
        // It was complete and succesful.
        // It is time to turn off the relay and return to idle.
        success++;
        Serial.print("Success=");
        Serial.println(success);
        Serial.println("Going to WAIT_FOR_BOTH_OFF state");
        lcd.setCursor(0,1);
        lcd.print(success);
        digitalWrite(RelayPin, LOW);  // Turn Off RelayPin
        state = WAIT_FOR_BOTH_OFF;
      }
      break;
    default:
      Serial.println("Error, unknown state");
      break;
  }
}

// This function returns the input state.
// There is no StateChangeDetection, because a state machine is used.
int getInputState()
{
  int returnInputState;

  // Read the debounce state and create a input state according to the 'enum' values.
  int value1 = debouncer1.read();
  int value2 = debouncer2.read();

  if(value1 == LOW && value2 == LOW)
  {
    returnInputState = BOTH_OFF;
  }
  else if(value1 == HIGH && value2 == HIGH)
  {
    returnInputState = BOTH_ON;
  }
  else
  {
    // Not both on, not both off, so it must be something else.
    returnInputState = SOMETHING_ELSE;
  }

  return(returnInputState);

}

Sorry about the formatting, I went back to edit it but it was already changed to the correct formatting. Thanks.,

Another issue the code has upon further testing is that an operator could hold one button down and then hit the other and it allows the relay to turn on. That behavior won't work either as the device is to increase the effectiveness of a safety system on some equipment and it is supposed to prevent any operator from being able to "trick" a safety system into letting it allow a user to use only one hand or to be able to force the system to cycle without hands. Thanks again for looking.

Are both buttons equally important ? And you only have to know if both are pressed or both are released or something in between ? Then there is no need for two variables to store the millis value. For the state, either use a single variable that can be multiple states or two variables. Have you programmed a state machine before ? A state machine with StateChangeDetection for the buttons would make the sketch a lot larger but also easier to read and easier to add things to it and to change things. Without the state machine, I would create a single StateChangeDetection for both buttons together.

Hello Jot, I have used a state change in a previous device but I can't figure out how to add it in. Both buttons are equally important as they are safety switches designed to keep both of an operators hands occupied and out of the way as the relay is on. Whenever one or both switches is released the relay needs to turn off as quick as possible. The air solenoid attached to the relay automatically switches in reverse and initiates a brake system to stop the device.

A state change does seem Ideal as the whole system needs to wait after a relay cycle is complete until both buttons are released and then depressed again in order to start a  new relay cycle.

A good way to make a sketch easier is to split it into three parts. The input part, the processing part and the output part. What about making an input function that returns a value from a enum { BOTH_OFF, BOTH_ON, SOMETHING_ELSE }. Then you can isolate the input from the rest. The processing part can be a state machine. The more I think about it, the more I think in the direction of a state machine.

Hello, I haven't used an enum before I will look up the function now and see how to use it. I think you are right about splitting up the sketch, I have been trying to lay it out in a "Bubble Diagram" to get my head around it. I am thinking that a state machine need to wrap around the outside of the whole sketch and the inputs and running of the relay needs to reside within that state machine. Thanks for the guidance, it's appreciated!

The Arduino has a loop function, that runs over and over again.
The Arduino has a millis function for the time.
Those two combine beautifully with a state machine.
Once I made a function that returns the input value as BOTH_OFF, BOTH_ON, or SOMETHINE_ELSE, then the state machine automatically unfolds itself.
I hope you see how clean the code is. Every state has its own code. You don't have to think for hours how to make a spaghetti of if-statements. Although the sketch is now larger, there is no unnecessary code.
If you want to change something, you only have to find the state that you want to change. Adding a new state is also easy.
I have added some explanation in the sketch.
// A state machine is used, only to make it more clear what is going on.
//
// When a button is pressed, the input turns HIGH.
// Are there an external pulldown resistors ?
//
// Normally only one 'enum' is used for the state, that controls the code.
// This sketch has also a 'enum' for the buttons, which is called the input state.

// define the different states for this sketch.
// An 'enum' is like a number of #define with increasing numbers.
enum
{
  WAIT_FOR_BOTH_OFF,
  WAIT_FOR_BOTH_ON,
  SAFETY_WINDOW,
  RELAY_ON,
} state;       // an 'enum' is automatically an integer <- it is not an integer

// define the different input states.
enum
{
  BOTH_OFF,        // no buttons are pressed.
  BOTH_ON,         // both buttons are pressed.
  SOMETHING_ELSE,  // probably one of the buttons is pressed.
};

const int ButtonPin1 = 2;
const int ButtonPin2 = 3;

// The previousMillis is used twice for two different things.
// That is okay in this state machine.
unsigned long previousMillis;

const unsigned long RelayOnTime = 1000;    // Length of time for relay
const unsigned long PushTimeWindow = 1000; // Length of time to allow two pushes

// Counters for the number of failed relay triggers and successful cycles.
// They can probably be normal integers as well.
unsigned long failed = 0;
unsigned long success = 0;

void setup()
{
  Serial.begin(9600);
  Serial.println("Hello");

  pinMode(ButtonPin1, INPUT);
  pinMode(ButtonPin2, INPUT);

  pinMode(LED_BUILTIN, OUTPUT);  // LED_BUILTIN for testing

  Serial.println("Going to WAIT_FOR_BOTH_OFF state");
  state = WAIT_FOR_BOTH_OFF;
}

void loop()
{
  unsigned long currentMillis = millis();

  // Collect all input data.
  int inputState = getInputState();

  // Process the data in a state machine.
  // The output part is also in the state machine.
  switch(state)
  {
    case WAIT_FOR_BOTH_OFF:
      // Both buttons must be released to be able to continue.
      if(inputState == BOTH_OFF)
      {
        // Prepare to go to the next state.
        Serial.println("Going to WAIT_FOR_BOTH_ON state");
        state = WAIT_FOR_BOTH_ON;
      }
      break;
    case WAIT_FOR_BOTH_ON:
      // This is the state when everything is idle and no buttons are pressed.
      // Normally both buttons are released,
      // but when both are pressed, then go to the next state.
      if(inputState == BOTH_ON)
      {
        // Prepare to go to the next state.
        Serial.println("Going to SAFETY_WINDOW state");
        previousMillis = currentMillis;
        state = SAFETY_WINDOW;
      }
      break;
    case SAFETY_WINDOW:
      if(inputState != BOTH_ON)
      {
        // During the safety time window, a button was released.
        // Return to idle.
        Serial.println("Going to WAIT_FOR_BOTH_OFF state");
        state = WAIT_FOR_BOTH_OFF;
      }
      else if(currentMillis - previousMillis >= PushTimeWindow)
      {
        // The buttons are still pressed.
        // The time window has reached the end.
        // Prepare to go to the next state.
        Serial.println("Going to RELAY_ON state");
        previousMillis = currentMillis;
        digitalWrite(LED_BUILTIN, HIGH);  // LED_BUILTIN for testing
        state = RELAY_ON;
      }
      break;
    case RELAY_ON:
      if(inputState != BOTH_ON)
      {
        // One of the buttons was released.
        // Stop the relay and return to idle.
        // Although the relay was triggered, it was not succesful.
        failed++;
        Serial.print("Failed=");
        Serial.println(failed);
        Serial.println("Going to WAIT_FOR_BOTH_OFF state");
        digitalWrite( LED_BUILTIN, LOW);  // LED_BUILTIN for testing
        state = WAIT_FOR_BOTH_OFF;
      }
      else if(currentMillis - previousMillis >= RelayOnTime)
      {
        // Everyting was okay.
        // The buttons are still pressed.
        // It was complete and succesful.
        // It is time to turn off the relay and return to idle.
        success++;
        Serial.print("Success=");
        Serial.println(success);
        Serial.println("Going to WAIT_FOR_BOTH_OFF state");
        digitalWrite(LED_BUILTIN, LOW);  // LED_BUILTIN for testing
        state = WAIT_FOR_BOTH_OFF;
      }
      break;
    default:
      Serial.println("Error, unknown state");
      break;
  }
}

// This function returns the input state.
// There is no StateChangeDetection, because a state machine is used.
int getInputState()
{
  int returnInputState;

  // Read the buttons and create a input state according to the 'enum' values.
  int ButtonState1 = digitalRead(ButtonPin1);
  int ButtonState2 = digitalRead(ButtonPin2);

  if(ButtonState1 == LOW && ButtonState2 == LOW)
  {
    returnInputState = BOTH_OFF;
  }
  else if(ButtonState1 == HIGH && ButtonState2 == HIGH)
  {
    returnInputState = BOTH_ON;
  }
  else
  {
    // Not both on, not both off, so it must be something else.
    returnInputState = SOMETHING_ELSE;
  }

  return(returnInputState);
}

A few extra notes about a state machine or "finite state machine" or "FSM":
In the SAFETY_WINDOW state, I use "if .. else if .." instead of two seperate "if" statements. When the state is changed due to the buttons, then I don't want to check the timeout anymore.
In the SAFETY_WINDOW state, the relay is turned on, because there I prepare for the next state. If you think that is confusing, you can add a state in between, for example called INITIATE_RELAY_ON, and turn the relay on in that state and then continue to the next state.
That is also nice about a state machine. You can add or remove states and move code around for you convenience.
In the SAFETY_WINDOW state I check the buttons first and then the timeout. I could also check the timeout first. It does not matter.
This is typical for a state machine. When delay is replaced by millis and the Arduino loop and the state machine are executed many times per second, then it does not matter which condition is checked first.
A sketch can have many state machines. Sometimes a library contains a state machine. Such libraries often have a 'update' function, that is supposed to be called every time the Arduino loop runs.
Correction nov 4, 2017
Oops, an 'enum' is not automatically an integer. An 'enum' is its own type. Its type is more like the type of a union or struct.

That works brilliantly! Thank you for leaving the breadcrumbs in there to work out how it functions. I was running in circles trying to set up 4 different state changes timed with the millis function. I have been researching setting up finite state machines but I think I have been way over thinking it. I ended up thinking I needed 12 "What" states to keep track of instead of 7 like you used. I am now down the rabbit hole learning how these things are set up and know I think I will use similar logic here on out. Thanks again!

I can see how everything is switched around and executed in the "switch...case" function. I think I was definitely missing that type of envelope that groups it together properly. I am definitely more versed in long strings of "IF" statements that are trying to switch up and toggle too many variables.

Thanks. I have added "A few extra notes" paragraph at the end of my answer. I hope that makes the explanation complete.

Thank you for the additional information, it's really helpful.

Hello, I built the system and made the circuit board but ran into an unforeseen issue. The OSHA approved industrial switches are big and seem to bounce like crazy and in turn toggle off the logic of the program to turn off the relay and wait for the state to go low then high again. To debounce them would it would be a matter of adding an enum and a state to define each switch as debounced or not within a const unsigned long period and count millis again to toggle between the two states of within or outside of the bounce window? Does that sound on the correct track?

I suppose some smoothing capacitors on the input of the switches may do the trick of absorbing the spikes too... the solenoids and relays seem to have a nasty habit of throwing a lot of back spikes to the system which needed smoothing as well.

I would reading the inputs with digitalRead replace by Bounce2 ( https://github.com/thomasfredericks/Bounce2 ). The "debouncer.update" is called in the loop function many times until the input is stable during the specified period (called interval). There is also a mathematical much more advanced way for heavy debouncing: https://github.com/PaulMurrayCbr/DebounceInput

A RC filter at the input is always good for some extra protection. Not just a capacitor. When using only a capacitor, the current spike through the wires increases. What value is the pullup/pulldown resistor for the switch ? 220 ohm to 2k2 would be better than 10k.

Hello, I will check out bounce2 and and the other link you sent and see how it goes thank you. I have 10k pull down resistors on the switches now. I added (2) .1uf capacitors to each switch in parallel because I didn't have .2uf caps. It did smooth the bouncing out somewhat but I think that some software debouncing would really improve the system as it is still affected some by the bounce.

I use 10k for a button that is on the same pcb board. Use lower values. Can you measure with a storage scope how long the buttons bounce ? The "debouncer.update" goes directly in the Arduino loop, not behind an if-statement or so.

I have used the bounce2 library and it seems to be working as expected. I am building another system that I can test it on before I add the smoothing caps to the switches to see. The scope we have here is not working correctly so unfortunately I will have to do a bit of guessing on the debounce time. One thing that I hadn't noticed before is that the program does everything as expected except it seems to not honor the SAFETY_WINDOW. A button can be held down and even if the window has passed it still turns on the relay.

Is this behavior perhaps because the case WAIT_FOR_BOTH_ON constantly updates each cycle so the time window can't expire when the code previousMillis = currentMillis is called in that case? I will post the current state of the code in the question to show where it's at.

I tested the program before adding Bounce2 as well and the behavior of not honoring the safety window is still present.

Only 5ms ? That is for a little tiny micro switch. Use 50ms, or even up to 200ms. Can you get a number for how long the buttons are bouncing ? If you don't have a scope, perhaps a measuring sketch ? Did you replace the 10k resistor with 1k ? You really must lower that 10k. I do not understand your question, but you use the debouncerX.update and the debouncerX.read correctly. Perhaps the wires collect a lot of noise, or the wire to the button is floating. Try to measure and test more.

Now I understand your question. When a state is changed, old variables of the previous state don't have to be cleared, they are just no longer used. So when the state is changed I use the same previousMillis for the new state. I see no problem, but you can split it into two variables. What about a minimal time that both buttons must be off. There is definitely something going on with the buttons and the signal from the buttons. Is the signal perhaps LOW when the buttons are pressed ?

Hello, I will up the ms on the debounce time for sure and try to get a sketch going on to test the bounces. The pull downs have been reduced to 1k. I will try to split the time variables into two and see if I can get that to work to get the safety window working. The caps across the inputs have smoothed a lot of the bounce and the system functions as planned for the most part. I figure double insurance never hurts and I am excited to understand bounce2 and use it in the future. The only thing left is to fix the safety window. I will update when I get more information.

Perhaps my explanation of the original function was off because the notes in the sketch function exactly as they say. The buttons should have a small window within both need to be pressed. If they aren't pressed within that window they need to be released and pushed again to go back to WAIT_FOR_BOTH_OFF state. It is a window to ensure they are pushed within a specified time of each other, not a window to delay the relay turning on.

I think that may constitute a a new question as it is a different function than originally how it sounded it was stated. I will open up a new question to pose that logic.

Is there a reason that the state machine would ignore the input state of "SOMETHING_ELSE"? it seems to not ever enter that state despite one button being pushed and both high and both low not being true so it should return that state correct? I opened an additional question that is linked to this one with the new code since it was a new function to the original question.

From what I understood, this is what you're trying to do:

Turn a relay on as long as both buttons are pushed for 'pushWindowTime' milliseconds;
Keep the relay on for 'relayOnTime' milliseconds, or until at least one of the buttons are pushed.

I believe the difficulty you're facing is mostly because time is a parameter in your program, and in order to achieve that you're using 'millis()', which returns the number of milliseconds elapsed since the program starts. But rather than working with that, it may be easier in this case to use a delay associated to a loop, which is what I did.
int ButtonPin1 = 0;
int ButtonPin2 = 0;
int RelayPin = 0;

int ButtonState1 = 0;
int ButtonState2 = 0;

bool highState = false;

int pushTimeWindow = 10000;
int relayOnTime = 10000;

void setup() {
  //IOs definition
  pinMode(ButtonPin1, INPUT);
  pinMode(ButtonPin2, INPUT);
  pinMode(RelayPin, OUTPUT);

  digitalWrite(RelayPin, LOW);
}

void loop() {

  //Loop for reading each button's state in a given period of time 'pushTimeWindow'.
  for(int i = 0; i < pushTimeWindow; i++) {

    //Reads each button's state at every iteraction
    ButtonState1 = digitalRead(ButtonPin1);
    ButtonState2 = digitalRead(ButtonPin2);

    //Flags a boolean if both buttons are pushed.
    if((ButtonState1 == HIGH)&&(ButtonState2 == HIGH))
      highState = true;

    //If a button is released, breaks the loop.
    else {
      highState = false;
      break;
    }
    //Delays the loop one second.
    delay(1000);
  }

  if(highState) {

    //Loop to activate the relay as long as both buttons are pushed, during the time limit 'relayOnTime'.
    for(int i = 0; i < relayOnTime; i++) {

      ButtonState1 = digitalRead(ButtonPin1);
      ButtonState2 = digitalRead(ButtonPin2);

      //Activates the relay if both buttons are pushed.
      if((ButtonState1 == HIGH)&&(ButtonState2 == HIGH))
        digitalWrite(RelayPin, HIGH);

      //Shuts down the relay if a button is released and breaks the loop.
      else {
        digitalWrite(RelayPin, LOW);
        break;
      }

  //Delays the loop one second.
  delay(1000);
}

  }

  //Makes sure that every time loop() starts again, the relay is shut down.
  highState = false;

}

Hope this answers your question. Let us know what you find.

Hello, Thank you for taking a look at the code. The logic you stated is mostly what I am trying to do. I am trying to turn the relay on when both buttons are pushed within a time window. Both buttons need to stay pushed through the relay cycle. If either or both are released they relay must go off. After a relay cycle the system needs to wait until both buttons are released until it can initiate another relay cycle. My main concern with delays is if the system doesn't look for a button release the relay will not turn off.

Oh, I see. Now that you mentioned, there is an error in my code. The second loop also needs a digitalRead in order to constantly update each button's value. I'll edit the answer. Also, I'm assuming you would work with times like 5 or 10 seconds for both loops, so that's why the delay is 1 second long. If you want to work with shorter time periods, you could always make the delays smaller. Let me know if it works for you.

Here is the code:

your code and the code pieces posted so far suffer from two problems: 1) too specific to the application; and 2) too complicated.
here is a different approach to consider:
1) write a piece of code that reads the state of a button, with or without debouncing;
2) write a piece of code that detects no press, single press, double press, and long press (or even more if you want), using 1) above.
3) write a piece of code that detects the same but for two buttons, using 2) above.
...
you can consider the use of enum to make the code more robust.
with this approach, your code can be reused for future projects, and will be easier to maintain / understand as it is very intuitive and modular.


text:
Need help with my urgent problem
Today I found a problem in my project, here is the video of problem
https://streamable.com/wamm9
code MASTER : https://www.dropbox.com/s/l4x3zwzv6szrs50/MASTER.ino?dl=0
#include <Wire.h>

const int BUTTON1 = 5;
const int BUTTON2 = 6;
int buttonchoose;

void setup() {
  // put your setup code here, to run once:
  pinMode(BUTTON1, INPUT);
  pinMode(BUTTON2, INPUT);
  Wire.begin();
  Serial.begin(9600);
}

void loop() {
  Serial.println("You want turn X motor");
  Serial.println("1-YES  2-NO");
  buttonchoose = fonctioninput();
  delay(500);
  if (buttonchoose == 1) {
    //Turn motor x for onerevolution
    Wire.beginTransmission(8); // transmit to device #8
    Wire.write('X'); // send M (milk)
    Wire.endTransmission();    // stop transmitting
    Serial.println("send X");
  }
  Serial.println("You want turn Y motor");
  Serial.println("1-YES  2-NO");
  buttonchoose = fonctioninput();
  delay(500);
  if (buttonchoose == 1) {
    //Turn motor Y for onerevolution
    Wire.beginTransmission(8); // transmit to device #8
    Wire.write('Y'); // send M (milk)
    Wire.endTransmission();    // stop transmitting
    Serial.println("send Y");
  }

  Serial.println("You want turn Z motor");
  Serial.println("1-YES  2-NO");
  buttonchoose = fonctioninput();
  delay(500);
  if (buttonchoose == 1) {
    //Turn motor Z for onerevolution
    Wire.beginTransmission(8); // transmit to device #8
    Wire.write('Z'); // send M (milk)
    Wire.endTransmission();    // stop transmitting
    Serial.println("send Z");
  }
}

int fonctioninput() {
  int val1 = 0;
  int val2 = 0;
  int buttonreturn = 0;
  while ( (val1 - val2) == 0) {
    val1 = digitalRead(BUTTON1);
    val2 = digitalRead(BUTTON2);
  }

  if (val1 == 1) {
    buttonreturn = 1;
  }
  else {
    buttonreturn = 2;
  }
  return buttonreturn;
}

code SLAVE : https://www.dropbox.com/s/2lg8ogjep80gtsa/SLAVE.ino?dl=0
#include <Wire.h>
#include <Stepper.h>

const int stepsPerRevolution = 64;
int led = A0;
Stepper motorX(stepsPerRevolution, 2, 3, 4, 5);
Stepper motorY(stepsPerRevolution, 6, 7, 8, 9);
Stepper motorZ(stepsPerRevolution, 10, 11, 12, 13);

void setup() {
  Wire.begin(8);
  // Wire.onRequest(requestEvent);
  Wire.onReceive(receiveEvent);

  pinMode(led, OUTPUT);
  motorX.setSpeed(60);
  motorY.setSpeed(60);
  motorZ.setSpeed(60);
  Serial.begin(9600);
}

void loop() {}

void receiveEvent(int howMany) {

  char choose;

  while (Wire.available() > 0) {
    //initialization
    choose = 'A';
    choose = Wire.read();

    if (choose == 'X')    {
      Serial.println("TURN MOTOR X");

      turnX();
    }
    else if (choose == 'Y') {
      Serial.println("TURN MOTOR Y");
      turnY();
    }
    else if (choose == 'Z') {
      Serial.println("TURN MOTOR Z");
      turnZ();
    }
  }
  analogWrite(led, 1020);
  delay(300);
  analogWrite(led, 0);
}

void turnX() {
  motorX.step(stepsPerRevolution);
}

void turnY() {
  motorY.step(stepsPerRevolution);
}

void turnZ() {
  motorZ.step(stepsPerRevolution);
}

When I choose yes to turn a motor it works well but the other motors that is after does not work.
I want the other motors to turn if I choose yes even if the previous motor is running.
Please, I need your URGENT help because my project is blocked
 :(

Please edit your question to include the code that you want help with.

Also asked at http://forum.arduino.cc/index.php?topic=503016

Under what circumstances may I add “urgent” or other similar phrases to my question, in order to obtain faster answers?

The step function from the Stepper library is blocking.  So it can only run one motor at a time.  You need a different stepper library that is non-blocking.  Try AccelStepper.


text:
Compilation Error in nodeMCU along with oneWire temperature sensor ds18b20, and 2x16 LCD display (not I2C)
I am using nodeMCU along with oneWire temperature sensor ds18b20, and 2x16 LCD display (not I2C). I am using Arduino IDE to program nodeMCU. I am getting a compilation error:
C:\Program Files (x86)\Arduino\libraries\OneWire/OneWire.h:108:2: error: #error "Please define I/O register types here"
#error "Please define I/O register types here"
^
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

What is meant by: "Please define I/O register types here"? Thank you for the help.

Also asked at https://stackoverflow.com/q/46498587

I replaced my old OneWire.h code with this(Click here) code, and it worked amazingly.

It appears you're using an outdated version of the OneWire library that does not support ESP8266. Please follow these instructions to upgrade to the latest release of the library:

Sketch > Include library > Manage libraries...
Wait for the download to finish.
In the "Filter your search..." box, type "onewire".
Click on the "OneWire" entry.
Click the "Update" button.
Wait for the installation to finish.
Click the "Close button.

The recent releases of the OneWire library have support for ESP8266 so this should solve your compilation issue.


text:
There is an error stating that "exit status 1 expected unqualified-id before 'if'. This project is used to turn on/off LED and magnetic door
* /
#define CUSTOM_SETTINGS
#define INCLUDE_KEYPAD_SHIELD

/* Include 1Sheeld library. */
#include <OneSheeld.h>

/* Define an iterator. */
int iterations = 0;

/* A name for the LockPin on pin D2. */
int lockPin = 2;
int ledRed = A5;
int ledGreen = A4;

/* A name for the switch led on pin D5. */
const int lampuPin = 5;
const int ledlampu = A0;

// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
int stateBefore = 0;
int i = 0;
int j = 0;

void setup() {
  /* Start communication. */
  OneSheeld.begin();
  /* Set the LED & LOCK as output. */
  pinMode(lockPin, OUTPUT);
  pinMode(ledRed, OUTPUT);
  pinMode(ledGreen, OUTPUT);
  /* Set the LampuPin pin as output. */
  pinMode(lampuPin, INPUT);
  /* Set the LED pin as output. */
  pinMode(ledlampu, OUTPUT);
}

void loop() {
  //======Lampu Rumah=======
  // read the state of the pushbutton value:
  buttonState = digitalRead(lampuPin);
  if (buttonState != stateBefore) {
    if (buttonState == HIGH and i == 0) {
      digitalWrite (ledlampu, HIGH);
      j = 1;
    } else if (buttonState == LOW and j == 1) {
      i = 1;
    } else if (buttonState == HIGH and i == 1) {
      digitalWrite (ledlampu, LOW);
      j = 0;
    } else if (buttonState == LOW and j == 0) {
      i = 0;
    }
  }
  stateBefore = buttonState;
}

//======Pintu Hadapan Rumah=======
/* Check if "1" is pressed, iterate one time. */
if (iterations == 0 && isOnePressed()) {
  iterations++;
} else if (iterations == 1 && isTwoPressed()) {
  /* Check if "2" is pressed, iterate one time. */
  iterations++;
} else if (iterations == 2 && isThreePressed()) {
  /* Check if "3" is pressed, iterate one time. */
  iterations++;
} else if (iterations == 3 && isFourPressed()) {
  /* Check if "4" is pressed, iterate one time. */
  iterations++;
} else if (isOtherButtonPressed()) {
  /* Check if any other button is pressed, reset iterations. */
  iterations = 0;
}
if (iterations == 4) {
  /* Check if the number of iterations is 4, blink the LED. */
  digitalWrite(lockPin, LOW);
  digitalWrite(ledGreen, HIGH);
  digitalWrite(ledRed, LOW);
  OneSheeld.delay(6000);
  digitalWrite(lockPin, HIGH);
  digitalWrite(ledRed, HIGH);
  digitalWrite(ledGreen, LOW);
  OneSheeld.delay(1000);
  /* Reset the iterator. */
  iterations = 0;
}

/* Helper functions check if a certain button is pressed by checking its row and column. */

boolean isOnePressed() {
  return Keypad.isRowPressed(0) && Keypad.isColumnPressed(0);
}

boolean isTwoPressed() {
  return Keypad.isRowPressed(0) && Keypad.isColumnPressed(1);
}

boolean isThreePressed() {
  return Keypad.isRowPressed(0) && Keypad.isColumnPressed(2);
}

boolean isFourPressed() {
  return Keypad.isRowPressed(1) && Keypad.isColumnPressed(0);
}

boolean isOtherButtonPressed() {
  return ((Keypad.isAnyColumnPressed() || Keypad.isAnyColumnPressed()) && !isOnePressed() && !isTwoPressed() && !isThreePressed() && !isFourPressed());
}

You got an extra closing brace after this line.
stateBefore = buttonState;
}

It ends the loop function so the next if is outside any function and illegal.  Hit Control-T in the IDE to auto-format the code and it will line up the indention and that will help you spot these sorts of errors.


text:
ESP8266-01 wrong flow control settings
Changed ESP8266-01 to wrong settings by mistake. It was working ok
at 115200 (its default settings). It was connected like this:
PC->(USB)->Arduino->ESP8266.
Using Arduino as bridge

Pins 0 and 1 (RX/TX) connected directly to ESP8266 since I didnt have
USB to TTL adapter.
MCU removed so I could make that scenario work

It was just for testing AT commands. I did it like that because I realized that I was getting errors all the time trying to connect
using SerialSoftware (and different pins in Arduino).
Found out later that SerialSoftware does not work correctly at 115200...
So I issued the following AT command:
         AT+UART_DEF=9600,8,1,0,3

Now I cannot connect to the ESP8266 to correct that setting. All I get is garbage characters. I understand it's because of the flow control settings. I set it to both RTS and CTS which I also read later ESP8266 does not support?
Have tried:

Using Putty to change settings of COM port at connect. Have tried all speeps and flow control settings combinations I could think of. I get nothing or garbage characters.
Changing COM port setting from Device Manager (Windows 7)
Flashing ESP8266 using official tool (ESPFlashDownloadTool_v3.6.1.0).It won't sync with the ESP8266. It does not allow me to adjust speed to 9600. Minimun speed that show is 115200
Changing settings in ESPFlashDownloadTool_v3.6.1.0 so it will sync at 9600 (file: spi_download.conf)

I cannot think of anymore ideas. Have I completely messed up my ESP8266?
Is there a way that I'm not aware of that could fix this problem? How?
Thanks in advance!
Jorge

Maybe https://arduino.stackexchange.com/a/31610/20513 can help? Seems like it helps in some situations at least.

AT+UART_DEF=9600,8,1,0,3

Are you aware that this configuration (3) as a rule would require both RTS and CTS extra physical signals to work ? That means, if you do not connect anything there, the level present at some pin configured anywhere would prevent ESP8266 from receiving further data from serial.
In general people use "no flow control" (0)
AT+UART_DEF=9600,8,1,0,0

andre,
As I stated in my post I did it by mistake. Nonetheless I was able to fix it by using a different flashing tool that used just one .bin file instead of many like the official ESP8266 tool does.
Can anyone please explain me why is that? Why are there different tools to flash the ESP8266? In concrete, why one requires just one file that will update the SDK and AT firmware in one pass, and the other requires many differente files? Or just a link to a site o post so I can better understand the differences?
The tool I ended up usign is "ESP8266 Flash Downloader"

The file I used: AiThinker_ESP8266_DIO_8M_8M_20160615_V1.5.4.bin
Thanks!


text:
Arduino <<I2C>> ATtiny85 stops updating variables after a while
I've been working on a project for the last few days and spent a LOT of time googling, reading and testing. I'm kinda running out of ideas now and instead of bumping my head to the wall I thought posting my issue here in the hopes someone might be able to point me towards the right direction
I've got an Arduino UNO programmed as I2C Master and an ATtiny85 as an I2C slave. An single Adafruit Neopixel LED is attached to the slave.
When running the two sketches below everything actually works perfect.....for about a minute or so.
While during correct operations the Neopixel LED is actually changing color correctly and the serial monitor on the Uno shows the correctly updated R-G-B values, things change after about 1 minute of running.
The LED keeps blinking, which tells me the ATtiny is not frozen.
The UNO keeps sending I2C and is receiving I2C data...but the data is constant. The updated RGB that the Uno (master) has been sending to the ATtiny slave are somehow not handled (correctly) by the slave.
Any thoughts are more then appreciated. I'm totally lost and do not know which directions to go from here so any pointers would be more then welcome.
The Master - Arduino Uno -
#include <Wire.h>

#define I2C_MASTER_ADDR 0x04
#define I2C_SLAVE_ADDR 0x05

/*
* Software config
*/
int pollInterval = 700;//Milliseconds

//Demo's
#define demoLedInterval 150//In milliseconds
boolean demoRequest = false;

/*
* Internal variables
*/
unsigned long lastPoll = 0;

int demoLedState = 0;
unsigned long lastDemoLedUpdate = 0;

/*
* Setup function
*/
void setup()
{
 Wire.begin(I2C_MASTER_ADDR);  // join i2c bus (address optional for master)
 Serial.begin(115200);         // start serial for output
 Serial.println("Setup complete");
}

/*
* The main loop
*/
int i =0;
void loop()
{

 /*
  * Poll the slave
  */
 if( (millis()-lastPoll) > pollInterval)
 {
   /*
    *
    */
   int red=0; int green=0; int blue=0;

     if(i==0)
     {
       Serial.println("Write data to slave - set led red");
       Wire.beginTransmission(I2C_SLAVE_ADDR);
       Wire.write(0xC2);//Command
       Wire.write(0x00);
       Wire.write(255);//Data
       Wire.endTransmission();
       Wire.beginTransmission(I2C_SLAVE_ADDR);
       Wire.write(0xC3);//Command
       Wire.write(0x00);
       Wire.write(0);//Data
       Wire.endTransmission();
       Wire.beginTransmission(I2C_SLAVE_ADDR);
       Wire.write(0xC4);//Command
       Wire.write(0x00);
       Wire.write(0);//Data
       Wire.endTransmission();
     }
     if(i==1)
     {
       Serial.println("Write data to slave - set led green");
       Wire.beginTransmission(I2C_SLAVE_ADDR);
       Wire.write(0xC2);//Command
       Wire.write(0x00);
       Wire.write(0);//Data
       Wire.endTransmission();
       Wire.beginTransmission(I2C_SLAVE_ADDR);
       Wire.write(0xC3);//Command
       Wire.write(0x00);
       Wire.write(255);//Data
       Wire.endTransmission();
       Wire.beginTransmission(I2C_SLAVE_ADDR);
       Wire.write(0xC4);//Command
       Wire.write(0x00);
       Wire.write(0);//Data
       Wire.endTransmission();
     }
     if(i==2)
     {
       Serial.println("Write data to slave - set led blue");
       Wire.beginTransmission(I2C_SLAVE_ADDR);
       Wire.write(0xC2);//Command
       Wire.write(0x00);
       Wire.write(0);//Data
       Wire.endTransmission();
       Wire.beginTransmission(I2C_SLAVE_ADDR);
       Wire.write(0xC3);//Command
       Wire.write(0x00);
       Wire.write(0);//Data
       Wire.endTransmission();
       Wire.beginTransmission(I2C_SLAVE_ADDR);
       Wire.write(0xC4);//Command
       Wire.write(0x00);
       Wire.write(255);//Data
       Wire.endTransmission();
     }

   i++; if(i>2) i =0;

   /*
    * General request (without data). Should return something though
    */
   Serial.println("General request for slave");
   Wire.requestFrom(I2C_SLAVE_ADDR, 7);//Request N bytes, N=byte_len
   delay(10);//Give the slave time to answer
   while (Wire.available())
   {
     uint8_t next_byte = Wire.read();
     Serial.print(next_byte);Serial.print(" ");
   }
   Serial.println("\n");

   lastPoll = millis();
 }//End if time to poll again

}//End loop

The Slave code - ATtiny 85 - Main file
#include <EEPROM.h>
#include <OneWire.h>
#include <TinyWireS.h>
#include <Bounce2.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__ //Which will be true for ATtiny85
  #include <avr/power.h>
#endif

#define I2C_SLAVE_DEFAULT_ADDR 0x05

#include "namespaces.h"//Include at last to make sure all libs are present

//Software config
#define BUTTON_DEBOUNCE 5//Debounce milliseconds

//Hardware config
#define NEOPIXEL_PIN  1
#define BUTTON_PIN    3
#define DS2401_PIN    4

#define NUMPIXELS     1

/*
 * Initialize instances/classes
 */
Bounce button = Bounce();
Adafruit_NeoPixel neopixel = Adafruit_NeoPixel(NUMPIXELS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
OneWire ds(DS2401_PIN);

void setup()
{
  uint32_t _now = millis();

  //Start I2C
  uint8_t _device_addr = EEPROM_DATA::get_device_addr();
  //TinyWireS.begin(_device_id);
  TinyWireS.begin(I2C_SLAVE_DEFAULT_ADDR);
  TinyWireS.onReceive(I2C::receiveEvent);
  TinyWireS.onRequest(I2C::requestEvent);

  //Start NeoPixel
  neopixel.begin();
  neopixel.setPixelColor(NUMPIXELS-1, neopixel.Color(255, 255, 255) );
  neopixel.show();

  //Start Button
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  button.attach(BUTTON_PIN);
  button.interval(BUTTON_DEBOUNCE);

}

unsigned long lastBlink = 0;
boolean lastBlinkState;

void loop()
{

  button.update();

  if(VARS::led_needs_update)
  {
    led_update();
    VARS::led_needs_update = false;
  }

  if(button.fell())
  {
    VARS::button_state = HIGH;
  }
  if(button.rose())
  {
    VARS::button_state = LOW;
  }

  //testblink
  if ( (millis()-lastBlink) > 600)
  {
    if(lastBlinkState)
    {
      neopixel.setPixelColor(NUMPIXELS-1, 0,0,0 );
      neopixel.show();
      lastBlinkState = false;
    }
    else
    {
      led_update();
      lastBlinkState = true;
    }
    lastBlink = millis();
  }

  // This needs to be here for the TinyWireS lib
  TinyWireS_stop_check();
}

/*
 * Helper functions
 */
void led_update()
{
  neopixel.setPixelColor(NUMPIXELS-1,
    VARS::led_red,
    VARS::led_green,
    VARS::led_blue
  );
  neopixel.show();
}

The Slave code - ATtiny 85 - namespaces.h
namespace VARS
{
  //These are available in a I2C response
  volatile boolean button_state = 0;
  volatile int led_red = 0;
  volatile int led_green = 0;
  volatile int led_blue = 0;
  uint8_t sn_family;
  uint8_t sn_bit1;
  //uint64_t serial_number = 0;
  //int I2C_response_max_length = 4;//Count the above

  //These are internal
  volatile boolean led_needs_update = false;
  int update_interval     = 300;
  unsigned long last_update = 0;
}

//===========================================================================

namespace EEPROM_DATA
{
  uint8_t default_device_addr   =     I2C_SLAVE_DEFAULT_ADDR;
  uint8_t this_device_address   =     0x05;

  bool device_addr_valid(uint8_t addr)
  {
    return (addr > 0x04 && addr < 0x7E);
  }
  bool store_device_addr(uint8_t new_device_addr)
  {
    if (!device_addr_valid(new_device_addr)) return false;//cancel if out of bounds. Assume corrupt data.
    EEPROM.write(EEPROM_DATA::this_device_address, new_device_addr);//Set new i2c address into EEPROM
    return true;
  }
  uint8_t get_device_addr()
  {
    uint8_t _addr = EEPROM.read(EEPROM_DATA::this_device_address);
    if (!device_addr_valid(_addr))
    {
      _addr = EEPROM_DATA::default_device_addr;
      store_device_addr(_addr); //update EEPROM with a valid/default device id.
    }
    return _addr;
  }
}

//===========================================================================

namespace COMMANDS
{
  enum {
    assign_new_device_addr  =     0xC1,
    set_led_red             =     0xC2,
    set_led_green           =     0xC3,
    set_led_blue            =     0xC4
  };
  bool do_command(uint8_t cmd, uint16_t cmd_data)
  {
    //interpret command.
    switch (cmd)
    {
      //set new i2c slave adress.
      //ATTENTION: After command is performed, the chip will need a hard reset.
      case COMMANDS::assign_new_device_addr:
        uint8_t new_device_addr;
        new_device_addr = uint8_t(cmd_data & 0x007F);//ensure the address is 7-bit.
        return EEPROM_DATA::store_device_addr(new_device_addr);//return true if saved, false if invalid address.
        break;

      case COMMANDS::set_led_red:
        //if (cmd_data > 0x00FF) break;//ignore out of range data. Assume corrupt packet.
        VARS::led_red = int(cmd_data);
        VARS::led_needs_update = true;
        break;

      case COMMANDS::set_led_green:
        //if (cmd_data > 0x00FF) break;//ignore out of range data. Assume corrupt packet.
        VARS::led_green = int(cmd_data);
        VARS::led_needs_update = true;
        break;

      case COMMANDS::set_led_blue:
        //if (cmd_data > 0x00FF) break;//ignore out of range data. Assume corrupt packet.
        VARS::led_blue = int(cmd_data);
        VARS::led_needs_update = true;
        break;
    }
  }
}

//===========================================================================
int pointer = 0;
namespace I2C{

  //Gets called when the ATtiny receives a general i2c data request.
  //Tx_stop is sent after end of call, so all bytes need to be sent before leaving.
  void requestEvent()
  {

//The number of bytes requested should NOT exceed the number of bytes returned
    TinyWireS.send( VARS::button_state );
    TinyWireS.send( VARS::led_red );
    TinyWireS.send( VARS::led_green );
    TinyWireS.send( VARS::led_blue );

  }

  //Gets called when the ATtiny recieves an i2c message THAT CONTAINS DATA from another device.
  void receiveEvent(uint8_t byte_count)
  {
    //first byte is command, next 2 bytes is data for command. Total must equal 3 bytes.
    if (!TinyWireS.available() || byte_count != 3 ) return;

    //retrieve the command and 16-bit data.
    //Incomming data is ordered CMD,Data-MSB,Data-LSB.
    uint8_t cmd = TinyWireS.receive();
    uint16_t cmd_data = (TinyWireS.receive() << 8);
    cmd_data += TinyWireS.receive();

    COMMANDS::do_command(cmd, cmd_data);
  }

}

Three packets of data are sent over the I2C bus, with no time to breathe for air for the Attiny85 in between. You could add delay(1) between sending the commands after Wire.endTransmission. The delay(10) after the Wire.requestFrom can be removed. The Wire.requestFrom does the waiting itself. The slave uses NeoPixel and OneWire. That is a big problem since both libraries turn off the interrupts for the timing specific protocol. That will always be in the way of interrupts. You could make the Attiny85 the master. How long are the wires ? https://sigrok.org/wiki/Supported_hardware#Logic_analyzers

millis() returns a long, but your pollInterval is an int.  Try pollInterval as a long to avoid an implied casting issue.  You do long to int comparisons in other places as well.

Dennis Hunink, what is happening ? You ask a very specific question. I mentioned a timing/interrupt problem which could be the problem. But then you don't respond anymore.

@Jot real life happend  I did not had time to post the final answer until just now. But I did found a solution thanks to your very specific suggestions. Thanks so much for that. The timing and interrupts proved to be the essential factors here. So basically your comment saved my life
(wires are about 20CM so no issues there; turned out to be purely software)

Please, accept your own answer to close this question

After diving into interrupts, timing etc I did found the solution.
Thanks for all the suggestions, in particular to @Jot!
In the end I took the following steps:
- adding a 1ms delay after each Wire.endTransmission()
- dropped the Neopixel lib (https://github.com/cpldcpu/light_ws2812)
Below is the final code, for anyone interested.
There is still an issue with this code: requesting multiple bytes from the slave always results in receiving just a single byte. But since that's most likely unrelated to the original question I'm opening a new topic for that (if I really can't find a solution myself, that is).
Master
/*
 *
 */

#include <Wire.h>

#define I2C_MASTER_ADDR 0x04
#define I2C_SLAVE_ADDR 0x05

/*
 * Software config
 */
int pollInterval = 700;//Milliseconds

/*
 * Internal variables
 */
unsigned long lastPoll = 0;

/*
 * Setup function
 */
void setup()
{
  Wire.begin(I2C_MASTER_ADDR);  // join i2c bus (address optional for master)
  Serial.begin(115200);         // start serial for output
  Serial.println("Setup complete");
}

/*
 * The main loop
 */
int i = 0;
void loop()
{

  /*
   *
   */
  if( (millis()-lastPoll) > pollInterval)
  {
    Serial.println("Write data to slave");
    Wire.beginTransmission(I2C_SLAVE_ADDR);
    Wire.write(0x01);//Register to start at
    switch(i)
    {
      case 0:
        Wire.write(255);
        Wire.write(0);
        Wire.write(0);
        i++;
        break;
      case 1:
        Wire.write(0);
        Wire.write(255);
        Wire.write(0);
        i++;
        break;
      case 2:
        Wire.write(0);
        Wire.write(0);
        Wire.write(255);
        i = 0;
        break;
    }
    Wire.endTransmission();
    delay(1);//Dont let the slave panic

    //Set the register pointer back to 0x01
    Wire.beginTransmission(I2C_SLAVE_ADDR);
    Wire.write(0x00);//Register to start at
    Wire.endTransmission();
    delay(1);//Dont let the slave panic

    //Get values from the three registers up form 0x01
    Wire.requestFrom(I2C_SLAVE_ADDR, 6);//Request N bytes
    while (Wire.available())
    {
      uint8_t next_byte = Wire.read();
      Serial.print(next_byte);Serial.print(" ");
    }
    Serial.println("\n");

    lastPoll = millis();
  }//End if time to poll again

}//End loop

Slave
#include <EEPROM.h>
#include <OneWire.h>
#include <TinyWireS.h>
#include <Bounce2.h>
#include <WS2812.h>
#ifdef __AVR__ //Which will be true for ATtiny85
  #include <avr/power.h>
#endif

//Software config
#define I2C_SLAVE_DEFAULT_ADDR 0x05
#define BUTTON_DEBOUNCE 5//Debounce milliseconds

//Hardware config
#define NEOPIXEL_PIN  1
#define BUTTON_PIN    3
#define DS2401_PIN    4

#define NUMPIXELS     1

/*
 * I2C Registers
 *
 * Register map:
 * 0x00 - Button state
 * 0x01 - led value red
 * 0x02 - led value green
 * 0x03 - led value blue
 * 0x04 - SerialNumber - Family (byte 0)
 * 0x05 - SerialNumber - Byte 1
 * 0x06 - SerialNumber - Byte 2
 * 0x07 - SerialNumber - Byte 3
 * 0x08 - SerialNumber - Byte 4
 * 0x09 - SerialNumber - Byte 5
 * 0x10 - SerialNumber - Byte 6
 * 0x11 - SerialNumber - CNC (byte 7)
 *
 * Total size: 12
 */
const byte reg_size = 12;
volatile uint16_t i2c_regs[reg_size];

/*
 * Internal variables
 */
cRGB value;
volatile boolean led_needs_update = false;
volatile byte reg_position;

/*
 * Initialize instances/classes
 */
Bounce button = Bounce();
WS2812 led(NUMPIXELS);

void setup()
{
  //Start I2C
  //uint8_t _device_addr = EEPROM_DATA::get_device_addr();
  TinyWireS.begin(I2C_SLAVE_DEFAULT_ADDR);
  TinyWireS.onReceive(i2cReceiveEvent);
  TinyWireS.onRequest(i2cRequestEvent);

  //Start Led
  led.setOutput(NEOPIXEL_PIN);
  value.b = 255; value.g = 0; value.r = 0;
  led.set_crgb_at(0, value); //Set value at LED found at index 0
  led.sync(); // Sends the value to the LED

  //Start Button
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  button.attach(BUTTON_PIN);
  button.interval(BUTTON_DEBOUNCE);

}

void loop()
{
  button.update();

  if(led_needs_update)
  {
    led_update();
    led_needs_update = false;
  }

  if(button.fell())
  {
    i2c_regs[0x00] = true;
  }
  if(button.rose())
  {
    i2c_regs[0x00] = false;
  }

  // This needs to be here for the TinyWireS lib
  TinyWireS_stop_check();

}

/*
 * I2C Handelers
 */
void i2cReceiveEvent(uint8_t howMany)
{
    if (howMany < 1)
    {
        return;// Sanity-check
    }

    reg_position = TinyWireS.receive();
    howMany--;
    if (!howMany)
    {
        return;// This write was only to set the buffer for next read
    }

    while(howMany--)
    {
        //Store the recieved data in the currently selected register
        i2c_regs[reg_position] = TinyWireS.receive();

        //Proceed to the next register
        reg_position++;
        if (reg_position >= reg_size)
        {
            reg_position = 0;
        }
    }
    led_needs_update = true;
}//End i2cReceiveEvent()

void i2cRequestEvent()
{
    //Send the value on the current register position
    //NOT WORKING when requestin multiple bytes
    //TinyWireS.send(i2c_regs[reg_position]);

    //WORKAROUND
    int n = reg_size - reg_position;//Number of registers to return
    for(int i = reg_position; i < n; i++)
    {//Return all bytes from the reg_position to the end
      TinyWireS.send(i2c_regs[i]);
    }

    // Increment the reg position on each read, and loop back to zero
    reg_position++;
    if (reg_position >= reg_size)
    {
        reg_position = 0;
    }
}//End i2cRequestEvent

/*
 * Helper functions
 */
void led_update()
{
  cRGB val;
  val.r = i2c_regs[0x01];
  val.g = i2c_regs[0x02];
  val.b = i2c_regs[0x03];
  led.set_crgb_at(0, val);
  led.sync(); // Sends the value to the LED
}

I'm glad it is working better. I don't know why only a single byte is received. I can't see that in the code. The WS2812 RGB leds need that specific timing protocol. Looking at the light_ws2812.c source code, it also turnes off interrupts. I have an Arduino Uno as a slave and a DHT22 sensor connected to it. The DHT22 also have a timing protocol and turn off the interrupts. My solution was to remove the disabling of interrupts, and let the DHT22 library run every few seconds and simply ignore the wrong ones. It has a checksum, so that was a lot easier than a RGB led.

Yeah to be perfectly honest I do believe that the primary fix was adding the delay(1) after each write. After switching from Neopixel to WS2812 lib I did found that interrupts were still affected. Looks like that's a requirement for the chips. So I am thinking a lot on how to make the I2C communication more reliable, even when affected due to interruptes. checksum is perfect, but even with RGB values there has to be a way. And it not, we will find a way :0
On the other hand, implementing a checksum should not be that hard...

About the single byte that is received: is that a know limitation of the TineWireS ? That only one byte at a time can be send per request ?

That’s what I’ve been trying to figure out, without luck so far. The source code is just a bit to complicated for me to give a definitive answer. But the inline commands on github suggest there should not be such a limitation...

@Jot after spending a lot more time on reading through the TinyWireS lib over and over again I do think sending multiple bytes should be possible. As I am officially stuck now, I've openend a issue here: https://github.com/rambo/TinyWire/issues/36


text:
ERROR on SIM900AT comand HTTPDATA (POST method)
Good day community, I have a project which is VEHICLE GPS Tracker and I'm using Arduino Mega, NEO GPS6MV2 and SIM900. I'm using SIM900 to send the GPS coordinates on a web server. I'm using the POST method and SIM900 is capable of this by using AT commands. I will also save the coordinates on a MySQL database.
My problem here is I can't send the data on the MySQL database. As you can see on the latter part of the commands, it response "ERROR".  That's why the coordinates failed to enter on the database. This is what I have on the database: What do you think is the problem here?

Is there a 10 second delay between DOWNLOAD and ERROR?

If you say you are going to send 90 characters you must send 90 characters. No more, no less. I count 70 there.
You have to send them immediately the modem responds DOWNLOAD otherwise it times out (10 seconds) and you get ERROR. It looks to me like you're not sending anything (except maybe a blank line) for those 10 seconds and only trying to send once it has errored.


text:
A4988 Vref too low
I'm driving a stepper rated at 5V/1.7A using an A4988-based driver circuit with a 12V power supply.  An Arduino controls the stepping sequence.
According to the datasheet for my A4988, I should be calculating Vref as:
Imax = Vref / (8 * Rs)  so,
Vref = I * (8 x Rs) (where Rs is 0.1 ohm on this particular board and confirmed with meter).
So, Vref should be (1.7A x .8) or 1.36V to drive 1.7amps.
The problem is, I cannot adjust the A4988 to get Vref up that high.
With the adjustment pot full swing, the best I can get is .9 to 1V.  When I energize and hold the motor and use an amp meter, the coil is drawing about .9 amps -- which is still less than the 70% of 1.7 Amps I would like (using full-step mode).
Is Vref potential limited by the input voltage of 12 volts?  Is there something else I'm missing?
Thanks in advance.
Added:  This is the circuit I am using:

Can you please provide your circuit diagram/schematic. I suspect your wiring is wrong.

Image of circuit added..

I see the circuit but not the adjustment pot referenced in the question, so can't answer yet.

The adjustment pot is built into the circuit board and came that way.  Rs is also built into the circuit.  http://www.elegoo.com/product/elegoo-stepstick-stepper-motor-driver-module-a4988-heat-sink-for-3d-printer-reprap-cnc-machine-or-roboticspack-of-5/

You have a 30K resistor divider in series with the trimmer. Change the 30K resistor for one rated at 27K to obtain those higher values. ;)


text:
Can Arduino post multiple sensor data to one Google Spreadsheet?
Let's say I have one MQ5 gas sensor at home and one MQ135 gas sensor at the park. They are wirelessly hooked to Arduino.
My questions are:
Can Arduino post the data from two or more sensors to one Google Spreadsheet and organize it in two different charts?
Can only one Arduino accomplish this?
If not, what are the alternatives?

Perhaps you could do a web search before posting ?

I do this sort of thing for my solar plant, but I do it by pairing all my arduino-based sensors with a Raspberry Pi via Serial.  I keep the Arduino IDE on the Pi so I can reprogram them remotely via the same cable.  Pis are accessed via WiFi.  The Pis all have Internet access so this wouldn't be difficult to do it that way directly.  Myself, I have each Pi collect the readings into CSV files and also PNG plots (using gnuplot), then at midnight my main Linux machine uploads all the data for formatting.  I can't answer your question directly, but in my case, I do all Internet stuff in Linux.

Not directly but with addon service like Pushingbox, temboo and so on it can.
If you google on your topic there are a ton of ways to do it!