text:
ESP8266 won't receive messages after a while
There are 5 ESP8266s being used. Three act as a middleman (in AP_STA mode), one sends the message, and the last one receives the message after being passed over the middlemans (imagine it as a line, starting with nr. 1 in STA mode, sending the date to middleman 1. M1 sends it to M2, M2 sends it to M3, M3 sends it to the receiver, set in AP mode).
After like 10 min. of sending a message, one chip always stops. Stops as in, not receiving or sending the message. Every time a message is send, I use the command Client21.flush() (Client21 is just a name).
My idea is that I have to somehow also flush() after recieving a message, not just after sending one. Is there like a "receive buffer" that I can flush(), and how is it possible?
(no code provided)
Update 1: This is what the first middleman (chip no.3) printed in serial monitor when he "crashed":
Exception (29):
epc1=0x4000e1c3 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000018 depc=0x00000000

ctx: sys
sp: 3fffebc0 end: 3fffffb0 offset: 01a0

stack
3fffed60:  3fffc278 40101fe8 3fffc200 00000000
3fffed70:  3ffed93c 3fffb374 000000c0 401004e4
3fffed80:  40000f83 3fffb374 402384b0 401068b0
3fffed90:  402268ac 00000023 00000000 402268d1
3fffeda0:  000000c0 4021403b 00000018 3ffed6cc
3fffedb0:  00000000 00000000 00000020 40100f22
3fffedc0:  4021881e 4021873c 3ffef80c 40100f22
3fffedd0:  01004e43 4010000d 3ffee034 4021cb7d
3fffede0:  00000018 3ffed750 3ffed6cc 00000000
3fffedf0:  402188df 3ff20a00 3ffef80c 3ffe9be6
3fffee00:  3ffe9bcc 3fffee90 3fffee90 00000000
3fffee10:  4c4c4148 3331324f 40102200 3ffe9bcc
3fffee20:  3ffe9be6 0000002c 00000004 40100518
3fffee30:  3ffe9bd6 3ffefc74 402154a0 3ff20a00
3fffee40:  3ffef80c 3fffbfcc 00000015 40215373
3fffee50:  4000050c 3ffef45c 00000000 4021b377
3fffee60:  40106afd 00000030 00000011 ffffffff
3fffee70:  00000000 4bc6a7f0 7645a1ca 00000000
3fffee80:  00000000 00000000 4bc6a7f0 00000000
3fffee90:  4020cb8c 3ffe8f84 40106520 00190810
3fffeea0:  00000000 4bc6a7f0 3ffe8f84 40212cbc
3fffeeb0:  1cf15308 00000000 00000002 4020bad8
3fffeec0:  4021d149 ffffffa2 00000000 000001f4
3fffeed0:  40214baf 3ffe9bcc 3ffecd80 3ffef80c
3fffeee0:  00000000 3ffe9bd6 3ffe9bf0 3ffeeec4
3fffeef0:  4020cb8c 00000000 00000000 3ffe9bd6
3fffef00:  61c78017 000000c3 00000000 3ffefc74
3fffef10:  3ffe9bc0 00000000 00000002 4022463a
3fffef20:  3ffecd80 3ffe9bc0 3fffdcc0 3ffe9370
3fffef30:  3ffe9bdc 3ffefab4 00000040 3ffe9370
3fffef40:  00000040 3ffecd80 00000000 3ffe85e0
3fffef50:  40223f17 3fffdab0 00000000 40204ac7
3fffef60:  3ffe9370 40000f49 3fffdab0 40000f49
3fffef70:  40000e19 40001878 00000002 00000000
3fffef80:  3fffff10 aa55aa55 0000008f 40104424
3fffef90:  4010442a 00000002 00000000 056f21c7
3fffefa0:  4010000d 31c0f00e 8b4afbe9 f30f0180
3fffefb0:  00000000 3fffef4c 00000000 3fffff28
3fffefc0:  3fffffd0 00000000 00000000 feefeffe
3fffefd0:  feefeffe feefeffe feefeffe feefeffe
3fffefe0:  feefeffe feefeffe feefeffe feefeffe
3fffeff0:  feefeffe feefeffe feefeffe feefeffe
3ffff000:  feefeffe feefeffe feefeffe feefeffe
3ffff010:  feefeffe feefeffe feefeffe feefeffe
3ffff020:  feefeffe feefeffe feefeffe feefeffe
3ffff030:  feefeffe feefeffe feefeffe feefeffe
3ffff040:  feefeffe feefeffe feefeffe feefeffe
3ffff050:  feefeffe feefeffe feefeffe feefeffe
3ffff060:  feefeffe feefeffe feefeffe feefeffe
3ffff070:  feefeffe feefeffe feefeffe feefeffe
3ffff080:  feefeffe feefeffe feefeffe feefeffe
3ffff090:  feefeffe feefeffe feefeffe feefeffe
3ffff0a0:  feefeffe feefeffe feefeffe feefeffe
3ffff0b0:  feefeffe feefeffe feefeffe feefeffe
3ffff0c0:  feefeffe feefeffe feefeffe feefeffe
3ffff0d0:  feefeffe feefeffe feefeffe feefeffe
3ffff0e0:  feefeffe feefeffe feefeffe feefeffe
3ffff0f0:  feefeffe feefeffe feefeffe feefeffe
3ffff100:  feefeffe feefeffe feefeffe feefeffe
3ffff110:  feefeffe feefeffe feefeffe feefeffe
3ffff120:  feefeffe feefeffe feefeffe feefeffe
3ffff130:  feefeffe feefeffe feefeffe feefeffe
3ffff140:  feefeffe feefeffe feefeffe feefeffe
3ffff150:  feefeffe feefeffe feefeffe feefeffe
3ffff160:  feefeffe feefeffe feefeffe feefeffe
3ffff170:  feefeffe feefeffe feefeffe feefeffe
3ffff180:  feefeffe feefeffe feefeffe feefeffe
3ffff190:  feefeffe feefeffe feefeffe feefeffe
3ffff1a0:  feefeffe feefeffe feefeffe feefeffe
3ffff1b0:  feefeffe feefeffe feefeffe feefeffe
3ffff1c0:  feefeffe feefeffe feefeffe feefeffe
3ffff1d0:  feefeffe feefeffe feefeffe feefeffe
3ffff1e0:  feefeffe feefeffe feefeffe feefeffe
3ffff1f0:  feefeffe feefeffe feefeffe feefeffe
3ffff200:  feefeffe feefeffe feefeffe feefeffe
3ffff210:  feefeffe feefeffe feefeffe feefeffe
3ffff220:  feefeffe feefeffe feefeffe feefeffe
3ffff230:  feefeffe feefeffe feefeffe feefeffe
3ffff240:  feefeffe feefeffe feefeffe feefeffe
3ffff250:  feefeffe feefeffe feefeffe feefeffe
3ffff260:  feefeffe feefeffe feefeffe feefeffe
3ffff270:  feefeffe feefeffe feefeffe feefeffe
3ffff280:  feefeffe feefeffe feefeffe feefeffe
3ffff290:  feefeffe feefeffe feefeffe feefeffe
3ffff2a0:  feefeffe feefeffe feefeffe feefeffe
3ffff2b0:  feefeffe feefeffe feefeffe feefeffe
3ffff2c0:  feefeffe feefeffe feefeffe feefeffe
3ffff2d0:  feefeffe feefeffe feefeffe feefeffe
3ffff2e0:  feefeffe feefeffe feefeffe feefeffe
3ffff2f0:  feefeffe feefeffe feefeffe feefeffe
3ffff300:  feefeffe feefeffe feefeffe feefeffe
3ffff310:  feefeffe feefeffe feefeffe feefeffe
3ffff320:  feefeffe feefeffe feefeffe feefeffe
3ffff330:  feefeffe feefeffe feefeffe feefeffe
3ffff340:  feefeffe feefeffe feefeffe feefeffe
3ffff350:  feefeffe feefeffe feefeffe feefeffe
3ffff360:  feefeffe feefeffe feefeffe feefeffe
3ffff370:  feefeffe feefeffe feefeffe feefeffe
3ffff380:  feefeffe feefeffe feefeffe feefeffe
3ffff390:  feefeffe feefeffe feefeffe feefeffe
3ffff3a0:  feefeffe feefeffe feefeffe feefeffe
3ffff3b0:  feefeffe feefeffe feefeffe feefeffe
3ffff3c0:  feefeffe feefeffe feefeffe feefeffe
3ffff3d0:  feefeffe feefeffe feefeffe feefeffe
3ffff3e0:  feefeffe feefeffe feefeffe feefeffe
3ffff3f0:  feefeffe feefeffe feefeffe feefeffe
3ffff400:  feefeffe feefeffe feefeffe feefeffe
3ffff410:  feefeffe feefeffe feefeffe feefeffe
3ffff420:  feefeffe feefeffe feefeffe feefeffe
3ffff430:  feefeffe feefeffe feefeffe feefeffe
3ffff440:  feefeffe feefeffe feefeffe feefeffe
3ffff450:  feefeffe feefeffe feefeffe feefeffe
3ffff460:  feefeffe feefeffe feefeffe feefeffe
3ffff470:  feefeffe feefeffe feefeffe feefeffe
3ffff480:  feefeffe feefeffe feefeffe feefeffe
3ffff490:  feefeffe feefeffe feefeffe feefeffe
3ffff4a0:  feefeffe feefeffe feefeffe feefeffe
3ffff4b0:  feefeffe feefeffe feefeffe feefeffe
3ffff4c0:  feefeffe feefeffe feefeffe feefeffe
3ffff4d0:  feefeffe feefeffe feefeffe feefeffe
3ffff4e0:  feefeffe feefeffe feefeffe feefeffe
3ffff4f0:  feefeffe feefeffe feefeffe feefeffe
3ffff500:  feefeffe feefeffe feefeffe feefeffe
3ffff510:  feefeffe feefeffe feefeffe feefeffe
3ffff520:  feefeffe feefeffe feefeffe feefeffe
3ffff530:  feefeffe feefeffe feefeffe feefeffe
3ffff540:  feefeffe feefeffe feefeffe feefeffe
3ffff550:  feefeffe feefeffe feefeffe feefeffe
3ffff560:  feefeffe feefeffe feefeffe feefeffe
3ffff570:  feefeffe feefeffe feefeffe feefeffe
3ffff580:  feefeffe feefeffe feefeffe feefeffe
3ffff590:  feefeffe feefeffe feefeffe feefeffe
3ffff5a0:  feefeffe feefeffe feefeffe feefeffe
3ffff5b0:  feefeffe feefeffe feefeffe feefeffe
3ffff5c0:  feefeffe feefeffe feefeffe feefeffe
3ffff5d0:  feefeffe feefeffe feefeffe feefeffe
3ffff5e0:  feefeffe feefeffe feefeffe feefeffe
3ffff5f0:  feefeffe feefeffe feefeffe feefeffe
3ffff600:  feefeffe feefeffe feefeffe feefeffe
3ffff610:  feefeffe feefeffe feefeffe feefeffe
3ffff620:  feefeffe feefeffe feefeffe feefeffe
3ffff630:  feefeffe feefeffe feefeffe feefeffe
3ffff640:  feefeffe feefeffe feefeffe feefeffe
3ffff650:  feefeffe feefeffe feefeffe feefeffe
3ffff660:  feefeffe feefeffe feefeffe feefeffe
3ffff670:  feefeffe feefeffe feefeffe feefeffe
3ffff680:  feefeffe feefeffe feefeffe feefeffe
3ffff690:  feefeffe feefeffe feefeffe feefeffe
3ffff6a0:  feefeffe feefeffe feefeffe feefeffe
3ffff6b0:  feefeffe feefeffe feefeffe feefeffe
3ffff6c0:  feefeffe feefeffe feefeffe feefeffe
3ffff6d0:  feefeffe feefeffe feefeffe feefeffe
3ffff6e0:  feefeffe feefeffe feefeffe feefeffe
3ffff6f0:  feefeffe feefeffe feefeffe feefeffe
3ffff700:  feefeffe feefeffe feefeffe feefeffe
3ffff710:  feefeffe feefeffe feefeffe feefeffe
3ffff720:  feefeffe feefeffe feefeffe feefeffe
3ffff730:  feefeffe feefeffe feefeffe feefeffe
3ffff740:  feefeffe feefeffe feefeffe feefeffe
3ffff750:  feefeffe feefeffe feefeffe feefeffe
3ffff760:  feefeffe feefeffe feefeffe feefeffe
3ffff770:  feefeffe feefeffe feefeffe feefeffe
3ffff780:  feefeffe feefeffe feefeffe feefeffe
3ffff790:  feefeffe feefeffe feefeffe feefeffe
3ffff7a0:  feefeffe feefeffe feefeffe feefeffe
3ffff7b0:  feefeffe feefeffe feefeffe feefeffe
3ffff7c0:  feefeffe feefeffe feefeffe feefeffe
3ffff7d0:  feefeffe feefeffe feefeffe feefeffe
3ffff7e0:  feefeffe feefeffe feefeffe feefeffe
3ffff7f0:  feefeffe feefeffe feefeffe feefeffe
3ffff800:  feefeffe feefeffe feefeffe feefeffe
3ffff810:  feefeffe feefeffe feefeffe feefeffe
3ffff820:  feefeffe feefeffe feefeffe feefeffe
3ffff830:  feefeffe feefeffe feefeffe feefeffe
3ffff840:  feefeffe feefeffe feefeffe feefeffe
3ffff850:  feefeffe feefeffe feefeffe feefeffe
3ffff860:  feefeffe feefeffe feefeffe feefeffe
3ffff870:  feefeffe feefeffe feefeffe feefeffe
3ffff880:  feefeffe feefeffe feefeffe feefeffe
3ffff890:  feefeffe feefeffe feefeffe feefeffe
3ffff8a0:  feefeffe feefeffe feefeffe feefeffe
3ffff8b0:  feefeffe feefeffe feefeffe feefeffe
3ffff8c0:  feefeffe feefeffe feefeffe feefeffe
3ffff8d0:  feefeffe feefeffe feefeffe feefeffe
3ffff8e0:  feefeffe feefeffe feefeffe feefeffe
3ffff8f0:  feefeffe feefeffe feefeffe feefeffe
3ffff900:  feefeffe feefeffe feefeffe feefeffe
3ffff910:  feefeffe feefeffe feefeffe feefeffe
3ffff920:  feefeffe feefeffe feefeffe feefeffe
3ffff930:  feefeffe feefeffe feefeffe feefeffe
3ffff940:  feefeffe feefeffe feefeffe feefeffe
3ffff950:  feefeffe feefeffe feefeffe feefeffe
3ffff960:  feefeffe feefeffe feefeffe feefeffe
3ffff970:  feefeffe feefeffe feefeffe feefeffe
3ffff980:  feefeffe feefeffe feefeffe feefeffe
3ffff990:  feefeffe feefeffe feefeffe feefeffe
3ffff9a0:  feefeffe feefeffe feefeffe feefeffe
3ffff9b0:  feefeffe feefeffe feefeffe feefeffe
3ffff9c0:  feefeffe feefeffe feefeffe feefeffe
3ffff9d0:  feefeffe feefeffe feefeffe feefeffe
3ffff9e0:  feefeffe feefeffe feefeffe feefeffe
3ffff9f0:  feefeffe feefeffe feefeffe feefeffe
3ffffa00:  feefeffe feefeffe feefeffe feefeffe
3ffffa10:  feefeffe feefeffe feefeffe feefeffe
3ffffa20:  feefeffe feefeffe feefeffe feefeffe
3ffffa30:  feefeffe feefeffe feefeffe feefeffe
3ffffa40:  feefeffe feefeffe feefeffe feefeffe
3ffffa50:  feefeffe feefeffe feefeffe feefeffe
3ffffa60:  feefeffe feefeffe feefeffe feefeffe
3ffffa70:  feefeffe feefeffe feefeffe feefeffe
3ffffa80:  feefeffe feefeffe feefeffe feefeffe
3ffffa90:  feefeffe feefeffe feefeffe feefeffe
3ffffaa0:  feefeffe feefeffe feefeffe feefeffe
3ffffab0:  feefeffe feefeffe feefeffe feefeffe
3ffffac0:  feefeffe feefeffe feefeffe feefeffe
3ffffad0:  feefeffe feefeffe feefeffe feefeffe
3ffffae0:  feefeffe feefeffe feefeffe feefeffe
3ffffaf0:  feefeffe feefeffe feefeffe feefeffe
3ffffb00:  00000000 00000000 00000020 40100f22
3ffffb10:  3ffe92f0 40104304 3ffefd44 feefeffe
3ffffb20:  00000001 40103523 3ffed470 feefeffe
3ffffb30:  40103986 feefeffe feefeffe feefeffe
3ffffb40:  feefeffe feefeffe feefeffe feefeffe
3ffffb50:  4010346a 0000007f 7fffffff 00000000
3ffffb60:  0000007f feefeffe feefeffe feefeffe
3ffffb70:  401022eb 00080000 00000020 40100f22
3ffffb80:  00000000 00000000 00000000 4000050c
3ffffb90:  3fffc278 40101fe8 3fffc200 00000022
3ffffba0:  3ffffbb0 00000030 00000008 ffffffff
3ffffbb0:  00000000 00000000 0000001f 40104bfd
3ffffbc0:  4000050c 3ffedf28 00000002 00008e88
3ffffbd0:  40226856 00000030 00000008 ffffffff
3ffffbe0:  4021744b 00000000 00000001 3ffec950
3ffffbf0:  00000002 00000000 3fffab2a 00000001
3ffffc00:  00000003 00020021 00000001 3fff02f8
3ffffc10:  00000000 00000000 0000001f 40104bfd
3ffffc20:  4000050c 00ffffff 0000003f 3ffeca10
3ffffc30:  40000f83 00000030 00000008 ffffffff
3ffffc40:  4020b372 00000023 3fffdcc0 3fffb452
3ffffc50:  0000003a 000000f1 000000b9 00000003
3ffffc60:  00000001 fffffffd 00000001 3ffeee88
3ffffc70:  00000000 00000000 0000001f 40104bfd
3ffffc80:  4000050c 00000000 40225077 00000001
3ffffc90:  40000e86 00000030 0000001f fffffffe
3ffffca0:  40000e86 00000023 00000002 00000010
3ffffcb0:  00000010 00000000 3fffdbc0 3ffe93a8
3ffffcc0:  00000000 3fffc6fc 00000002 00000000
3ffffcd0:  3ffed440 00000001 00000000 00000030
3ffffce0:  00000000 3ffed470 20110486 00000000
3ffffcf0:  ffffffff 3fffc6fc 00000000 3ffefd44
3ffffd00:  3ffed440 00000001 00000000 00000030
3ffffd10:  3fffb41c 00000000 00000020 40100f22
3ffffd20:  3ffe92f0 4020b391 3ffeee88 3ffefc74
3ffffd30:  3fffb452 0000003a 3ffed470 40100f22
3ffffd40:  0000000c 00000000 00000020 3ffef2e1
3ffffd50:  000005e0 00000000 40103125 3ffed470
3ffffd60:  0000003c 00000000 3fffb452 00000100
3ffffd70:  0000001c 00000001 4010426a 3ffed470
3ffffd80:  3ffed440 4010431f 00000000 3ffed094
3ffffd90:  00000005 00000000 00000020 40100f22
3ffffda0:  3ffe92f5 4010431f 3ffecd80 40100f22
3ffffdb0:  40101c3d 3ffecd80 3ffefd44 40100f22
3ffffdc0:  00000023 61c7d6c4 3ffed750 40101e0e
3ffffdd0:  3ffe9b70 00000000 00000000 40100f22
3ffffde0:  00000023 61c7d6c4 4010224e 00000100
3ffffdf0:  7fffffff 3ffe9b70 3ffe9b70 00000001
3ffffe00:  00000001 00000040 3ffed750 40101e0e
3ffffe10:  3ffe9ba0 61c7d6c4 00000000 4000050c
3ffffe20:  3fffc278 40101fe8 3fffc200 00000022
3ffffe30:  3ffe9bac 3ffe9ba0 3ffe9ba0 00000001
3ffffe40:  40204bf3 00000030 00000010 ffffffff
3ffffe50:  40204bf3 00000001 00000001 00000000
3ffffe60:  00000000 00000000 00000000 fffffffe
3ffffe70:  ffffffff 3fffc6fc 00000001 00000064
3ffffe80:  3ffeebc8 3ffeeb98 3ffeec60 00000030
3ffffe90:  40204b9b 00000000 3ffeee68 00000000
3ffffea0:  00000000 00000000 00000000 fffffffe
3ffffeb0:  ffffffff 3fffc6fc 00000001 00000000
3ffffec0:  00000000 3fffdad0 3ffeed20 00000030
3ffffed0:  00000000 00000000 00000001 3ffeed18
3ffffee0:  00000000 3fffdad0 3ffeed20 00000030
3ffffef0:  ffffffff 3fffc6fc 00000001 3ffeed18
3fffff00:  00000000 3fffdad0 3ffeed20 00000030
3fffff10:  00000000 3fffdad0 3ffeed20 00000030
3fffff20:  3ffeeb98 3ffeebc8 3fffff60 401006dc
3fffff30:  3ffeeb98 3ffeec60 40204b0c 40204734
3fffff40:  4020158e 00000000 3ffeed18 40204f14
3fffff50:  3ffeeb98 3ffeebc8 3ffeed18 40202b38
3fffff60:  00000000 00000000 00000000 0106a8c0
3fffff70:  00000000 00000000 00000000 00000000
3fffff80:  00000000 3ffeec14 3ffeec60 40202a43
3fffff90:  40205198 6407a8c0 00000000 3ffeed20
3fffffa0:  00000000 00000000 00000001 40204b2d
stack

last failed alloc call: 3FFED93C(192)

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
vbb28d4a3
~ld

Update 2: It isn't only the first middleman (chip no.1) which crashes, now it happened to be the second one (chip no.4)

Are you sure it's not receiving, and not that the whole chip has crashed? What attempts at debugging it have you made?

can you use ESP-NOW instead of wifi? it's a lot faster/more stable for ad-hoc p2p

@dandavis I can't use ESP-NOW, because the project requires more abilities to control the system (I'd like to explain the project but it's way too big already). The chain reaction (sending) works fine for like 20 min. tho which is kinda weird

@Majenko I'll try to hook all up and wait until it "crashes" (takes around 20 min.). Sending info tomorrow

would rebooting every 15 mins cause too much downtime?

I have LEDs installed, to see "where the message is at" when it's being send. I have the LED connected to PIN 13 which is  "UART0 also has hardware flow control on pins 15 and 13 (RTS0 and CTS0 resp.). These two pins can also be used as alternative TX0 and RX0 pins." https://tttapa.github.io/ESP8266/Chap04%20-%20Microcontroller.html , going to change it to an unused one

@dandavis the project applies to many fields, and in certain circumstances it should go down every 6 hours. Plus I'm also not aware, if the ~20 min. are a safe time, maybe it could go down after 5 min.. I'm trying something out right now, giving feedback tomorrow

there are hardware watchdog timers, or maybe software is enough, if you find the hanging timeout consistent.

@Majenko So when no.1 sends a message, no.2 doesn't seem to handshake or respond to the sent message, which then results into no.1 having problems to go on int the code. After that no.2 actually crashed... going to hook it up to a serial monitor, maybe I can find out more.

Next thing I'll try is changing all the 'delay()'s inside the code and use millis() for timing instead

do you know about https://github.com/me-no-dev/EspExceptionDecoder ? it will give you the actual line number of your code where the problem occurs. When things go bad for more than 5 mins, it's time to bust it out...

@dandavis Took me a while to get it installed, but what I received was "Decode failed"

you might have to restart your IDE or possibly reflash the ESP with a higher debug level, but the data you pasted looks like the info it needs (the first few lines, not the raw ram dump)

I couldn't get that Exception Decoder to work, guess I'm to stupid for that. But what I've noticed now is, that when I only use 3 chips (so only one middleman instead of 3), it doesn't crash nor slow down

@dandavis I found the solution but still I'm thankful that you've tried to help me (posted as an answer). Have a nice day

I've swapped through 25 ESP8266-12 chips hoping I just had bad luck when receiving these things. I also tried changing the baud-rate, which resulted into some chips becoming a so called "brick" (don't set the baud-rate to 9600, or else you will have to flash them again). Changing the power supply wasn't helpful too. I tried to see if this was caused by a memory leak, so I included the method ESP.getFreeHeap() and printed the results. They didn't seem suspicious at all.
What I think did the trick was to put a delay(1) at the end of the loop and reduce the time interval of messages being sent from five seconds to one. For now this seems stable and reliable.
Update: I changed the delay(1) to the method yield(). As the ESP8266 runs a lot of utility functions in the background (keeping WiFi connected, managing the TCP/IP stack, and performing other duties) blocking these functions from running can cause the ESP8266 to crash and reset itself. To avoid these mysterious resets, avoid long, blocking loops in your sketch. Blocking loops can be for example sending messages with the TCP/IP.
Still delay(1) also worked for me because delays don't "freeze" the chip completely. There are multiple layers, some which are reachable for us and some which are not (keeping WiFi connected etc.), so delay() has a similar outcome as yield(). You can even find yield() in the delay() method in wiring.c.
void delay(unsigned long ms)
{
    uint32_t start = micros();

    while (ms > 0) {
        yield();                       //<-------
        while ( ms > 0 && (micros() - start) >= 1000) {
            ms--;
            start += 1000;
        }
    }
}

But to set a delay() one needs to know how long it has to be so the duties get finished in time. yield() on the other hand pauses reading the script until the background duties are finished (that doesn't take too long).
Editing your script so that the chip keeps executing the yield() method often enough per run fixed it for me.


text:
If a condition is ever met I want to run a loop permanently
I am trying to run an LED to do SOS in morse code if a temperature is over 20 C and motion is detected, but I want it to continue doing SOS even after the motion goes away or the temperature comes down.
Right now it simply does SOS 1 time and stops.
(sorry if coding is messy)
   int counter;
   int motion = 0;

   void setup()
  {

    {Serial.begin(9600);
     pinMode(4, INPUT);
     pinMode(0, OUTPUT);
     pinMode(2, OUTPUT);
     pinMode(1, INPUT);
     digitalWrite(0, HIGH);

     }
  }

    void loop()
   {

   int sensorA0Value = analogRead(A0);
   float voltage = sensorA0Value * (5.00 / 1023.00);
   Serial.print("Voltage: ");
   Serial.print(voltage);

   float temp = (voltage -.5)*100;
   Serial.print("| Temp: ");
   Serial.print(temp);
   Serial.println(" Celcius|");

   motion = digitalRead(4);

   if(motion == HIGH)
    {Serial.println("Motion Detected");}
   if(motion == LOW)
     {Serial.println("No Motion");}

   if(motion == HIGH && temp > 30)
     {
     digitalWrite(2, HIGH);
     delay(300);
     digitalWrite(2, LOW);
     delay(300);
     digitalWrite(2,HIGH);
     delay(300);
     digitalWrite(2, LOW);
     delay(300);

     digitalWrite(2, HIGH);
     delay(600);
     digitalWrite(2, LOW);
     delay(600);
     digitalWrite(2, HIGH);
     delay(600);
     digitalWrite(2, LOW);
     delay(600);
     digitalWrite(2, HIGH);
     delay(600);
     digitalWrite(2, LOW);

     delay(600);
     digitalWrite(2, HIGH);
     delay(300);
     digitalWrite(2, LOW);
     delay(300);
     digitalWrite(2,HIGH);
     delay(300);
     digitalWrite(2, LOW);
     delay(300);
     digitalWrite(2,HIGH);
     delay(300);
     digitalWrite(2, LOW);
     delay(1000);

   }
     else {
     digitalWrite(2, LOW);

     }
   delay(1000);
    }

You could use a while-loop like this:
if(motion == HIGH && temp > 20) {
  while(true){
   SosMethod();
   }
}

to clean everything up, then outside your void loop() you declare your SOSMethod()
void loop() {
 ... .
 }

 void SosMethod(){
 your-led-code-with-delays
 }

This may be unrelated to the actual question but... your Morse timings
are completely messed up. The standard timings are:
element         duration
------------------------
dot                 1
dash                3
interelement gap    1
intercharacter gap  3
interword gap       7

where the time unit is the duration of a dot. A correctly timed SOS can
be implemented as follows:
const uint32_t DOT_TIME = 150;  // 8 words per minute

void dot() {
    digitalWrite(2, HIGH);
    delay(1 * DOT_TIME);
    digitalWrite(2, LOW);
    delay(1 * DOT_TIME);
}

void dash() {
    digitalWrite(2, HIGH);
    delay(3 * DOT_TIME);
    digitalWrite(2, LOW);
    delay(1 * DOT_TIME);
}

void send_sos() {
    dot(); dot(); dot();
    dash(); dash(); dash();
    dot(); dot(); dot();
    delay(6 * DOT_TIME);  // interword gap
}

Notice that there are no intercharacter gaps within SOS, as this is a
procedural signal, transmitted with no letter boundaries. It
is not a three-letter word. The last delay is written as
6 * DOT_TIME as there is already a one DOT_TIME delay at the end of
the function dot().

It seems this is your SOS code:
if(motion == HIGH && temp > 30)
{
 digitalWrite(2, HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);
 digitalWrite(2,HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);

 digitalWrite(2, HIGH);
 delay(600);
 digitalWrite(2, LOW);
 delay(600);
 digitalWrite(2, HIGH);
 delay(600);
 digitalWrite(2, LOW);
 delay(600);
 digitalWrite(2, HIGH);
 delay(600);
 digitalWrite(2, LOW);

 delay(600);
 digitalWrite(2, HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);
 digitalWrite(2,HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);
 digitalWrite(2,HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(1000);
}

Step 1: I think you want to send the first S (.-.-.-.-) as 3 sequences instead of 2 sequence, so the code is:
if(motion == HIGH && temp > 30)
{
 digitalWrite(2, HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);
 digitalWrite(2, HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);
 digitalWrite(2,HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);

 digitalWrite(2, HIGH);
 delay(600);
 digitalWrite(2, LOW);
 delay(600);
 digitalWrite(2, HIGH);
 delay(600);
 digitalWrite(2, LOW);
 delay(600);
 digitalWrite(2, HIGH);
 delay(600);
 digitalWrite(2, LOW);

 delay(600);
 digitalWrite(2, HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);
 digitalWrite(2,HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);
 digitalWrite(2,HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(1000);
}

Step 2: Reduce the duplicate code (each 6 sequences of digitalWrite and delay), you will get:
if(motion == HIGH && temp > 30)
{
  send(300);
  send(600);
  send(300);
  delay(1000);
}

void send(int delayTime)
{
   for (length = 0; length < 3; length++)
   {
      digitalWrite(2, HIGH);
      delay(delayTime);
      digitalWrite(2, LOW);
      delay(600);
   }
}

Than you want to fix your problem to keep it sending
Instead of
if(motion == HIGH && temp > 30)
{
  send(300);
  send(600);
  send(300);
  delay(1000);
}

Use
while ((motion == HIGH) && (temp > 30))
{
  send(300);
  send(600);
  send(300);
  delay(1000);
}

For easy reading, I always use parenthesis around equal conditional operator (like ==, >).
The variables motion and temp will not be changed in the while loop, so you can use a while here. It is assumed that the variables are not changed in an interrupt.

In this instance, while (condition) is indeed equivalent to if (condition) while (true). The later, however, clearly exposes the intent of the programmer, whereas the former is very likely to cause confusion.

source: Stack Exchange

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

sort: votes


text:
Understanding analog pins in pinMode
When passing the pin number in pinMode its possible to use A0 - A7, does it apply only to that methode?
How can pinMode expect a number (is it int?) type in case of digital pin another (is it then string?) in case of analog pin?
I want to use that in my class methode, is there a way to use that and have my code more readable or should I use the pin numbers?
P.S. I have tried to read the source code but I don't understand the uin8_t (I know its a byte, but not how it can understand A5 as an int)
Tnx a lot

pinMode is actually declared as void pinMode(uint8_t, uint8_t);  in arduino.h
A0 is a defined as a number (somewhere depending on the actual hardware), on an Uno/Nano it translates to 14, and when executing pinMode it translates to the appopriate bit in the correct DDRx register.

On an atmega328 Arduino pin 14 ( or A0 ) is directed to PORTA bit 0, which can be used as a digital I/O or alternatively as an ADC channel.

The ATmega328 doesn't have a port 0. pin 14 (A0) is PC0.

Correct: PORTC Bit 0  Thanks.   In the DIP28 atmega328P-PU its Pin 23

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


text:
Getting at the PS_ON pin on a RAMPS1.4 mounted to a Mega
Got it! Check end of post for solution.
I'm running a Mega 2560 with a RAMPS 1.4 Shield which is usually used for 3D printing applications. For my use case I only want to get at the stepper motor drivers. The RAMPS is pulling its own 12V power supply (using an old xbox 360 brick rated for 12V and have tested with a multimeter) and the Arduino is pulling 5V from an RPI. But for some reason I seem unable to get the stepper motor A4988 drivers to pull anything from the 12V power supply. The LED on the RAMPS turns on, and the stepper drivers are pulling a little power (also tested) but obviously not enough to get them to make the motors turn. In other words, the RAMPS isn't using the external power supply.
I'm NOT using any of the 3D printer firmware like Marlin since it can't compile on Raspbian and I only want to get at the Stepper Motor Drivers and now in my case the PS_ON pin...
Here's the schematic:

My code for trying to get the motors to turn (and flip the PS_ON switch) is as follows:
int PS_ON = 12;
int X_STEP_PIN = 54;
int X_DIR_PIN = 55;
int X_ENABLE = 38;
int NUM_OF_STEPS = 400;
int WAIT_TIME = 500;
int LED_PIN = 13;

void setup(){

  digitalWrite(LED_PIN, HIGH);

  delay(2000);

  pinMode(PS_ON, OUTPUT);

  delay(20000);

  pinMode(X_DIR_PIN, OUTPUT);
  pinMode(X_STEP_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(X_ENABLE, OUTPUT);

  digitalWrite(PS_ON, LOW);
  digitalWrite(X_ENABLE, LOW);

  digitalWrite(X_DIR_PIN, HIGH);
  for(int n = 0; n < NUM_OF_STEPS; n++){
    digitalWrite(X_STEP_PIN, HIGH);
    digitalWrite(X_STEP_PIN, LOW);
    delay(WAIT_TIME);
    digitalWrite(LED_PIN,!digitalRead(LED_PIN));
  }

  delay(3000);

  digitalWrite(X_DIR_PIN, LOW);
  for(int n = 0; n < NUM_OF_STEPS; n++){
    digitalWrite(X_STEP_PIN, HIGH);
    digitalWrite(X_STEP_PIN, LOW);
    delay(WAIT_TIME);
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
  }
}

void loop(){

}

Any thoughts would be appreciated.
Here's how I got it to work.
Firstly if you're going to use a Xbox 360 PSU to power the RAMPS you need to tie together the red wire and the blue wire to force the box out of standby and make it give out a constant 12V (if you buy a 3rd party psu then the wire colors/layout will be different and you're on your own, but all the ones made by Microsoft for the base xbox 360 are color coded like this, including current Xbox One PSUs as far as I can tell).
There's also the option of connecting the blue to VCC and the red to GND on the RAMPS board (im not sure why that also works, but it's also mentioned in the docstring of the config.h or config_adv file under power supply settings in the Marlin firmware which is where I got the idea)
At that point, if you're reading 12V on a multimeter on the 5A rail of the RAMPS, make sure the RAMPS is able to power itself without the Arduino, if it can you should be good to go. There seems to be no need to get at the PS_ON at this point and you can power the RAMPS without any firmware.

Got it working without using any firmware, going to sleep. Will update post in the morning for how I got it working for anyone else with a similar question in the future.


text:
Controlling a button
I'm going to write a sketch that would light up the first LED (D1) of the training shield at the beginning, then move the LED light to the left or to the right whenever you press the S1 or S2 buttons, respectively. When the LED is already at the first (D1) or the last (D8), it should no longer move when going further to the left or right, respectively.
Looks exactly like this: https://www.youtube.com/watch?v=_KQQTdDMgOU
Here's what I made so far:
int x = 0;

void setup() {
  for(int i=11; i <= 18; i++) {
    pinMode(i, OUTPUT);
  }
}

void loop() {
  x = digitalRead(pushButtonPin);
  if (pushButtonState == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

What you made so far is only turn on and off LED according to button state. I believe there's more efficient code out there, but you can try:
int x = 11;

 void setup() {
 for(int i=11; i <= 18; i++) pinMode(i, OUTPUT); //assuming the led is on pin 11-18
 }

 void turnLED(int num)
 {
     for(int i=11; i <= 18; i++)
         if (num==i) digitalWrite(i,HIGH); else
                     digitalWrite(i,LOW);
 }

 void loop() {

    if (digitalRead(buttonRight))
    {
        x++;
        if (x>18) x=18;
    }
    else if (digitalRead(buttonLeft))
    {
        x--;
        if (x<11) x=11;
    }
    turnLED(x); //turn LED on according to value of 'x'
    delay(500);
}

You also need to add software or hardware debouncing to your button or else you will get multiple false button press for a single physical press of the button.

@AndreCourchesne theoretically the 500ms delay would handle this? (though a bit long), but I don't believe the button would keep bouncing for 500ms

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


text:
UART communication issue on Arduino Mega
I am using an MH-Z19 CO2 sensor with an Arduino Mega using UART. As per the specifications of this sensor, after we send a command, we expect the response in a particular 9 byte format (with starting bytes as 0xFF and 0x86).
byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
byte response[9];
Serial.flush();
Serial.write(cmd,9);
while (Serial.available()<9) {}
for(int n=0; n<9; n++) {
  response[n] = Serial.read();
}
if (response[0] != 0xFF) {
  //Error
  predictCo2 = 0;
} else if (response[1] != 0x86) {
  //Error
  predictCo2 = 1;
} else {
  predictCo2=((response[2]*256)+response[3]);
}

I wait till all the 9 bytes are filled in to read the values.
The problem here is that, when I turn the board ON, most of the times the response isn't in the required format (starting bytes aren't 0xFF or 0x86).
But, if I press the Arduino reset button, it starts reading values in proper format straight away.
I'm wondering why this is happening. Why is the UART response not in the proper format immediately after I turn on the Arduino, and I have to explicitly do a reset? Is the reset button clearing the serial stream? How can this be achieved through software?
I included serial.flush() before sending the command, but that didn't help either.

Sounds like a startup delay needed. See https://revspace.nl/MHZ19#Log_of_MH-Z19_response_at_startup.

Serial.flush() only empties the output buffer, so that won't achieve anything. Reading exactly 9 bytes and hoping they match the input stream is not very effective, as you found. If you are out of sync with the incoming bytes, you will stay out of sync.
It would be better to keep reading (single bytes) until you get 0xFF or 0x86 and then read the rest.

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


text:
Storing data on AT24C02 EEPROM chips with Arduino
I have recently come across some  8-pin 128-byte EEPROM chips. I've seen those USB EEPROM chip programmer units, but I was wondering if there is any way I could manually store data on the chip with my Arduino.
I don't have any application for the chips yet, but I would just like to see if I can read / write data on the chips.
Here's the data sheet for the chips.

Did you try googling the keywords "Arduino" with the name of the chip?

@gre_gor http://fritzing.org/projects/readwrite-serial-eeprom-via-i2c would this work?

Please edit your question and add the part numbers of the EEPROM chips.  Some chips have different specs than others.

@jwpat7 it's in the link i believe

Ok, I overlooked that link.  Still suggest editing the part number into title and question

@jwpat7 I did it

Ok, +1, but note that the AT24C02 is the 256-byte model rather than 128

You wire your chips on a breadboard, with the +/- left rail for Vcc/GND, and the right +/- rail for SCL/SDA, plus a little acrobatics to connect everything.
Your chips can have 8 addresses, 0x50 to 0x57, set up with the A0/1/2 pins: all low = 0x00, all high = 0x07. The you read and write to the EEPROM of your choice with:
char i2c_eeprom_read_char(int deviceaddress, unsigned int eeaddress) {
  char rdata = 0xFF;
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8)); // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.read();
  return rdata;
}

void i2c_eeprom_write_char(int deviceaddress, unsigned int eeaddress, char data) {
  int rdata = data;
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8)); // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.write(rdata);
  Wire.endTransmission();
}

If you have more than 8 chips (well throw them away and get larger ones, but anyway, for completeness sake): wire all of them with A1/A2 to GND, and each A0 to a different digital pin. When you need to access a chip, set all A0s to LOW, except the one you want to HIGH, and use 0x51 as the address. By doing this you're setting all chips except the one you want to address 0x50 (which doesn't matter) leaving only one at 0x51. That enables you to have as many chips as you have free digital pins...

When I use the I2C Scanner, I see 8 addresses 0x50..0x57with only one connected to the I2C bus, I have A0..A2+GND connected to ground (LOW). Any ideas? Before I had no connections made and saw this article so I thought this could be the solution but for me it is not. I can read the EEPROM and write it but only first 256 bytes.

A0/A1/A2 connected to ground means address 0x50. Do you have anything else connected to the I2C bus? Maybe write a question, explaining your setup. Easier than in comments.

Hi dda, there is nothing else on the bus. I posted a question yesterday about the capacity and the adresses on stackoverflow: https://stackoverflow.com/questions/47823243/can-read-write-eeprom-address-however-can-only-read-write-first-memory-page/47829869#47829869 About the capacity, read documention wrong, capacity is in bits and not in bytes so there is only 256 bytes available. Why manufacturers use bits instead of bytes to specify the capacity? All capacity is always measured in bytes, very confusing and explains my error.


text:
MCP23017 and stepper motors
I am new to Arduino and programming and I am muddling along with some tutorials, I have a little project I am working on. It's basically an LCD screen with 5 buttons, a simple menu system that will control some stepper motors.
Now I have been able to both program and run the LCD from the Arduino and program and run the stepper motors. This was pretty straightforward due to the abundance of information. Now due to the small number of inputs on the Uno I knew I would need to expand on these so I bought some MCP23017 I/O expander chips.
Setting up the LCD on the MCP23017 was easy enough again due to the lots of tutorials and libraries, but I just cannot figure out how to work a stepper motor via the MCP23017. I am using 28BYJ-48 stepper motors and ULN2003 stepper driver boards. Yes I know cheap and nasty but they are fine for my task.
So I am basically looking for a little help on how to run stepper motors through the MCP23017 chips. I have the wiring and connections set up, just need some help on the programming.

I couldn't understand what the problem is, since you already managed to connect an LCD to it... Anyway...
To run a stepper motor you have to first define the control technique. AFAIK there are a few, but the ones I know are

full step
rotated full step
half step
microstep

Your motor is a unipolar motor. You have to connect the common wire to +5V, the other ones to one transistor of the ULN2003, and each transistor should be directly controlled by one pin. These are called phases (and let's call these PH1, PH2, PH3 and PH4).
Now for the explanation I'll use some tables. In these tables, each row is a step, each column a pin, and if there is a X the transistor should be on during that step.
Now, the full step technique is the simplest one. It consists of four phases:
Step PH1 PH2 PH3 PH4
  1   X
  2       X
  3           X
  4               X

As you can see, you just have to power each phase through each step. Cycling the steps as 1-2-3-4-1-2-3... will rotate in one sense, 4-3-2-1-4-3-2... in the other.
The rotated full step technique powers two phases at each step:
Step PH1 PH2 PH3 PH4
  1   X   X
  2       X   X
  3           X   X
  4   X           X

This usually gives a higher current consumption, but also higher torque.
The half step is a mix of the two:
Step PH1 PH2 PH3 PH4
  1   X
  2   X   X
  3       X
  4       X   X
  5           X
  6           X   X
  7               X
  8   X           X

As you can see, the number of steps per cycle is twice as much. This means that you can increase the accuracy (since a 32 steps/rev motor will now require 64 steps to perform a complete revolution).
The microstepping technique requires a different hardware, since it better controls the current in the phases to further divide each step in different steps.
Anyway, a basic implementation using the MCP23017 and the full step technique can be this one. I used Adafruit's library, but you can change using whatever library you chose or the direct calls you used for the LCD.
#include <Wire.h>
#include "Adafruit_MCP23017.h"
Adafruit_MCP23017 mcp1;

const byte PH1 = 0, PH2 = 1, PH2 = 3, PH3 = 4;

const byte phasesTable[][] = {
    { HIGH, LOW,  LOW,  LOW  },
    { LOW,  HIGH, LOW,  LOW  },
    { LOW,  LOW,  HIGH, LOW  },
    { LOW,  LOW,  LOW,  HIGH }
    };

int currentPosition, targetPosition;
unsigned long previousMillis;
const int StepDelayMs = 100; // delay between steps

void setup()
{
    mcp1.begin(0);
    mcp1.pinMode(PH1, OUTPUT);
    mcp1.pinMode(PH2, OUTPUT);
    mcp1.pinMode(PH3, OUTPUT);
    mcp1.pinMode(PH4, OUTPUT);
    currentPosition = -1; // force first update
    targetPosition = 0;
}

void loop()
{
    void updatePosition(); // function prototype
    updatePosition(); // execute the update

    // ----------------------
    // Functional part
    // ----------------------
    // Edit this code according to your application
    // changing the targetPosition variable (DON'T CHANGE
    // the currentPosition variable

    if (currentPosition == targetPosition)
    {
        if (targetPosition == 50)
            targetPosition = 0;
        else
            targetPosition = 50;
    }
}

void updatePosition()
{
    if ((millis() - previousMillis) > StepDelayMs)
    {
        previousMillis += StepDelayMs;

        if (targetPosition != currentPosition)
        {
            if (targetPosition < currentPosition)
                currentPosition--;
            else
                currentPosition++;

            byte phIdx = currentPosition % (sizeof(phasesTable) / sizeof(phasesTable[0]));

            mcp1.digitalWrite(PH1, phasesTable[phIdx][0]);
            mcp1.digitalWrite(PH2, phasesTable[phIdx][1]);
            mcp1.digitalWrite(PH3, phasesTable[phIdx][2]);
            mcp1.digitalWrite(PH4, phasesTable[phIdx][3]);
        }
    }
}

NOTE: I did not test this code, but I'm pretty confident it should work. Maybe there are some bugs left, however, but you should be able to correct them yourself.
The program behaves this way: every 100ms (you can go a bit faster, but sometimes you can lose steps, so you have to test it) it checks if the motor has reached the final position he needs to reach (targetPosition). If it has, the program does nothing. Otherwise it moves one step towards the target. All this is managed in the updatePosition function.
You have to call this in the loop (and make a NON BLOCKING loop, otherwise also the motor will block). In the loop, modify the target position that you need to reach (the part I called Functional part). In the example, the program moves the motor 50 steps back and forth (so 50 steps in one direction, then back to the origin, then to 50 and so on).
The control technique used is the full step. If you want to use another, change the phasesTable constant variable.
If you need more functionalities, there are a lot of libraries for the steppers. Just use the proper commands to edit the pins on the MCP rather than the ones on the board.


text:
Linux IDE 1.0.6 & Nano: Problem with if statement
This is a basic battery monitor for a solar-powered control box.  It keeps the solar panels tracking the sun.
The Arduino monitors the voltage on the battery and turns on an AC-powered battery charger if the voltage drops too low.
It works, but there is an odd quirk.

Actual code is posted here. Too long to post and it does a bunch of other stuff that can be distracting.

One simple if statement isn't executing, as described below and shown on the plot.

HERE IS THE KEY CODE SEGMENT WHERE THE FAILURE OCCURS:
if (vind < vTriggerOn) {    // Batt low, turn on charger
  digitalWrite(powerPin,LOW);
  digitalWrite(powerPin2,LOW);
  vAC=17.0;
  }
if (vind > vTriggerOff) {   // Solar panels on, turn off charger
  digitalWrite(powerPin,HIGH);
  digitalWrite(powerPin2,HIGH);
  }

//  HERE IS THE PROBLEM :  THIS ONE DOESN'T EXECUTE
if (vind > 15.5) {vind=15.48; vin=15.48;}

This is followed by yet another if statement that works.
Problem:  That if statement in question is supposed to keep it from going off-scale above the top of the plot.  Yet it is not executing.

The two gray lines show that it is detecting the on and off triggers, but the voltage is going off the top.  This should be impossible.
The first two if statements are executing but the third one is not.

Considered the fact that I hadn't upgraded the Arduino IDE since first installation.  It is "Arduino 2:1.0.6:dpsg2-4"
Tried this:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install arduino

and it told me I had the latest version.

Question:  How can I make it execute that third if statement?

Not sure why about that.  But the plot tells the story.  You can see it trigger at the voltage points by drawing vertical gray lines, and the voltage runs off the top of the plot even though that one statement should hold it to just under the plot boundaries.  I know this is not a big deal, but it is worrisome..

There is absolutely no problem with multiple if statements. How do you know that the third one doesn't "execute"? Maybe "other stuff..." is the problem.

I've noticed that when I have too many if statements, they may or may not work.  absolutely not. You have a bug in code you haven't shown us. If the gcc compiler sometimes didn't execute "if" statements the world would grind to a standstill because of the amount of code that uses it.

And 3 is hardly too many. Try 100,000.

This is hard to believe, and it would be a very serious bug. Could you please post somewhere the exact source code that causes the problem, together with the generated .elf file? And also tell us what versions are you using. Raspbian Stretch? The Arduino IDE that comes packaged with it? Version of avr-gcc? I would like to disassemble your .elf and compare with what I compile myself on Raspbian Stretch.

Nick, you are right.  It was indeed "other stuff" - having nothing to do with my source code.

The program you posted does not compile. I did the minimal fixes to make it compilable, then compiled it on an up-to-date Raspbian stretch (arduino-core 1.0.5, gcc-avr 4.9.2) and ran it on an Uno. It works as expected. It seems you misdiagnosed your problem. My guess is you had some issue in your code, which is not in the part you showed us. Either you fixed the bug when upgrading the IDE, or it just stopped manifesting itself (this can happen when you have undefined behavior). Then you wrongly blamed the Arduino IDE.

If the version packaged with Raspbian miscompiled code, that would certainly matter. But you show no evidence of such a thing.


text:
How can I seriously calibrate ADC voltage readings with Arduino Nano?
I have been using Arduino Nano Analog input to measure voltages, in the range between 22-30 Volts.
I want to measure it down to a tenth of a volt.
Following the instructions found here:
Read Analog Voltage (www.arduino.cc)
Which basically states that all I need is this code:
int sensorValue = analogRead(A0);
float voltage= sensorValue * (5.0 / 1023.0);

5.0/1023 = 0.004888 volts per increment in analog readings.  Turning that around, voltage input divided by this value should give me the sensor value.
Clearly they are presuming an input of 0-5 Volts.
My voltage divider is 1 Mohm (R1) between the voltage input and A2, then 200K (R2) from A2 to ground
30 Volts measures as 4.2 Volts.  22 Volts measures as 3.1 Volts.
I think the range between 22 volts and 30 Volts doesn't present enough variation to the ADC - every single-digit change in the analogRead really make a big difference.
The result is that it is giving me some crazy readings.  It is definitely nonlinear, so I am having real trouble trying to get it to be accurate at both ends of my measurement range.  Each slight ADC increment makes too much of a difference in the measured voltage because I am not using the full 0-5V input range.
So I have been taking 10 readings in a row, at 500 ms intervals, then averaging.
And yet it is not working well enough.
(The biggest problem was the reference voltage and resolution were assumed to be 5/1024 which is completely incorrect.  Unless, as someone pointed out, I fed the Nanos directly at the 5V pin - which is still on the table - then it would be 5/1023)
I changed my resistor network to be 147K/23.5K
(Parts list:  1x 100K, 3x 47K)
R1 = 47K / 47K = 23.5K
R2 = 100K + 47K = 147K
Also added a 100uF 50V electrolytic across the input from the battery bank I am monitoring.
I am feeding 5V to Vin.  And have figured out that the reference is measurable on the 5V pin, after the regulator, as 4.6V.
Knowing that
Resolution/Vref = ADC/Vin
I turned that around to be
Vin = ADC * (Vref/Resolution)
Or, Vin = A2 * (4.6/1023)
Using a laboratory power supply I was able to confirm that with those settings 22 Volts came in at 3 Volts, and 29.98 came in right at 4 Volts.
So
Vbat = A2 * (4.6/1023) / (R2/(R1+R2))
Vbat = A2 * (4.6/1023.0)/(147000/170500)
It is now operating reasonably well.

(Yellow means the inverter is on)
--UPDATE--
  Changed resistors to 100K/20K for the divider and brought power to the 5V pin, bypassing the regulator for a reference.  It measures at 5.02 and is stable.
Results:
Charge controller meter says I am at 24.5 Volts.
Program says 24.64  (in the serial monitor).

--ADDENDUM:  I want to pursue the Op-Amp setup.  But if 741 won't work will need a suggestion.

Similarly, I went to 147K/47K for the 11-15 Volt circuit, and moved a higher-quality P/S over to the 5V pin, where it measures 5.03V; the results are better there, too. Just very slightly high.

So anyway, I'll put this to rest until I can figure out an op-amp circuit.
Thank you all for your help

You asked the question twice without a link to the other one, now we are answering to both without knowing each other answers. https://electronics.stackexchange.com/questions/307586/need-help-calibrating-adc-input-using-a-voltage-divider

If your power supply is 5volt you should connect it to Vcc directly, instead of Vin. If you connect to vin it first goes through the regulator, lowering the voltage.

Hello @Gerben.  By Vcc I assume you mean the 5V terminal.  I thought about that but since the Nano connects to a Pi I didn't feel safe having it unregulated.  The power supply is at least 5V, and no more than 5.1, and is regulated well enough for the Nano, for sure.  But I don't think it would be useful as the reference since it might wander some.  I am more comfortable trusting the regulator, especially since there have been Pi meltdowns at 5.15.

The nano can handle up to 6V. Giving a regulator too low a voltage makes it unable to regulate, and the voltage will flunctiate bases once the load. This fluctuation will also affect the ADC.

In my opinion, this is a very Arduino specific question.
First of all, you can't map 22-30V to 0-4.4V with a voltage divider (unless you have a negative voltage available). A opamp introduces a little more inaccuracy but can map the voltage which increases the accuracy. I suggest to first get the maximum out of the voltage divider. If that is not enough, then you can try a opamp.
The impedance of the circuit at a analog pin should be 10k or less for a accurate ADC conversion. You can add a small capacitor (1nF to 100nF) from the analog pin to GND, to keep the value stable during the ADC conversion.
The 5V VCC as a reference is a pain. The best option is to use an external voltage reference, for example a LM4040. The second best option is the internal voltage reference of 1.1V. That voltage is never 1.1V, and you have to determine the actual voltage. That 1.1V also depends on the temperature and a little on VCC.
Only 10 readings for an average is a small number. Sometimes I use 5, sometimes I use thousands.
Is the Arduino Nano used indoors, with only a small variation in temperature ? Then select the analogReference(INTERNAL). Use for example 10k and 270k for the voltage divider and 10nF parallel with the 10k. Use the average of 100 samples. An accuracy to measure the 24-30V with 0.1V resolution should be easy to achieve and 50mV resolution should be possible.
If you prefer the 1M to measure the voltage, you can also use 1M and 33k. With the 10nF parallel to the 33k, the ADC conversion is probably still accurate enough.
[ADDED] You have not told us yet how accurate you want to read the battery voltage. Is ±500mV okay, or must you have ±20mV ? I say it again: 0.1V resolution is easy. But it all depends on a good reference. A bad reference means even worse results. Dit you take a look at analogReference to see what the INTERNAL reference is about ?

The internal reference may even have better stability. Similar products using (I assume) the same or similar reference have temperature coefficients of 90 ppm or less.

Yes, you are right. The LM4040 that I mentioned is not the best. I prefer a good overall absolute accuracy, so it can be used right out of the box. The bandgap voltage of the reference of the ATmega328p can be 1.0 to 1.2 volts. With a lot of tuning and averaging it is still very useful.

You are right that it turned out to be a very specific-to-Arduino question after all.  It is inside.  Resolution can be within a tenth of a volt, or so.  Yes I looked at the reference and like the DEFAULT - 5V pin is a great touch point to verify it.  You said you sometimes take thousands - what interval can I use for the ADC to settle down in between readings if I wanted to take 100?

For normal noise reduction I don't use a delay at all. Just a for-loop with analogRead. Only when trying to eliminate the 50Hz or 60Hz mains noise, a delay might be needed.

I have .1uF in both ceramic and electrolytic. Also can build a 1147000/47000 divider with 1% parts to get 1.81 volts from 30.  Building it now.

Well I'll be a monkey's uncle.  Ref is measuring 1.04, and the capacitor is 0.1uF electrolytic.  Taking readings every second and they are as close as they can be.  24.8V is feeding 0.92 volts into A2.    After the math I am getting mostly 24.77, with some wandering - like from 24.5-24.9.  I think if I take 10 samples and average it will work.

So tomorrow we'll see how it does when the sun is out and it goes up to 29.2 - If it keeps working this well I'll duplicate this on the production system (which  is a lot more elaborate:  It includes undervolt protection relays and battery disconnects for inverter shutoff and automatic power switching back to house power from inverter)  Thank you VERY much, @Jot.

I just caught @Edgar's comment that the output resistance should be under 10K.  That probably explains the wandering.  Right now it only takes a single reading every minute so we'll just see how it goes.  Making that happen would require a two-stage voltage divider.

Rather than mapping to a range of 0 to 4.4 V, map to the range 0 to 1.1 V and use analogReference(INTERNAL) to select the internal band-gap 1.1 V reference source.  This reference voltage might vary a small amount as Vcc varies, but the variation is likely to be just a few millivolts.
To get your input voltage into the range  0 to 1.1 V, use a voltage divider and a voltage subtractor.  The voltage divider ratio should map the 8-volt range of 22 to 30 V to a 1.1 V range, ie, should have a ratio of 8:1.1, and should map 30 V to 4.125 V and 22 V to 3.025 V.
If you use a Unity Gain Differential Amplifier as described at electronics-tutorials.ws, the divider can use large resistors, ie, need not provide the under-10 KΩ resistance needed for ADC input; instead, the UGDA's low output impedance will meet that requirement when used as ADC input.  For example, you could have 1 MΩ in series with 160 KΩ for the main divider.
Feed that divided voltage into V1 in the diagram below.  Use a pot or another voltage divider to create a 3.025 V reference to feed into V2, perhaps based on the board's 3.3 V regulator output.
Note, use R1 = R2 = R3 = R4, with all of them some value like 10 KΩ or 20 KΩ.

Similar products using (I assume) a similar band-gap voltage reference have temperature coefficients of less than 90 ppm so the band-gap reference is probably the most accurate reference at hand.

I hadnt heard of that.

Changed resistors to 100K/20K for the divider

you probably want to read the datasheet about the impedance requirement on the source and potential solutions there.

Thank you for your answers and there is a lot of collective knowledge there.  It helped me find the way to stabilize and calibrate this system with what I had on hand.  The biggest problem was that the reference voltage and resolution were 5/1024, which is completely incorrect.
I changed my resistor network to be 147K/23.5K  (Parts list:  1x 100K, 3x 47K)
Also added a 100uF 50V electrolytic across the input from the battery bank I am monitoring.
I am feeding 5V to Vin.  And have figured out that the reference it is using is measurable on the 5V pin.
Knowing that Resolution / Vref = ADC reading / Vin, I turned that around to be Vin = ADC * Vref / Resolution.
(Can someone please edit that previous line so the equations look right?
I found out that the proper resolution is 1023, not 1024
Then by measuring the 5V pin I found 4.6 from the 12v-to-5v converter going through the regulator.  The 12 Volts is battery-backed and is very stable.
Vin = A2 * (4.6 / 1023)
Using a laboratory power supply I was able to confirm that with those settings 22 Volts came in at 3 Volts, and 29.98 came in right at 4 Volts.
Then I divided the Vin by (R2/R1+R2) to get the Vbat reading
Vbat = A2 * (4.6/1023) / (R2/(R1+R2))
Vbat = A2 * (4.6/1023.0)/(147000/170500)
You can see it better at
https://electronics.stackexchange.com/questions/307586/need-help-calibrating-adc-input-using-a-voltage-divider/307643#307643
It is now operating reasonably well.

(Yellow means the inverter is on)
Next step is to try 100K/20K for the divider and bring in 5V to the 5V pin, bypassing the regulator.
I want to pursue the Op-Amp setup.  But if 741 won't work will need a suggestion.  This setup I have been asking for measures a 500Ah 24 Volt deep-cycle Marine battery bank being charged by 6x 100W poly PV panels with a single-axis positioning system.
I now also need to measure exactly half the voltage, 11-15, for the positioning circuitry that has its own battery and dedicated 50 Watt panel to run the computer and motors.  The regulated 5V out there is el-cheapo but I now have the parts on hand to give it better 5V just like I have in here with the storage bank.  Should be able to finish that part today after church.   I expect the ADC will see half the voltage.  Instead of 3-4 Volts it should see 1.5-2 Volts.
Terrible loss of precision.  I really want both systems to see 0-4 Volts at the ADC.
So my question is still the same.  I think the answer is here.

Note that your resistance network has an equivalent output resistance of 20.3 kΩ, which is above the maximum recommended at an ADC input (10 kΩ). Note also that the ADC gain is 1024/Vref according to the manufacturer's datasheet. I measured it recently on an ATmega328P and found it to be more like 1026.1/Vref.

The 4.6V can not be a good reference voltage. Use the internal 1.1V.

https://meta.stackexchange.com/questions/216606/which-stack-exchange-sites-use-mathjax/216607#216607

OK, @Jot.  I am still getting nonlinear readings.  Up near 29.2 volts Boost charge it is OK, but it reads a bit high at 27.6 Float, then low near 25 Dark.  I am using a meter to calibrate the 5V terminal in the V/1023 part of the equation.  The supply voltage is stable, with about 50 Ah of battery behind it - it is not load-dependant.  The main battery bank being measured is  500 Ah of battery plus 600W solar (degraded by temps, of course)  and an MPPT controller.  I see how to set it to INTERNAL but do not know how to code for it.  Do I just use 5/1023 if I set it to INTERNAL?

Also, I am asking myself why I am using the 5V pin instead of AREF and EXTERNAL.  While I would love to use an op-amp to spread out the range, right now I am stuck with 3-4 Volts to represent 20-30 Volts, using 100K/20K as my divider.

I already had a link in my answer: https://www.arduino.cc/en/Reference/AnalogReference Select the INTERNAL and adjust the voltage divider for the lower voltage. You have to measure the actual voltage for each Arduino board that uses it, since it can be between 1.0 and 1.2 volt. Select INTERNAL and measure the AREF pin with a multimeter. Put that voltage in the calculation. The calculation uses 1.1V instead of 5V: float voltageAtPin = float( analogRead(A0)) * 1.1 / 1024.0 Keep in mind that trying to get a full range with many components might be less accurate then settling with a lower range.

Turns out @Jot was absolutely correct.  See the comments under his answer for the right way to do this.  analogReference(INTERNAL) and a voltage divider that brings 30 Volts down to 0-1.2 volts (1147000/47000)  with a .1uF Electrolytic across the input.  Run it once to set it up, then  measure REF for use in the Vref/1024 portion of the equation.  It works great.  The only glitch is that the very first reading is wrong, so I put three analogReads into setup, since my Rpi program resets the Nano as it begins recording readings.

Use a ceramic capacitor. A electrolytic or tantalum capacitor leaks, and make the voltage divider useless.


text:
Using ESP8266-01 via Arduino(no flash) without AT commands(using serial monitor)
I'm trying to build a smart Keychain using Arduino uno wifi(org, so Im using it like it's Arduino uno), ESP8266-01 And neo6m GPS device.
My esp8266 wasn't new, and it came without AT firmware. I flashed it so it could have AT commands but it's not completely working.
Anyway, the flash is using 115200 baud and I'd like to use serial monitor to communicate it using arduino(and blynk app).
Is there a way could I do it without flashing the esp for 9600 baud rate?
Thanks!

What do you mean? How can I use it? My Arduino uno wifi board is Arduino.org which means(I read online) that until Arduino won't provide proper TCP library I can't really communicate with it online

your information is obsolete. you can use it as any Uno with external esp8266 on SoftwareSerial. read the answer

Arduino Uno WiFi Dev Ed has the on-board esp8266 wired to additional Serial interface (I2C to Serial adapter). With UnoWiFiDevEdSerial1 library you can use the on-board esp8266 and have Serial free for Serial Monitor and sketch upload. The EspProxy tool enables upload to the on-board esp8266 over the ATmega (passing bytes between Serial and Serial1).
I am the author of the UnoWiFiDevEdSerial1 library.

The thing is, I'm not able to use this library in order to do exactly that. Maybe im not trying right, but I did try it, and my professor said I must use esp8266-01 module. I can't use it with software serial without reflashing because software serial is up to 9600 baud rate and my esp is using 115200 baud rate.

what did you try? AT firmware or WiFiLink or your own esp8266 sketch

Doing this exactly https://github.com/jandrassy/UnoWiFiDevEdSerial1

but that library is like SoftwareSerial. it is only the gate to esp8266

did you try WiFiLink firmware? with WiFiLink library it can Arduino networking like WiFi or Ethernet library

@MaorGorelik, did you solve it?


text:
How to connect NodeMCU to NRF24L01
I need to connect NodeMCU and NRF24L01. where I'm receiving data from another NRF24L01 Transmission. I managed to connect to a WiFi network but the data receiving is not taking place as expected. Here is my code
#include <SPI.h>
#include "RF24.h"
#include <ESP8266WiFi.h>

RF24 myRadio(7, 8);
const char* ssid = "******";
const char* password = "********";
struct package
{
    int id = 0;
    float longitude = 0.0;
    float latitude = 0.0;
    char text[100] = "empty";
};

byte addresses[][6] = {"0"};

typedef struct package Package;
Package data;

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

    Serial.println();
    Serial.print("Connecting");
    while (WiFi.status() != WL_CONNECTED)
    {
     delay(500);
     Serial.print(".");
    }
    Serial.println("success!");
    Serial.print("IP Address is: ");
    Serial.println(WiFi.localIP());
    myRadio.begin();
    myRadio.setChannel(115);
    myRadio.setPALevel(RF24_PA_MAX);
    myRadio.setDataRate(RF24_250KBPS);
    myRadio.openReadingPipe(1, addresses[0]);
    myRadio.startListening();
}

void loop()
{

    if (myRadio.available())
    {
        while (myRadio.available())
        {
            myRadio.read(&data, sizeof(data));
        }
        Serial.print("\nPackage:");
        Serial.print(data.id);
        Serial.print("\n");
        Serial.println(data.longitude);
        Serial.println(data.latitude);
        Serial.println(data.text);
    }
}

Any idea on why this is not receiving data as expected?. This somehow managed to connect to my WIFI successfully. Here are my pin connection

7, 8 should be pin numbers? io 5 to io 11 are internal flash memory QIO SPI pins. if you connected the module to D7, D8, use D7, D8 constants

Hi @Juraj I used D7 and D8. i have updated my question with an image of the pin connection

The Dx pin labels on NodeMcu and Wemos/Lolin boards do not correspond to esp8266 internal io pin numbers. The pins_arduino.h file in core defines Dx constants which map internal io numbers to Dx labels.
Use RF24 myRadio(D7, D8);


text:
Serial monitor doesn't work with piezo buzzer
So I can't see the distance of the proximity sensor anymore as soon as I type the code for the piezo buzzer. I've tried many things but it doesn't work.. Can anybody help me fixing this?
int trigPin = D7;
int echoPin = D8;
int BLUE = D3; //D3 zit in blauw
int GREEN = D4;
int RED = D5;
int piezoPin = D10;

void setup() {// deze code gaat maar 1 keer
  Serial.begin (115200);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
  pinMode(RED, OUTPUT);

}

void loop() { //code wordt steeds herhaalt
  long duration, distance;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH); // trig zendt een signaal uit
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH); // kijkt hoelang het duurt totdat signaal heen en weer gaat
  distance = (duration/2) / 29.1;
  // omdat het signaal heen wordt gezonden moet het door twee gedeelt worden
  // snelheid van geluid door lucht is circa 29 microseconden per cm dus gedeelt 29.

    Serial.print(distance);
    Serial.println(" cm");

//afstand wordt in cm weergegeven in serial monitor

  delay(500);

   if ((distance > 100) && (distance <= 150)){ //dit gebeurd er als de afstand vanaf sensor tussen groter dan 100 cm en gelijk aan of kleiner dan 150 cm is.
    analogWrite(BLUE, 0);
    analogWrite(GREEN, 255);
    analogWrite(RED, 0);

    tone(piezoPin, 1000, 1000); // toon duurt 1 seconden
    delay(2000); // 2 seconden geen geluid
    tone(piezoPin, 1000, 1000);
    delay(2000);

   }

   else if ((distance > 50) && (distance <= 100)){ //dit gebeurd er als de afstand vanaf sensor tussen groter dan 50 cm en gelijk aan of kleiner dan 100 cm is.
    Serial.println("Ga weg!");

    analogWrite(BLUE, 0);
    analogWrite(GREEN, 102);
    analogWrite(RED, 252);

    tone(piezoPin, 1000, 700); // toon duurt 0.7 seconden
    delay(1000); // 1 seconde geen geluid
    tone(piezoPin, 1000, 700);
    delay(1000);

  }

  else if ((distance >= 0) && (distance <= 50)){ //dit gebeurd er als de afstand vanaf sensor tussen groter dan of gelijk aan 0 cm en gelijk aan of kleiner dan 50 cm is.

    analogWrite(BLUE, 0);
    analogWrite(GREEN, 0);
    analogWrite(RED, 255);

    tone(piezoPin, 1000, 200); // toon duurt 0,2 seconden
    delay(100); // 0,1 seconden geen geluid
    tone(piezoPin, 1000, 200);
    delay(100);

  }

   else {
    analogWrite(BLUE, 0);
    analogWrite(GREEN, 0);
    analogWrite(RED, 0);

 }

}

I use a the NodeMCU

but there is no pin labeled D10 on NodeMCU

Can you explain what you have tried?

I have deleted some code and checked if anything was broken with my friend's code and redownloaded arduino

Pin D10 of NodeMcu is io 1 which is RX pin of Serial interface of the esp8266. Serial is on NodeMCU connected to USB. The pin is on board labeled RX.
D8 is boot config pin io 15. It must have pulldown on board. The pulldown can disturb the input on this pin. Use D6 (io 12) as echoPin.

I have changed the pin and it kind of works but not really good because it doesn't give the right distance it goes from 160 cm to 0 cm without moving anything...

but that is a different problem

D8 is io 15. it has a pulldown circuit on board. I don't know if it can disturb the measurement

I'm sorry but I don't know what io means. This is my first time programming with this program

try D6 (io 12) instead of D8

@TeddySmit, accept the answer to mark the question solved


text:
Slow serial communication with arduino and response on the application?
Currently, I'm doing a project as I want to use my Arduino Mega 2560 as an interface to my computer with a photo interrupter and stepper motor. So I need to send some commands and data to the Arduino from my PC. However, after upload the code to the board, I found out the serial communication of the Arduino quite slow. In fact, the moment after the code done uploading, my command in the Serial Monitor takes almost a second to execute. Below is the details about the code:-
    // Include the Arduino Stepper Library
#include <Stepper.h>

// Number of steps per output rotation
const int stepsPerRevolution = 200;

// Create Instance of Stepper library
Stepper myStepper(stepsPerRevolution, 12, 11, 10, 9);

int val;
int counter = 0;

void setup()
{
  // set the speed at 200rpm:

  myStepper.setSpeed(200);
  // initialize the serial port:
  Serial.begin(9600);
}

void loop()
{
  val = analogRead(A0);
  Serial.println(val);

  myStepper.step(stepsPerRevolution);
  counter = counter + 1;
  Serial.println(counter);

if (val > 200){
    Serial.println("it is running");

   } else {
    myStepper.setSpeed(0);
    Serial.println(counter);

   }

}

Any help so much appreciated.

so why not set a higher baud rate?

About a second between opening the serial monitor and the first response arriving? Yes. That's normal. That's called the bootloader executing. If you want faster then use a board that doesn't use a serial bootloader, or delete the bootloader and program the board with a hardware programmer.


text:
DIP switches on RobotDyn Uno+WiFi
There are theses 8 small pins on the Uno+WiFi board. Can someone please give me a detailed table or something on the settings of these 8 DIP switches?
I'm sorry if this question has already been answered somewhere else but I am bad at looking for stuff online.
Thanks

but the table is on the link you provided in previous question. CH340 is USB converter for connection to computer. https://robotdyn.com/uno-wifi-r3-atmega328p-esp8266-32mb-flash-usb-ttl-ch340g-micro-usb.html

Oh ok thank you very much I am sorry for the inconvenience caused here

There are 3 major chips on the board. Atmega 328, esp8266 and the USB converter CH340. Every device has one RX and one TX pin. But you need sometimes connect the Atmega to esp8266, sometimes connect the Atmega to computer over USB and sometimes connect the esp8266 to computer. The first 6 switches are in pairs (RX and TX) for connecting two of the 3 devices.

1,2 ON all others OFF connect esp8266 to Atmega. no connection to
computer.
3,4 ON all others OFF connects Atmega to computer over USB. no
connection to esp8266
5,6 ON all others OFF connects esp8266 to computer over USB. no
connection to Atmega

The switch 7 sets io 0 of esp8266 LOW which puts esp8266 to flashing mode at reboot. So you turn it ON with connection of esp8266 to USB (computer) to upload sketch to esp8266.


text:
How do I directly access a memory mapped register of AVR with C
Assume I want to write the following without using DDRD or PORTD:
#include <avr/io.h>
#include <util/delay.h>

int main(void) {
    DDRD = 0xFF;
    PORTD = 0xFF;
}

I found this link which includes a list of mapped registers to memory addresses:
https://github.com/DarkSector/AVR/blob/master/asm/include/m328Pdef.inc
So I replaced one of the keywords with a pointer:
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    DDRD = 0xFF;
    unsigned char *portd = 0x0b;
    *portd = 0xFF;
}

But it's not working (my LED isn't turning on with the second code). Why is that?

It might get optimized out, as it's not volatile. Or it's using wrong instruction to store data so it needs different address.

If you'd use unsigned char *portd = &PORTD; would your pointer work for port manipulation? That would lead to #2. 2. From here:
unsigned char * myportA = (unsigned char *) 0x003B; Of course, adjusted to your microcontroller. If that works for you, I lack of knowledge why would you need to cast it, but if passing the port name by reference works (#1) and direct assign using the hex doesn't, it has something to do with that. 3. Could declaring the pointer variable volatile help, in case something else modifies it?

what in this question is about Arduino?

It's worth exploring how PORTD is defined in the actual AVR header file.  The relevant file is iom328p.h, and it's defined as:
#define PORTD   _SFR_IO8(0x0B)

_SFR_IO8 is defined as
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)

and
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))

This shows that 0x0b is not the address of the PORTD register, but its offset from the address __SFR_OFFSET, which is 0x20.  Indeed, if you look at the ATMEGA328 datasheet, the register summary shows that PORTD is at offset 0x2b.  So that is the address that you would want to access via a pointer.
Note that this also shows the type of the pointer, if we fully expand the original definition of PORTD we get:
#define PORTD   _SFR_IO8(0x0B)
#define PORTD _MMIO_BYTE((0x0B) + __SFR_OFFSET)
#define PORTD _MMIO_BYTE((0x0B) + 0x20)
#define PORTD (*(volatile uint8_t *)(0x2B))

This syntax takes the integer 0x2B, casts it to type pointer to volatile uint8_t, and dereferences that pointer so you can assign to or read from the location the pointer references.  The volatile qualifier is important because it prevents the compiler from optimizing out accesses to memory.  Without it, the compiler may store the value to a register instead, or not store it at all, which would mean your IO port would remain unchanged or appear to report an incorrect value.
To go back to the title of your question, you have asked how to "directly access a memory mapped register in C", well the answer is you do that exactly the way the header file defines for you:
(*(volatile uint8_t *)(0x2B) = 0xFF

aka
PORTD = 0xff

There is no more direct way than this.  The compiler sees a literal address and writes to it.  What you've written is very different (adjusting to use the correct address and type:
volatile uint8_t * portd = 0x2b;
 *portd = 0xFF;

This allocates a location in memory symbolized by portd, which holds the value 0x2B.  When you write *portd = foo, the MCU has to access the location where portd is stored, take the value found there as an address to find the location you actually want to write to.  This method requires that you allocate a place in memory to hold portd and requires an extra memory access to be able to read or write to the port register.  This method is therefore indirect.
In reality, if optimization is enabled, the compiler may optimize the pointer away and replace it with the same literal access as in the PORTD case, however this depends on the program structure, and in particular the qualification and scope of the pointer.  Limiting the scope of portd as much as possible and/or declaring it as volatile uint8_t * const portd = 0x2b (which indicates that the pointer's value is constant even if the value pointed to is volatile) will increase the likelihood of the pointer being optimized away.

The reason the AVR headers define the IO port registers this way is because in addition to the standard load/store instructions that can access the entire data memory address space and take three clock cycles to complete, the IO registers are special, and can also be accessed using IN/OUT instructions, which complete in two cycles.  The load/store instructions use the memory address for the IO registers (starting at offset 0x20), whereas the IN/OUT instructions use the IO address, which starts at 0x00, but corresponds to 0x20 in the memory address space.  From the datasheet:

So when you access an IO location, the optimizer should recognize that it can issue a more efficient instruction than the standard load/store, and it will replace the load/store to 0x2b with an in/out to 0x0b.

Re “ This method requires that you allocate a place in memory to hold portd and requires an extra memory access”: Not really. It compiles to the exact same machine code as PORTD = 0xff.

It may get optimized to the same instructions, but the abstract C machine is instructed to do as I described and there is no guarantee that such optimization will take place.  It will depend on the scope of portd and optimization level, but in any case it's still not more direct than using the existing PORTD macro.

You may then want to make it clearer in your answer that by “the MCU” you mean the abstract C machine, not the actual MCU.

The behavior of the target must be equivalent to the behavior of the abstract machine; that's the whole point.  Accessing a literal address is only equivalent to accessing a dereferenced pointer in a limited subset of cases, therefore the compiler will issue instructions for pointer dereferencing unless it can determine that the literal access is equivalent.  Try different scopes and qualifications for portd and see what instructions are emitted.  In any case, it's worth mentioning the optimization, so I've added that to the answer.

Re “Try different scopes and qualifications for portd”: for the specific case of the question, it will be optimized away. There is no “may”. If you manage to coerce the compiler to store the pointer, I would love to see it, but it will will clearly be a very different code from the one in the question.

See: I have seen many beginners here who are prone to misguided micro-optimization attempts. Some are confused because they severely underestimate the compiler's ability to optimize. Never the contrary. Some avoid using variables for intermediate results under the misconception that they are reducing RAM consumption. Truth is they are only reducing program readability. Your explanations about the purported cost of the portd variable can only reinforce this misconception. Using intermediate variables is one of those cases where one should really trust the compiler to micro-optimize.

You're right, it is almost always best to let the compiler worry about optimizations like this. However, it is important to understand that in the two different cases you are telling the machine to do two different things, even if the syntax looks quite similar.  It's also important to understand how scope and qualification affects compiler behavior.  FWIW, when portd has global scope and is non-const, I still get pointer instructions at any optimization level with AVR-GCC 4.9.2.
Further discussion on this tangent should probably happen in chat.


text:
How to create a weather station with only GY-BME280-3.3 chip and w5100 Ethernet shield mounted over arduino mega 2560 r3
Want to create a weather station with only GY-BME280-3.3 chip and w5100 Ethernet shield mounted over Arduino mega 2560 r3 but I have no previous experience with Arduino. And The Arduino will be hooked up to a router using the Ethernet shield and powered using desktop USB connection or may be with the barrel jack and I want to control it using a GNU/Linux machine. So far I am trying to follow these
https://educ8s.tv/arduino-bme280-weather-station,
https://startingelectronics.org/tutorials/arduino/modules/pressure-sensor,
http://cactus.io/projects/weather/arduino-weather-station,
but none of these is an exact match for my setup, so a little confusing as a noob. But my questions is,
How to hook up the GY-BME280-3.3 sensor to the Arduino on which the Ethernet shield is already mounted?
EDIT:
So far I have connected the first 4 pins to the pins on the Ethernet on 1->3.3v, 2->gnd, 3->A5, 4->A4  or  1->3.3v, 2->gnd, 3->13, 4->11, 5->10, 6->12 but to no avail. Only 1+6->3.3v, 2->gnd, 3->21, 4->20 finds the sensor but reading is 0,0,0mb in that case and shows reading if SparkFun BME280 library is loaded.
Still the question is, if there any other pin combinations where I don't have to join 1+6 to a 3.3v, just one pin to 3.3v will be enough?

Yes, it can, and it can be accomplished by writing software for it. What have you tried so far?

I'm voting to close this question as off-topic because this is not a general project suggestion and hand-holding site. Try https://forum.arduino.cc/index.php?board=3.0

@Majenko, So far I am trying to follow these https://educ8s.tv/arduino-bme280-weather-station/,
https://startingelectronics.org/tutorials/arduino/modules/pressure-sensor/,
http://cactus.io/projects/weather/arduino-weather-station, but none of these is an exact match for my setup, so a little confusing as a noob. The ethernet is working but it shows that the sensor is not connected.

how did you connect the sensor?

@Juraj I have updated the question :)

I added to answer: CSB must be connected to VCC to select I²C interface.

You must decide if you want to connect the sensor over I2C or over SPI interface. According to datasheet of the sensor, at power-up pin CSB determines the interface. If CSB is pulled-down SPI is selected. CSB must be connected to VCC to select I²C interface.
On current revisions of Mega and Uno the 'standard location' of I2C pins SDA and SCL is near pin 13 after the Ground and AREF pin. Other location on Mega are pins 20 and 21. (A4 and A5 on Uno). Note that the 'standard location' pis are connected together with the 'numbered' pins, so you can't use 20 and 21 even if you connect the sensor to the standard location pins.
Pin SDO determines the I2C address of the sensor.
If you want to use SPI to connect the sensor to Mega, use SPI pins 50 to 52 and you can use pin 53 as CS (SS) pin. Ethernet shield uses pin 10 as CS for W5100 and pin 4 as CS for pin for the SD card. Note, that Ethernet shield connects to SPI bus on the ICSP header, but those are still SPI bus pins 50 to 52.
Adafruit has a tutorial for this sensor with wiring for Mega.


text:
Can I use an RF Receiver to any pin on an Arduino?
I have a project that uses a nodemcu and it includes an rf receiver, I created the pcb board already etc etc... so I've already chosen D7 (GPI013) before reading on connecting the rf receiver and found that a lot of people are saying to connect it to the interrupt pin and for the case of an Arduino it was pin 2 and for the nodemcu it's D3 (GPIO0).
UPDATE: the pin in question is the data pin for the rf receiver, this would be connected to D7 (GPIO13) because of the trace on the board. it is purely used for receiving the data it picks up and giving it to the nodemcu to handle.
Can I just use a different pin which in my example is D7 (GPIO13) or does it HAVE to be an interrupt pin?
Side note: I'm aware of the advantage of using an interrupt pin where that it takes priority over code running.

What does the pin do?  Is it used to notify the program that data is ready? if so, then you will have to poll that pin rather then take advantage of an interrupt, and this will be a bit slower, but I have no idea if that will effect your project since we dont know what your project is, or what that pin is even doing.

you did not say what is the purpose of the pin in question

you can hook it to the ESP, which can use any pin as an interrupt, and side-steps the middle man uno.

Thank you @dandavis how would I go about using D7 (GPIO13) as the pin interrupt in this case, when testing with the uno I would just define the enablereceiver as 0 which equals pin 2 on the board using RC Switch.


text:
Arduino button-controlled LED with AVR Assembly
I am trying to make a simple button-controlled LED, but I cannot seem to get any input from the button that would change the state of the LED. In other words, the program keeps branching to lighton, keeping the LED always on, regardless of the button state. I am using an Elegoo Uno R3.
Schematic:

Code:

.text
.global setup
.global loop

setup:
  ser r16
  sts DDRB, r16
  ldi r16, 0b00000000
  sts DDRD, r16
  ldi r16, 0b00100000
  sts PORTB, r16
  clr r16
  sts PORTD, r16

loop:
  lds r20, PORTD
  cpi r20, 0x00 ; PORTD always equal to 0x00 ?
  breq lighton
  clr r16
  sts PORTB, r16
  rjmp loop
lighton:
  ldi r16, 0b00100000
  sts PORTB, r16
  rjmp loop

Edit: I also implemented the method in https://stackoverflow.com/questions/39361410/creating-a-toggle-switch-in-avr-assembly to create a short delay with r18 instead of del, but it didn't help; see revised loop method below:

loop:
  cpi r18, 0
  brne dec_jmp
  lds r20, PORTD
  cpi r20, 0x00 ; PORTD always equal to 0x00 ?
  breq lighton
  clr r16
  sts PORTB, r16
  ldi r18, 250
  rjmp loop
lighton:
  ldi r16, 0b00100000
  sts PORTB, r16
  ldi r18, 250
  rjmp loop

dec_jmp:
  dec r18
  rjmp loop

With delay:

lighton:
  ldi r16, 0b00100000
  sts PORTB, r16
  call delay150
  ldi r16, 0b00000000
  sts PORTB, r16
  call delay150
  rjmp loop

Duplicate: https://stackoverflow.com/questions/39361410/creating-a-toggle-switch-in-avr-assembly

See edit in post

You have two potential problems in he setup: 1. You test not only PortB-bit2 (=Arduino pin 2), but all the pins of PortB. As these are floating your test (cpi r20 0x00) will never come true and the branch to lighton will never happen. 2. Your button will suffer from bouncing (google on this). Because of the 1st problem the LED should stay OFF. But it stays ON, so there is something else wrong. Break he program in small(er) parts and test each part on it's own. Did you try to switch the LED on and of by software alone (with a delay in between and not looking at the state of the switch)?

PORTB-bit2 corresponds to Pin13, which is the output pin that I am using. From what I understand, the branch to lighton is always happening and that's the problem. For example, I removed the line that sets PORTB in the setup method, and the LED remains on. So, Pin13 is constantly being set at lighton. Also, I did try the LED by itself with a delay and it works normally.

are you sure that the button is wired correctly? is the voltage on pin3 changing when you press the button?

Why did you connect a second LED to pin 13? You can as well used the LED that's already there (on the Arduino). Change the test to only test bit2 and not all the bytes from PortD (mask them out bij AND with 0x04). Even if you do that you still have the bouncing problem. Put a delay of a couple of seconds in so that you can see what happens in every loop. What happens when you replace the button with a piece of wire (like the button always closed), or when you take the button out (like button always open)?

See answer below

Just for the record: If you work with an Arduino Uno then Pin13 is on-board connected to a yellow LED via a non-inverting opamp and a resistor. Because of the opamp the load on the pin is negligible. - The setup of the other pins of PORTD is not so important. What is important is that you only test the status of pin2: lds r20 PORTD / andi r20 0b00000100 / breq lighton (the andi instruction sets the other bits to zero, so that the breq is based on the value of Pin2 only).

Fixed it with the below code for the loop:

loop:
  sbic PIND, 2
  call nopressb
  ; button pressed
  ldi r16, 0b00100000
  out PORTB, r16
  rjmp loop
nopressb:
  ldi r16, 0b00000000
  out PORTB, r16
  rjmp loop

Why do you use a call to jump to nopressb? call is ment to call a subroutine and stores the return address on the stack. Because you never return from a subroutine the stack will overflow.


text:
How to make Variable Frequency Drive (VFD) Inverter using Arduino
I have a VSI SPWM Inverter Project, but my supervisor ask me to upgrade it to a VFD Inverter. I've found a code about how to generate 3 phase SPWM in this article, and i've tried the code. The output signal is great. But i need to improve the code to VFD code with range frequency 0-100 Hz. I've found a reference about VFD from this one and tried to modify the SPWM code, but failed. Could anyone help me to improve the code, please? Here is the SPWM code..
int i=0;
int j=0;
int k=0;
int x=0;
int y=0;
int z=0;
int OK=0;
int OK1=0;
int OK2=0;
int OK3=0;
int OK4=0;
int sinPWM[]={1,2,5,7,10,12,15,17,19,22,24,27,30,32,34,37,39,42,
44,47,49,52,54,57,59,61,64,66,69,71,73,76,78,80,83,85,88,90,92,94,97,99,
101,103,106,108,110,113,115,117,119,121,124,126,128,130,132,134,136,138,140,142,144,146,
148,150,152,154,156,158,160,162,164,166,168,169,171,173,175,177,178,180,182,184,185,187,188,190,192,193,
195,196,198,199,201,202,204,205,207,208,209,211,212,213,215,216,217,219,220,221,222,223,224,225,226,227,
228,229,230,231,232,233,234,235,236,237,237,238,239,240,240,241,242,242,243,243,244,244,245,245,246,246,
247,247,247,248,248,248,248,249,249,249,249,249,255,255,255,255,249,249,249,249,249,248,
248,248,248,247,247,247,246,246,245,245,244,244,243,243,242,242,241,240,240,239,238,237,237,236,235,234,
233,232,231,230,229,228,227,226,225,224,223,222,221,220,219,217,216,215,213,212,211,209,208,207,205,204,
202,201,199,198,196,195,193,192,190,188,187,185,184,182,180,178,177,175,173,171,169,168,166,164,162,160,
158,156,154,152,150,148,146,144,142,140,138,136,134,132,130,128,126,124,121,119,117,115,113,110,108,106,
103,101,99,97,94,92,90,88,85,83,80,78,76,73,71,69,66,64,61,59,57,54,52,49,47,44,42,39,37,34,32,30,
27,24,22,19,17,15,12,10,7,5,2,1};

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

pinMode(4, OUTPUT);
pinMode(13,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(5,OUTPUT);

cli();// stop interrupts
TCCR0A=0;//reset the value
TCCR0B=0;//reset the value
TCNT0=0;//reset the value
//0b allow me to write bits in binary
TCCR0A=0b10100001;//phase correct pwm mode
TCCR0B=0b00000001; //no prescaler

TCCR2A=0;//reset the value
TCCR2B=0;//reset the value
TCNT2=0;//reset the value
//0b allow me to write bits in binary
TCCR2A=0b10100001;//phase correct pwm mode
TCCR2B=0b00000001; //no prescaler

TCCR3A=0;//reset the value
TCCR3B=0;//reset the value
TCNT3=0;//reset the value
//0b allow me to write bits in binary
TCCR3A=0b10100001;//phase correct pwm mode
TCCR3B=0b00000001; //no prescaler
TCCR1A=0;//reset the value
TCCR1B=0;//reset the value
TCNT1=0;//reset the value
OCR1A=509;// compare match value
TCCR1B=0b00001001; //WGM12 bit is 1 for CTC mode and no prescaler

TIMSK1 |=(1 << OCIE1A);// enable interrupts

sei();//stop interrupts
}
ISR(TIMER1_COMPA_vect){// interrupt when timer 1 match with OCR1A value
if(i>313 && OK==0){// final value from vector for pin 13
i=0;// go to first value of vector
OK=1;//enable pin 4
}
if(i>313 && OK==1){// final value from vector for pin 4
i=0;//go to firs value of vector
OK=0;//enable pin 13
}
x=sinPWM[i];// x take the value from vector corresponding to position i(i is zero indexed)
i=i+1;// go to the next position
if(OK==0){
OCR0B=0;//make pin 4 0
OCR0A=x;//enable pin 13 to corresponding duty cycle
}
if(OK==1){
OCR0A=0;//make pin 13 0
OCR0B=x;//enable pin 4 to corresponding duty cycle
}

if ((i==209) || OK1==1){//if i equal with 209 enable second signal
OK1=1;//mantain if function
if(j>313 && OK2==0){// final value from vector for pin 10
j=0;// go to first value of vector
OK2=1;//enable pin 9
}
if(j>313 && OK2==1){// final value from vector for pin 9
j=0;//go to firs value of vector
OK2=0;//enable pin 10
}
y=sinPWM[j];// y take the value from vector corresponding to position j(j is zero indexed)
j=j+1;// go to the next position
if(OK2==0){
OCR2B=0;//make pin 9 0
OCR2A=y;//enable pin 10 to corresponding duty cycle
}
if(OK2==1){
OCR2A=0;//make pin 10 0
OCR2B=y;//enable pin 9 to corresponding duty cycle
}
}
if ((j==209) || OK3==1){//if j equal with 209 enable third signal
OK3=1;//mantain if function
if(k>313 && OK4==0){// final value from vector for pin 5
k=0;// go to first value of vector
OK4=1;//enable pin 2
}
if(k>313 && OK4==1){// final value from vector for pin 2
k=0;//go to firs value of vector
OK4=0;//enable pin 5
}
z=sinPWM[k];// z take the value from vector corresponding to position k(k is zero indexed)
k=k+1;// go to the next position
if(OK4==0){
OCR3B=0;//make pin 2 0
OCR3A=z;//enable pin 5 to corresponding duty cycle
}
if(OK4==1){
OCR3A=0;//make pin 5 0
OCR3B=z;//enable pin 2 to corresponding duty cycle
}
}
}
void loop() {

}

Most, like I, in this corner of stackexchange.com (Arduinos) are likely thinking you mean Vacuum Florescent Display.  Not Variable Frequency Drive. You may get more responses if you explain this in your title.

Thanks for your reply, i'll edit the title..

i have sum code please visit my https://forum.arduino.cc/index.php?topic=645080.msg4363292#msg4363292