text:
ESP8266 exception on Array access
I have code to run an SH1106 display that works perfectly fine on a Mega328 (basic Uno clone) and Sparkfun Redboard Artemis (ARM M4).  The code for the ESP8266 (NodeMCU v1 clone) should be pretty similar to the ARM (i.e. bypassing the PROGMEM/memcpy_P stuff).  However, I've found that the ESP8266 goes into an infinite reboot loop with the following error message seen on the serial monitor:

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

load 0x4010f000, len 1392, room 16
tail 0
chksum 0xd0
csum 0xd0
v3d128e5c
~ld

I've tracked down the crash to the line where the Font Array data is accessed in my PutBigChar function in my My_SSH1106.h.  In fact, any attempt to access the array using a variable index causes an immediate reboot.  Using a constant literal index with the array does not cause the reboot.  Hence the horrible, ugly hack workaround in the code below.
Main sketch:

#include"My_SH1106.h"

void setup() {
  pinMode(LED_BUILTIN,OUTPUT);
  digitalWrite(LED_BUILTIN,HIGH);
  MySH1106_Init();
  MySH1106_Clear();
}

void loop() {

  MySH1106_PutBigString("I'm an arduino!",2,0);
  MySH1106_PutBigString("I'm an arduino!",2,14);

  delay(200);
}

My_SH1106.h
#include<Wire.h>
#include"lcdfont.h"

#define SH1106_SLAVE_ADDR 0x3c

#define CTRL_LAST_CMD 0x00
#define CTRL_NEXT_CMD 0x80
#define CTRL_LAST_RAM 0x40
#define CTRL_NEXT_RAM 0xC0

#define SH1106_OPT_INVERT 0x01
#define SH1106_OPT_UNDERL 0x02
#define SH1106_BIG_ROWS 4
#define SH1106_BIG_COLS 16

unsigned char MySH1106_workingBuffer[132];
unsigned char MySH1106_X, MySH1106_Y, MySH1106_options;

void MySH1106_Init() {
#ifdef ESP8266
    Wire.begin(D1,D2);  //sda, scl
#else
    Wire.begin();
#endif
    Wire.beginTransmission(SH1106_SLAVE_ADDR);
    Wire.write(CTRL_NEXT_CMD);
    Wire.write(0xaf); //display on
    Wire.write(CTRL_LAST_CMD);
    Wire.write(0xa5); //all on.
    //Wire.write(0xa4); //normal
    Wire.endTransmission(1);
    delay(200);
    Wire.beginTransmission(SH1106_SLAVE_ADDR);
    Wire.write(CTRL_LAST_CMD);
    Wire.write(0xa4);  //normal display
    Wire.endTransmission(1);
    MySH1106_X=0;
    MySH1106_Y=0;

}

void MySH1106_SetCol(unsigned char col) {
    Wire.beginTransmission(SH1106_SLAVE_ADDR);
    Wire.write(CTRL_NEXT_CMD);
    Wire.write(col & 0x0f);
    Wire.write(CTRL_LAST_CMD);
    Wire.write(0x10 | ((col>>4)&0xf));
    Wire.endTransmission(1);
}

void MySH1106_SetPage(unsigned char page) {
    Wire.beginTransmission(SH1106_SLAVE_ADDR);
    Wire.write(CTRL_LAST_CMD);
    Wire.write(0xb0 | (page & 0xf));
    Wire.endTransmission(1);
}

void MySH1106_SetPageCol(unsigned char page, unsigned char col) {
    Wire.beginTransmission(SH1106_SLAVE_ADDR);
    Wire.write(CTRL_NEXT_CMD);
    Wire.write(0xb0 | (page & 0xf));
    Wire.write(CTRL_NEXT_CMD);
    Wire.write(col & 0x0f);
    Wire.write(CTRL_LAST_CMD);
    Wire.write(0x10 | ((col>>4)&0xf));
    Wire.endTransmission(1);
}

void MySH1106_Clear() {
    for(unsigned char page=0;page<8;page++) {
        MySH1106_SetPage(page);
        MySH1106_SetCol(1);
        for(unsigned char x=0;x<129;x++) {
#ifdef ESP8266
            yield();
#endif
            Wire.beginTransmission(SH1106_SLAVE_ADDR);
            Wire.write(CTRL_LAST_RAM);
            Wire.write(0x00);
            Wire.endTransmission(1);
        } //of all columns

    }//of all pages
}

void MySH1106_PutBigChar(char c, unsigned char x, unsigned char y) {
    unsigned char remainder, offset, startPage, endPage, filldat, currentPage;
    unsigned char temp, curY, curX;

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
    unsigned char glyphBuf[CHAR_HEIGHT];
//#elif defined(ESP8266)
//    const unsigned char* glyphBuf;
#else
    unsigned char glyphBuf[CHAR_HEIGHT];
#endif

    unsigned char glyphRow=0, glyphCol,glyphByte;
    unsigned char args[4];

    offset = y % 8;
    remainder =(y+CHAR_HEIGHT) % 8;
    startPage = y/8;
    endPage = (y+CHAR_HEIGHT)/8;
    currentPage = startPage;
#ifdef ESP8266
    yield();
#endif

    //memcpy_P is for AVR8 based processors.
    //when running on Artemis, use a regular copy.
    //#ifdef __AVR__ would cover other AVRs.

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
    memcpy_P(glyphBuf, (unsigned char *)pgm_read_word(&(FontArray[c])),CHAR_HEIGHT);
#elif defined(ESP8266)
    //oddly, any attempt to dereference glyphBuf or use it as an array results in an exception.
    //glyphBuf = FontArray[c];

    //horrible, brutal hack.
    switch(c) {
        case ' ':
            glyphBuf[0]=NullArray[0];
            glyphBuf[1]=NullArray[1];
            glyphBuf[2]=NullArray[2];
            glyphBuf[3]=NullArray[3];
            glyphBuf[4]=NullArray[4];
            glyphBuf[5]=NullArray[5];
            glyphBuf[6]=NullArray[6];
            glyphBuf[7]=NullArray[7];
            glyphBuf[8]=NullArray[8];
            glyphBuf[9]=NullArray[9];
            glyphBuf[10]=NullArray[10];
            glyphBuf[11]=NullArray[11];
            glyphBuf[12]=NullArray[12];
            glyphBuf[13]=NullArray[13];
            break;
        case 'I':
            glyphBuf[0]=IArray[0];
            glyphBuf[1]=IArray[1];
            glyphBuf[2]=IArray[2];
            glyphBuf[3]=IArray[3];
            glyphBuf[4]=IArray[4];
            glyphBuf[5]=IArray[5];
            glyphBuf[6]=IArray[6];
            glyphBuf[7]=IArray[7];
            glyphBuf[8]=IArray[8];
            glyphBuf[9]=IArray[9];
            glyphBuf[10]=IArray[10];
            glyphBuf[11]=IArray[11];
            glyphBuf[12]=IArray[12];
            glyphBuf[13]=IArray[13];

            break;
        case 'a':
            glyphBuf[0]=aArray[0];
            glyphBuf[1]=aArray[1];
            glyphBuf[2]=aArray[2];
            glyphBuf[3]=aArray[3];
            glyphBuf[4]=aArray[4];
            glyphBuf[5]=aArray[5];
            glyphBuf[6]=aArray[6];
            glyphBuf[7]=aArray[7];
            glyphBuf[8]=aArray[8];
            glyphBuf[9]=aArray[9];
            glyphBuf[10]=aArray[10];
            glyphBuf[11]=aArray[11];
            glyphBuf[12]=aArray[12];
            glyphBuf[13]=aArray[13];
            break;
        case 'm':
            glyphBuf[0]=mArray[0];
            glyphBuf[1]=mArray[1];
            glyphBuf[2]=mArray[2];
            glyphBuf[3]=mArray[3];
            glyphBuf[4]=mArray[4];
            glyphBuf[5]=mArray[5];
            glyphBuf[6]=mArray[6];
            glyphBuf[7]=mArray[7];
            glyphBuf[8]=mArray[8];
            glyphBuf[9]=mArray[9];
            glyphBuf[10]=mArray[10];
            glyphBuf[11]=mArray[11];
            glyphBuf[12]=mArray[12];
            glyphBuf[13]=mArray[13];
            break;
        case 'n':
            glyphBuf[0]=nArray[0];
            glyphBuf[1]=nArray[1];
            glyphBuf[2]=nArray[2];
            glyphBuf[3]=nArray[3];
            glyphBuf[4]=nArray[4];
            glyphBuf[5]=nArray[5];
            glyphBuf[6]=nArray[6];
            glyphBuf[7]=nArray[7];
            glyphBuf[8]=nArray[8];
            glyphBuf[9]=nArray[9];
            glyphBuf[10]=nArray[10];
            glyphBuf[11]=nArray[11];
            glyphBuf[12]=nArray[12];
            glyphBuf[13]=nArray[13];
            break;
        default:
            glyphBuf[0]=NullArray[0];
            glyphBuf[1]=NullArray[1];
            glyphBuf[2]=NullArray[2];
            glyphBuf[3]=NullArray[3];
            glyphBuf[4]=NullArray[4];
            glyphBuf[5]=NullArray[5];
            glyphBuf[6]=NullArray[6];
            glyphBuf[7]=NullArray[7];
            glyphBuf[8]=NullArray[8];
            glyphBuf[9]=NullArray[9];
            glyphBuf[10]=NullArray[10];
            glyphBuf[11]=NullArray[11];
            glyphBuf[12]=NullArray[12];
            glyphBuf[13]=NullArray[13];
    }//of switch

#else
//this should work for ESP, but doesn't
    for(int i=0;i<CHAR_HEIGHT;i++) {
        glyphBuf[i]=FontArray[c][i];
    }
#endif

    MySH1106_SetPageCol(startPage,x);
    Wire.beginTransmission(SH1106_SLAVE_ADDR);//set up for ram read
    Wire.write(CTRL_LAST_RAM);
    Wire.endTransmission(1);

    Wire.requestFrom(SH1106_SLAVE_ADDR, 9, 1);
    while(Wire.available()<9) {
#ifdef ESP8266
        yield();
#endif
    };
    Wire.read(); //dummy read
    for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
        MySH1106_workingBuffer[curX] = Wire.read(); //real read.
    }
#ifdef ESP8266
    yield();
#endif

    for(curY=offset;curY<8;curY++) {
        glyphByte = glyphBuf[glyphRow++];
        glyphCol=0;
        for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
#ifdef ESP8266
            yield();
#endif
            if ((0x80>>glyphCol) & glyphByte) {
                MySH1106_workingBuffer[curX] |= (0x01<<curY);
            } else {
                MySH1106_workingBuffer[curX] &= ~(0x01<<curY);
            }

            glyphCol++;
#ifdef ESP8266
            yield();
#endif
        }

    }//of y offsets in first page.

    MySH1106_SetCol(x);
    Wire.beginTransmission(SH1106_SLAVE_ADDR);
    Wire.write(CTRL_LAST_RAM);
    for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
        Wire.write(MySH1106_workingBuffer[curX] );
    }
    Wire.endTransmission(1);
    currentPage++;

    //middle page
    if(currentPage<endPage) {
        MySH1106_SetPageCol(currentPage,x);
        Wire.beginTransmission(SH1106_SLAVE_ADDR);//set up for ram read
        Wire.write(CTRL_LAST_RAM);
        Wire.endTransmission(1);

        Wire.requestFrom(SH1106_SLAVE_ADDR, 9, 1);
        while(Wire.available()<9){
#ifdef ESP8266
            yield();
#endif
        };
        Wire.read(); //dummy read
        for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
            MySH1106_workingBuffer[curX] = Wire.read(); //real read.
        }

        for(curY=0;curY<8;curY++) {
            glyphByte = glyphBuf[glyphRow++];
            glyphCol=0;
            for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
                if(glyphByte & (0x80>>glyphCol)) {
                    MySH1106_workingBuffer[curX] |= (0x01<<curY);
                } else {
                    MySH1106_workingBuffer[curX] &= ~(0x01<<curY);
                }
                glyphCol++;
            }
#ifdef ESP8266
            yield();
#endif
        }//of y offsets in intermediate page

        MySH1106_SetCol(x);
        Wire.beginTransmission(SH1106_SLAVE_ADDR);
        Wire.write(CTRL_LAST_RAM);
        for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
            Wire.write(MySH1106_workingBuffer[curX] );
        }
        Wire.endTransmission(1);
        currentPage++;
    }

    MySH1106_SetPageCol(currentPage,x);
    Wire.beginTransmission(SH1106_SLAVE_ADDR);//set up for ram read
    Wire.write(CTRL_LAST_RAM);
    Wire.endTransmission(1);

    Wire.requestFrom(SH1106_SLAVE_ADDR, 9, 1);
    while(Wire.available()<9){
#ifdef ESP8266
        yield();
#endif
    };
    Wire.read(); //dummy read
    for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
        MySH1106_workingBuffer[curX] = Wire.read(); //real read.
    }

    for(curY=0;curY<remainder;curY++) {
        glyphByte = glyphBuf[glyphRow++];
        glyphCol=0;
        for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
            if(glyphByte & (0x80>>glyphCol)) {
                MySH1106_workingBuffer[curX] |= (0x01<<curY);
            } else {
                MySH1106_workingBuffer[curX] &= ~(0x01<<curY);
            }
            glyphCol++;
        }
#ifdef ESP8266
        yield();
#endif
    }//of y offsets in last page

    MySH1106_SetCol(x);
    Wire.beginTransmission(SH1106_SLAVE_ADDR);
    Wire.write(CTRL_LAST_RAM);
    for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
        Wire.write(MySH1106_workingBuffer[curX] );
    }
    Wire.endTransmission(1);

}//of PutBigChar

void MySH1106_PutBigString(const char* c, unsigned char x, unsigned char y) {
    int8_t stringIndex=0;

    while(c[stringIndex]) {
        MySH1106_PutBigChar(c[stringIndex++],x,y);

        x+=CHAR_WIDTH;
    }
}

lcdfont.h
/*
 * File:
 * Author:
 * Comments:
 * Revision history:
 */

//the font is shamelessly extracted from the "BIOS" of DosBox.

// This is a guard condition so that contents of this file are not included
// more than once.
#ifndef LCD_FONT_DATA_H
#define  LCD_FONT_DATA_H

#define CHAR_HEIGHT 14
#define CHAR_WIDTH 8
// TODO Insert appropriate #include <>

// TODO Insert C++ class definitions if appropriate

// TODO Insert declarations
const unsigned char NullArray[] PROGMEM = { // 0x20
0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char BangArray[] PROGMEM = { // 0x21
0x0, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00};
const unsigned char DquoteArray[] PROGMEM = { // 0x22
0x0, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char HashArray[] PROGMEM = { // 0x23
0x0, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00};
const unsigned char DollarArray[] PROGMEM = { // 0x24
0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00};
const unsigned char PercentArray[] PROGMEM = { // 0x25
0x0, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x66, 0xc6, 0x00, 0x00, 0x00};
const unsigned char AmpersandArray[] PROGMEM = { // 0x26
0x0, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00};
const unsigned char SquoteArray[] PROGMEM = { // 0x27
0x0, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char LparenArray[] PROGMEM = { // 0x28
0x0, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00};
const unsigned char RparenArray[] PROGMEM = { // 0x29
0x0, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00};
const unsigned char AsteriskArray[] PROGMEM = { // 0x2a
0x0, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char PlusArray[] PROGMEM = { // 0x2b
0x0, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char CommaArray[] PROGMEM = { // 0x2c
0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00};
const unsigned char DashArray[] PROGMEM = { // 0x2d
0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char PeriodArray[] PROGMEM = { // 0x2e
0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00};
const unsigned char SlashArray[] PROGMEM = { // 0x2f
0x0, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00};
const unsigned char n0Array[] PROGMEM = { // 0x30
0x0, 0x00, 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char n1Array[] PROGMEM = { // 0x31
0x0, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00};
const unsigned char n2Array[] PROGMEM = { // 0x32
0x0, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00};
const unsigned char n3Array[] PROGMEM = { // 0x33
0x0, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char n4Array[] PROGMEM = { // 0x34
0x0, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00};
const unsigned char n5Array[] PROGMEM = { // 0x35
0x0, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char n6Array[] PROGMEM = { // 0x36
0x0, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char n7Array[] PROGMEM = { // 0x37
0x0, 0x00, 0xfe, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00};
const unsigned char n8Array[] PROGMEM = { // 0x38
0x0, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char n9Array[] PROGMEM = { // 0x39
0x0, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00};
const unsigned char ColonArray[] PROGMEM = { // 0x3a
0x0, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00};
const unsigned char SemicolonArray[] PROGMEM = { // 0x3b
0x0, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00};
const unsigned char LtArray[] PROGMEM = { // 0x3c
0x0, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00};
const unsigned char EqualArray[] PROGMEM = { // 0x3d
0x0, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char GtArray[] PROGMEM = { // 0x3e
0x0, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00};
const unsigned char QuestionArray[] PROGMEM = { // 0x3f
0x0, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00};
const unsigned char AtArray[] PROGMEM = { // 0x40
0x0, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00};
const unsigned char AArray[] PROGMEM = { // 0x41
0x0, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00};
const unsigned char BArray[] PROGMEM = { // 0x42
0x0, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00};
const unsigned char CArray[] PROGMEM = { // 0x43
0x0, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00};
const unsigned char DArray[] PROGMEM = { // 0x44
0x0, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00};
const unsigned char EArray[] PROGMEM = { // 0x45
0x0, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00};
const unsigned char FArray[] PROGMEM = { // 0x46
0x0, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00};
const unsigned char GArray[] PROGMEM = { // 0x47
0x0, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00};
const unsigned char HArray[] PROGMEM = { // 0x48
0x0, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00};
const unsigned char IArray[] PROGMEM = { // 0x49
0x0, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00};
const unsigned char JArray[] PROGMEM = { // 0x4a
0x0, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00};
const unsigned char KArray[] PROGMEM = { // 0x4b
0x0, 0x00, 0xe6, 0x66, 0x6c, 0x6c, 0x78, 0x6c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00};
const unsigned char LArray[] PROGMEM = { // 0x4c
0x0, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00};
const unsigned char MArray[] PROGMEM = { // 0x4d
0x0, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00};
const unsigned char NArray[] PROGMEM = { // 0x4e
0x0, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00};
const unsigned char OArray[] PROGMEM = { // 0x4f
0x0, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00};
const unsigned char PArray[] PROGMEM = { // 0x50
0x0, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00};
const unsigned char QArray[] PROGMEM = { // 0x51
0x0, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00};
const unsigned char RArray[] PROGMEM = { // 0x52
0x0, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00};
const unsigned char SArray[] PROGMEM = { // 0x53
0x0, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char TArray[] PROGMEM = { // 0x54
0x0, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00};
const unsigned char UArray[] PROGMEM = { // 0x55
0x0, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char VArray[] PROGMEM = { // 0x56
0x0, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00};
const unsigned char WArray[] PROGMEM = { // 0x57
0x0, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00};
const unsigned char XArray[] PROGMEM = { // 0x58
0x0, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00};
const unsigned char YArray[] PROGMEM = { // 0x59
0x0, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00};
const unsigned char ZArray[] PROGMEM = { // 0x5a
0x0, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00};
const unsigned char LbracketArray[] PROGMEM = { // 0x5b
0x0, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00};
const unsigned char BslashArray[] PROGMEM = { // 0x5c
0x0, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00};
const unsigned char RbracketArray[] PROGMEM = { // 0x5d
0x0, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00};
const unsigned char CaretArray[] PROGMEM = { // 0x5e
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char _Array[] PROGMEM = { // 0x5f
0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00};
const unsigned char BquoteArray[] PROGMEM = { // 0x60
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char aArray[] PROGMEM = { // 0x61
0x0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00};
const unsigned char bArray[] PROGMEM = { // 0x62
0x0, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00};
const unsigned char cArray[] PROGMEM = { // 0x63
0x0, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char dArray[] PROGMEM = { // 0x64
0x0, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00};
const unsigned char eArray[] PROGMEM = { // 0x65
0x0, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char fArray[] PROGMEM = { // 0x66
0x0, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00};
const unsigned char gArray[] PROGMEM = { // 0x67
0x0, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00};
const unsigned char hArray[] PROGMEM = { // 0x68
0x0, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00};
const unsigned char iArray[] PROGMEM = { // 0x69
0x0, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00};
const unsigned char jArray[] PROGMEM = { // 0x6a
0x0, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00};
const unsigned char kArray[] PROGMEM = { // 0x6b
0x0, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00};
const unsigned char lArray[] PROGMEM = { // 0x6c
0x0, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00};
const unsigned char mArray[] PROGMEM = { // 0x6d
0x0, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00};
const unsigned char nArray[] PROGMEM = { // 0x6e
0x0, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00};
const unsigned char oArray[] PROGMEM = { // 0x6f
0x0, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char pArray[] PROGMEM = { // 0x70
0x0, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00};
const unsigned char qArray[] PROGMEM = { // 0x71
0x0, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00};
const unsigned char rArray[] PROGMEM = { // 0x72
0x0, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00};
const unsigned char sArray[] PROGMEM = { // 0x73
0x0, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char tArray[] PROGMEM = { // 0x74
0x0, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00};
const unsigned char uArray[] PROGMEM = { // 0x75
0x0, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00};
const unsigned char vArray[] PROGMEM = { // 0x76
0x0, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00};
const unsigned char wArray[] PROGMEM = { // 0x77
0x0, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00};
const unsigned char xArray[] PROGMEM = { // 0x78
0x0, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00};
const unsigned char yArray[] PROGMEM = { // 0x79
0x0, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00};
const unsigned char zArray[] PROGMEM = { // 0x7a
0x0, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xfe, 0x00, 0x00, 0x00};
const unsigned char LbraceArray[] PROGMEM = { // 0x7b
0x0, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00};
const unsigned char PipeArray[] PROGMEM = { // 0x7c
0x0, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00};
const unsigned char RbraceArray[] PROGMEM = { // 0x7d
0x0, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00};
const unsigned char TildeArray[] PROGMEM = { // 0x7e
0x0, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/*I'll say Kana is allowed to use one more row since there are no descenders.*/
/*on second thought, I don't want to have to come up with a separate 8x8 font*/
/*on third thought, 8x8 would be ugly.*/

const unsigned char dummy[] PROGMEM = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0};

const unsigned char *const FontArray[] PROGMEM = {
dummy,  // 0x00
dummy,  // 0x01
dummy,  // 0x02
dummy,  // 0x03
dummy,  // 0x04
dummy,  // 0x05
dummy,  // 0x06
dummy,  // 0x07
dummy,  // 0x08
dummy,  // 0x09
dummy,  // 0x0a
dummy,  // 0x0b
dummy,  // 0x0c
dummy,  // 0x0d
dummy,  // 0x0e
dummy,  // 0x0f
dummy,  // 0x10
dummy,  // 0x11
dummy,  // 0x12
dummy,  // 0x13
dummy,  // 0x14
dummy,  // 0x15
dummy,  // 0x16
dummy,  // 0x17
dummy,  // 0x18
dummy,  // 0x19
dummy,  // 0x1a
dummy,  // 0x1b
dummy,  // 0x1c
dummy,  // 0x1d
dummy,  // 0x1e
dummy,  // 0x1f
NullArray, // 0x20
BangArray, // 0x21
DquoteArray, // 0x22
HashArray, // 0x23
DollarArray, // 0x24
PercentArray, // 0x25
AmpersandArray, // 0x26
SquoteArray, // 0x27
LparenArray, // 0x28
RparenArray, // 0x29
AsteriskArray, // 0x2a
PlusArray, // 0x2b
CommaArray, // 0x2c
DashArray, // 0x2d
PeriodArray, // 0x2e
SlashArray, // 0x2f
n0Array, // 0x30
n1Array, // 0x31
n2Array, // 0x32
n3Array, // 0x33
n4Array, // 0x34
n5Array, // 0x35
n6Array, // 0x36
n7Array, // 0x37
n8Array, // 0x38
n9Array, // 0x39
ColonArray, // 0x3a
SemicolonArray, // 0x3b
LtArray, // 0x3c
EqualArray, // 0x3d
GtArray, // 0x3e
QuestionArray, // 0x3f
AtArray, // 0x40
AArray, // 0x41
BArray, // 0x42
CArray, // 0x43
DArray, // 0x44
EArray, // 0x45
FArray, // 0x46
GArray, // 0x47
HArray, // 0x48
IArray, // 0x49
JArray, // 0x4a
KArray, // 0x4b
LArray, // 0x4c
MArray, // 0x4d
NArray, // 0x4e
OArray, // 0x4f
PArray, // 0x50
QArray, // 0x51
RArray, // 0x52
SArray, // 0x53
TArray, // 0x54
UArray, // 0x55
VArray, // 0x56
WArray, // 0x57
XArray, // 0x58
YArray, // 0x59
ZArray, // 0x5a
LbracketArray, // 0x5b
BslashArray, // 0x5c
RbracketArray, // 0x5d
CaretArray, // 0x5e
_Array, // 0x5f
BquoteArray, // 0x60
aArray, // 0x61
bArray, // 0x62
cArray, // 0x63
dArray, // 0x64
eArray, // 0x65
fArray, // 0x66
gArray, // 0x67
hArray, // 0x68
iArray, // 0x69
jArray, // 0x6a
kArray, // 0x6b
lArray, // 0x6c
mArray, // 0x6d
nArray, // 0x6e
oArray, // 0x6f
pArray, // 0x70
qArray, // 0x71
rArray, // 0x72
sArray, // 0x73
tArray, // 0x74
uArray, // 0x75
vArray, // 0x76
wArray, // 0x77
xArray, // 0x78
yArray, // 0x79
zArray, // 0x7a
LbraceArray, // 0x7b
PipeArray, // 0x7c
RbraceArray, // 0x7d
TildeArray, // 0x7e

};

#endif

The horrible, ugly hack should not be necessary.  Is this some shortcoming of the ESP, or am I misusing the tool in some way?  Is there a simpler way to make this work?

Could it be a power issue? Reset cause 2 is a power reset (https://www.espressif.com/sites/default/files/documentation/esp8266_reset_causes_and_common_fatal_exception_causes_en.pdf). From my experience the esp is much more sensitive than the atmegas.

I don't have any issues running any other script, and I made sure the SH1106 was powered off of a separate supply.  I added additional storage caps to the 3.3V rail for good measure.  It doesn't feel like a power issue.  Other sketches that draw to the SH106 without accessing the font routine also have no problem.


text:
mp3 trigger, output to antoher input, no switch
I have two Arduinos: one is transferring on its output pin to other Arduino's input_pullup low or high signal depend on servo action (rotating/stop).
I need an action on slave Arduino with dfmini player: actually I need a code with which mp3 sample is triggered on slave Arduino.
servo rotates -output pin goes low = sample is played just once until servo reaches desired position
servo stopped -output pin goes high = sample stops
solving this issue will be really helpful for my project.
here is example code
tnx.
***************************************************
  DFPlayer - A Mini MP3 Player For Arduino
  <https://www.dfrobot.com/index.php?route=product/product&product_id=1121>

 ***************************************************
  This example shows the basic function of library for DFPlayer.

  Created 2016-12-07
  By [Angelo qiao](Angelo.qiao@dfrobot.com)

  GNU Lesser General Public License.
  See <http://www.gnu.org/licenses/> for details.
  All above must be included in any redistribution
 ****************************************************/

/***********Notice and Trouble shooting***************
  1.Connection and Diagram can be found here
  <https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299#Connection_Diagram>
  2.This code is tested on Arduino Uno, Leonardo, Mega boards.
 ****************************************************/

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#define pin 2 // connect to master digital output "pin"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

void setup()
{
 mySoftwareSerial.begin(9600);
 Serial.begin(115200);
 pinMode(2,INPUT_PULLUP);

 Serial.println();
 Serial.println(F("DFRobot DFPlayer Mini Demo"));
 Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

 if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
   Serial.println(F("Unable to begin:"));
   Serial.println(F("1.Please recheck the connection!"));
   Serial.println(F("2.Please insert the SD card!"));
   while (true);
 }
 Serial.println(F("DFPlayer Mini online."));

 myDFPlayer.volume(15);  //Set volume value. From 0 to 30
}

void loop(){
  if (digitalRead(2)==LOW) myDFPlayer.play(1); // 5 sec mp3 sample, turn on , then debounce or return ?

}

}

wiring scheme

output cobmination on master arduino

What exactly is your problem in writing the necessary code?

im newbie, i know little about coding, is it solution complicated ?

The normal way is to start learnimg coding with tutorials and simple examples from the web. You most likely won't find an example, that exactly fits your goal, but you can use them to learn enough to solve your problem. You can always ask a specific question here and we will try to help you.

i have searched online , but i cant find any example with direct connection between output and input pins, always button or switch is included.

For the slave Arduino it is just an input pin. It doesn't know, what is connected to the pin. Thus it is irrelevant, if you connect a button or a second Arduino to that input pin. For the slave these options are the same

yes, thats true, but stil waiting for possible solution.

you are going to have a long wait

source: Stack Exchange

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

sort: votes


text:
reversing DC motor rotation using TWO limit Switches Problem !! need help
I'd like to write a code for reversing DC motor rotation direction as follows:

Start the motor rotation clockwise (CW).
When reach Limit Switch (CW) → motor will stop for 5 sec.
after 5 sec. of stopping → the motor will rotate in counter clockwise direction(CCW).
When reach Limit Switch (CCW) → motor will stop for 5 sec.

and repeat point 1, 2, 3 and 4...
Actually I wrote a code for reversing the motor direction using two limit switches and it is working good. But when I added delay the motor did not stop using the limit Switches and continue to rotate...
If any one can help...
Here is my code for reversing the direction with out delay 5 sec. My limit SWs are connected on Normal Open.
int sw1, sw2, sw3;
const int LM1 = 0;
const int LM2 = 1;
const int LM3 = 6;
const int CW = 10;
const int CCW = 9;
const int Buzzer = 7;

void setup() {
  pinMode(LM1, INPUT);
  pinMode(LM2, INPUT);
  pinMode(LM3, INPUT);
  pinMode(CW, OUTPUT);
  pinMode(CCW, OUTPUT);
}

void loop(){
  sw3 = digitalRead(LM3);
  sw1 = digitalRead(LM1);
  sw2 = digitalRead(LM2);

  if (sw1 == LOW && sw2 == HIGH) {
    do {
      digitalWrite(Buzzer, HIGH);
      digitalWrite(CW, HIGH);// change the direction of rotation (DOWN Movement)
      digitalWrite(CCW, LOW);

      sw2 = digitalRead(LM2);
    } while (sw2 == HIGH);
  }
  else if (sw1 == HIGH && sw2 == LOW) {
    do {
      digitalWrite(Buzzer, HIGH);
      digitalWrite(CW, LOW);// change the direction of rotation (UP Movement)
      digitalWrite(CCW, HIGH);

      sw1= digitalRead(LM1);
    } while (sw1 == HIGH);
  }
}

Normally you use state machine for this kind of programming: you have a
state variable that remembers what you are doing, and depending on the
current state you decide what to do next. Below is an example with two
states. I have embedded a few assumptions about the wiring of your motor
and your switches, which may be wrong, so you have to check the code.
void loop() {
    static enum {MOVING_CW, MOVING_CCW} state;

    switch (state) {
    case MOVING_CW:
        if (digitalRead(LM2) == LOW) {  // hit switch
            digitalWrite(CW, LOW);      // stop
            delay(5000);
            digitalWrite(CCW, HIGH);    // restart
            state = MOVING_CCW;
        }
        break;
    case MOVING_CCW:
        if (digitalRead(LM1) == LOW) {  // hit switch
            digitalWrite(CCW, LOW);     // stop
            delay(5000);
            digitalWrite(CW, HIGH);     // restart
            state = MOVING_CW;
        }
        break;
    }
}

This will start in the MOVING_CW state, but you have to actually start
the movement in setup(). It has the drawback of having long delay()s in
the loop, which is undesirable if you have other tasks to perform. These
delays can be removed by “remembering” that you are waiting as two extra
states:
void loop() {
    static enum {MOVING_CW, MOVING_CCW, STOPPED_CW, STOPPED_CCW} state;
    static unsigned long time_stopped;
    unsigned long now = millis();

    switch (state) {
    case MOVING_CW:
        if (digitalRead(LM2) == LOW) {  // hit switch
            digitalWrite(CW, LOW);      // stop
            state = STOPPED_CW;
            time_stopped = now;
        }
        break;
    case MOVING_CCW:
        if (digitalRead(LM1) == LOW) {  // hit switch
            digitalWrite(CCW, LOW);     // stop
            state = STOPPED_CCW;
            time_stopped = now;
        }
        break;
    case STOPPED_CW:
        if (now - time_stopped >= 5000) {
            digitalWrite(CCW, HIGH);    // restart
            state = MOVING_CCW;
        }
        break;
    case STOPPED_CCW:
        if (now - time_stopped >= 5000) {
            digitalWrite(CW, HIGH);     // restart
            state = MOVING_CW;
        }
        break;
    }
}

Maybe the code with the 5 second delay is more usefull. Because you are telling us the code you now deliver is supposed to work?
Probably using delay(5000) will work?

I added delay (5000); at the end of my code -- > Doesn't work also I tried to add delay at the start of my code ---> Doesn't work

You will have to make another state (idle). Here you will have to put the commands low, this way the motor will actually stop. Then you can add the delay to it, so the motor will stop for the 5 second duration.

kindly give me idea or example about this issue

Motor CW > Motor idle > Motor CCW > Motor idle > Motor CW…..
Every change in limit switching should change the state of the motor.
In your program now it is: Motor CW > Motor CCW > Motor CW…
Are you able to put the motor on or off with program code?
Or are you only able to change its direction? If so, would writing both CW and CCW LOW deliver any problems?

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


text:
error: 'MonoOutput' has not been declared (Mozzi library, Arduino Nano)
I know this error is specific to this particular family of sketches, but please bear with me; when I try to compile this against an Arduino Nano/Uno (with Arduino IDE 1.8.15) the compiler complains that 'MonoOutput' has not been declared, like so:
Triple_DCO_1.3:697:14: error: 'MonoOutput' has not been declared
    return MonoOutput::from8Bit((aSin1.next() * (pgm_read_byte(&(gain_table[0][gain]))) / 512 + aSin2.next() * (pgm_read_byte(&(gain_table[1][gain]))) / 512 + aSin3.next() * (pgm_read_byte(&(gain_table[2][gain]))) / 512 + aSin4.next() * (pgm_read_byte(&(gain_table[3][gain]))) / 512 + aSin5.next() * (pgm_read_byte(&(gain_table[4][gain]))) / 512 + aSin6.next() * (pgm_read_byte(&(gain_table[5][gain]))) / 512 + aSin7.next() * (pgm_read_byte(&(gain_table[6][gain]))) / 512 )*Gain_CV_2/128);
           ^~~~~~~~~~

I have found that this issue has come up once on ModWiggler, once in YouTube comments, and once in the Mozzi GitHub repository (but in the last case only pertaining to the Nano Every and not a vanilla Nano), so I know it's not unique to my situation; but since most people don't seem to be experiencing this problem, it must be something particular to my setup or am missing something obvious.
The code in question (Triple_DCO_1.3.ino) is from luislutz GitHub; it is too long to post here, but a different sketch from the same family, pasted below, exhibits the same error for me:
#include <MozziGuts.h>
#include <Oscil.h> // oscillator template

#include <tables/saw2048_int8.h> // saw table for oscillator
#include <tables/square_no_alias512_int8.h> // saw table for oscillator
#include <tables/triangle_hermes_2048_int8.h> // saw table for oscillator
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <tables/waveshape_chebyshev_3rd_256_int8.h> // sine table for oscillator
#include <tables/halfsin256_uint8.h> // sine table for oscillator
#include <tables/waveshape_sigmoid_int8.h> // sine table for oscillator
#include <tables/phasor256_int8.h> // sine table for oscillator

Oscil <SAW2048_NUM_CELLS, AUDIO_RATE> aSaw1(SAW2048_DATA);
Oscil <SAW2048_NUM_CELLS, AUDIO_RATE> aSaw2(SAW2048_DATA);
Oscil <SAW2048_NUM_CELLS, AUDIO_RATE> aSaw3(SAW2048_DATA);
Oscil <SAW2048_NUM_CELLS, AUDIO_RATE> aSaw4(SAW2048_DATA);
Oscil <SAW2048_NUM_CELLS, AUDIO_RATE> aSaw5(SAW2048_DATA);

Oscil <SQUARE_NO_ALIAS512_NUM_CELLS, AUDIO_RATE> aSqu1(SQUARE_NO_ALIAS512_DATA);
Oscil <SQUARE_NO_ALIAS512_NUM_CELLS, AUDIO_RATE> aSqu2(SQUARE_NO_ALIAS512_DATA);
Oscil <SQUARE_NO_ALIAS512_NUM_CELLS, AUDIO_RATE> aSqu3(SQUARE_NO_ALIAS512_DATA);
Oscil <SQUARE_NO_ALIAS512_NUM_CELLS, AUDIO_RATE> aSqu4(SQUARE_NO_ALIAS512_DATA);
Oscil <SQUARE_NO_ALIAS512_NUM_CELLS, AUDIO_RATE> aSqu5(SQUARE_NO_ALIAS512_DATA);

Oscil <TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aTri1(TRIANGLE_HERMES_2048_DATA);
Oscil <TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aTri2(TRIANGLE_HERMES_2048_DATA);
Oscil <TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aTri3(TRIANGLE_HERMES_2048_DATA);
Oscil <TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aTri4(TRIANGLE_HERMES_2048_DATA);
Oscil <TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aTri5(TRIANGLE_HERMES_2048_DATA);

Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin1(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin2(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin3(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin4(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin5(SIN2048_DATA);

Oscil <CHEBYSHEV_3RD_256_NUM_CELLS, AUDIO_RATE> aChb1(CHEBYSHEV_3RD_256_DATA);
Oscil <CHEBYSHEV_3RD_256_NUM_CELLS, AUDIO_RATE> aChb2(CHEBYSHEV_3RD_256_DATA);
Oscil <CHEBYSHEV_3RD_256_NUM_CELLS, AUDIO_RATE> aChb3(CHEBYSHEV_3RD_256_DATA);
Oscil <CHEBYSHEV_3RD_256_NUM_CELLS, AUDIO_RATE> aChb4(CHEBYSHEV_3RD_256_DATA);
Oscil <CHEBYSHEV_3RD_256_NUM_CELLS, AUDIO_RATE> aChb5(CHEBYSHEV_3RD_256_DATA);

Oscil <HALFSIN256_NUM_CELLS, AUDIO_RATE> ahSin1(HALFSIN256_DATA);
Oscil <HALFSIN256_NUM_CELLS, AUDIO_RATE> ahSin2(HALFSIN256_DATA);
Oscil <HALFSIN256_NUM_CELLS, AUDIO_RATE> ahSin3(HALFSIN256_DATA);
Oscil <HALFSIN256_NUM_CELLS, AUDIO_RATE> ahSin4(HALFSIN256_DATA);
Oscil <HALFSIN256_NUM_CELLS, AUDIO_RATE> ahSin5(HALFSIN256_DATA);

Oscil <WAVESHAPE_SIGMOID_NUM_CELLS, AUDIO_RATE> aSig1(WAVESHAPE_SIGMOID_DATA);
Oscil <WAVESHAPE_SIGMOID_NUM_CELLS, AUDIO_RATE> aSig2(WAVESHAPE_SIGMOID_DATA);
Oscil <WAVESHAPE_SIGMOID_NUM_CELLS, AUDIO_RATE> aSig3(WAVESHAPE_SIGMOID_DATA);
Oscil <WAVESHAPE_SIGMOID_NUM_CELLS, AUDIO_RATE> aSig4(WAVESHAPE_SIGMOID_DATA);
Oscil <WAVESHAPE_SIGMOID_NUM_CELLS, AUDIO_RATE> aSig5(WAVESHAPE_SIGMOID_DATA);

Oscil <PHASOR256_NUM_CELLS, AUDIO_RATE> aPha1(PHASOR256_DATA);
Oscil <PHASOR256_NUM_CELLS, AUDIO_RATE> aPha2(PHASOR256_DATA);
Oscil <PHASOR256_NUM_CELLS, AUDIO_RATE> aPha3(PHASOR256_DATA);
Oscil <PHASOR256_NUM_CELLS, AUDIO_RATE> aPha4(PHASOR256_DATA);
Oscil <PHASOR256_NUM_CELLS, AUDIO_RATE> aPha5(PHASOR256_DATA);
#define CONTROL_RATE 128 // Hz, powers of 2 are most reliable

int freq1 = 110;//base freq
int voct = 1000;//external V/OCT LSB

int freqv1 = 440;//apply voct
int freqv2 = 440;
int freqv3 = 440;
int freqv4 = 440;
int freqv5 = 440;

byte note1 = 0;//Root
byte note2 = 0;//2nd
byte note3 = 0;//3rd
byte note4 = 0;//4th
byte note5 = 0;//Root

byte inv_aply1 = 0; //0 = no inv , 1 = inv , Root
byte inv_aply2 = 0; //2nd
byte inv_aply3 = 0; //3rd
byte inv_aply4 = 0; //4th
bool inv_aply5 = 0; //0 = no output root sound , 1 = output root sound

int inv = 0;
int inv_knob = 0;
int chord = 0;
byte wave = 0;//0=saw,1=squ,2=tri,3=sin,etc...

const static float voctpow[1024] PROGMEM = {
 0,  0.004882, 0.009765, 0.014648, 0.019531, 0.024414, 0.029296, 0.034179, 0.039062, 0.043945, 0.048828, 0.05371,  0.058593, 0.063476, 0.068359, 0.073242, 0.078125, 0.083007, 0.08789,  0.092773, 0.097656, 0.102539, 0.107421, 0.112304, 0.117187, 0.12207,  0.126953, 0.131835, 0.136718, 0.141601, 0.146484, 0.151367, 0.15625,  0.161132, 0.166015, 0.170898, 0.175781, 0.180664, 0.185546, 0.190429, 0.195312, 0.200195, 0.205078, 0.20996,  0.214843, 0.219726, 0.224609, 0.229492, 0.234375, 0.239257, 0.24414,  0.249023, 0.253906, 0.258789, 0.263671, 0.268554, 0.273437, 0.27832,  0.283203, 0.288085, 0.292968, 0.297851, 0.302734, 0.307617, 0.3125, 0.317382, 0.322265, 0.327148, 0.332031, 0.336914, 0.341796, 0.346679, 0.351562, 0.356445, 0.361328, 0.36621,  0.371093, 0.375976, 0.380859, 0.385742, 0.390625, 0.395507, 0.40039,  0.405273, 0.410156, 0.415039, 0.419921, 0.424804, 0.429687, 0.43457,  0.439453, 0.444335, 0.449218, 0.454101, 0.458984, 0.463867, 0.46875,  0.473632, 0.478515, 0.483398, 0.488281, 0.493164, 0.498046, 0.502929, 0.507812, 0.512695, 0.517578, 0.52246,  0.527343, 0.532226, 0.537109, 0.541992, 0.546875, 0.551757, 0.55664,  0.561523, 0.566406, 0.571289, 0.576171, 0.581054, 0.585937, 0.59082,  0.595703, 0.600585, 0.605468, 0.610351, 0.615234, 0.620117, 0.625,  0.629882, 0.634765, 0.639648, 0.644531, 0.649414, 0.654296, 0.659179, 0.664062, 0.668945, 0.673828, 0.67871,  0.683593, 0.688476, 0.693359, 0.698242, 0.703125, 0.708007, 0.71289,  0.717773, 0.722656, 0.727539, 0.732421, 0.737304, 0.742187, 0.74707,  0.751953, 0.756835, 0.761718, 0.766601, 0.771484, 0.776367, 0.78125,  0.786132, 0.791015, 0.795898, 0.800781, 0.805664, 0.810546, 0.815429, 0.820312, 0.825195, 0.830078, 0.83496,  0.839843, 0.844726, 0.849609, 0.854492, 0.859375, 0.864257, 0.86914,  0.874023, 0.878906, 0.883789, 0.888671, 0.893554, 0.898437, 0.90332,  0.908203, 0.913085, 0.917968, 0.922851, 0.927734, 0.932617, 0.9375, 0.942382, 0.947265, 0.952148, 0.957031, 0.961914, 0.966796, 0.971679, 0.976562, 0.981445, 0.986328, 0.99121,  0.996093, 1.000976, 1.005859, 1.010742, 1.015625, 1.020507, 1.02539,  1.030273, 1.035156, 1.040039, 1.044921, 1.049804, 1.054687, 1.05957,  1.064453, 1.069335, 1.074218, 1.079101, 1.083984, 1.088867, 1.09375,  1.098632, 1.103515, 1.108398, 1.113281, 1.118164, 1.123046, 1.127929, 1.132812, 1.137695, 1.142578, 1.14746,  1.152343, 1.157226, 1.162109, 1.166992, 1.171875, 1.176757, 1.18164,  1.186523, 1.191406, 1.196289, 1.201171, 1.206054, 1.210937, 1.21582,  1.220703, 1.225585, 1.230468, 1.235351, 1.240234, 1.245117, 1.25, 1.254882, 1.259765, 1.264648, 1.269531, 1.274414, 1.279296, 1.284179, 1.289062, 1.293945, 1.298828, 1.30371,  1.308593, 1.313476, 1.318359, 1.323242, 1.328125, 1.333007, 1.33789,  1.342773, 1.347656, 1.352539, 1.357421, 1.362304, 1.367187, 1.37207,  1.376953, 1.381835, 1.386718, 1.391601, 1.396484, 1.401367, 1.40625,  1.411132, 1.416015, 1.420898, 1.425781, 1.430664, 1.435546, 1.440429, 1.445312, 1.450195, 1.455078, 1.45996,  1.464843, 1.469726, 1.474609, 1.479492, 1.484375, 1.489257, 1.49414,  1.499023, 1.503906, 1.508789, 1.513671, 1.518554, 1.523437, 1.52832,  1.533203, 1.538085, 1.542968, 1.547851, 1.552734, 1.557617, 1.5625, 1.567382, 1.572265, 1.577148, 1.582031, 1.586914, 1.591796, 1.596679, 1.601562, 1.606445, 1.611328, 1.61621,  1.621093, 1.625976, 1.630859, 1.635742, 1.640625, 1.645507, 1.65039,  1.655273, 1.660156, 1.665039, 1.669921, 1.674804, 1.679687, 1.68457,  1.689453, 1.694335, 1.699218, 1.704101, 1.708984, 1.713867, 1.71875,  1.723632, 1.728515, 1.733398, 1.738281, 1.743164, 1.748046, 1.752929, 1.757812, 1.762695, 1.767578, 1.77246,  1.777343, 1.782226, 1.787109, 1.791992, 1.796875, 1.801757, 1.80664,  1.811523, 1.816406, 1.821289, 1.826171, 1.831054, 1.835937, 1.84082,  1.845703, 1.850585, 1.855468, 1.860351, 1.865234, 1.870117, 1.875,  1.879882, 1.884765, 1.889648, 1.894531, 1.899414, 1.904296, 1.909179, 1.914062, 1.918945, 1.923828, 1.92871,  1.933593, 1.938476, 1.943359, 1.948242, 1.953125, 1.958007, 1.96289,  1.967773, 1.972656, 1.977539, 1.982421, 1.987304, 1.992187, 1.99707,  2.001953, 2.006835, 2.011718, 2.016601, 2.021484, 2.026367, 2.03125,  2.036132, 2.041015, 2.045898, 2.050781, 2.055664, 2.060546, 2.065429, 2.070312, 2.075195, 2.080078, 2.08496,  2.089843, 2.094726, 2.099609, 2.104492, 2.109375, 2.114257, 2.11914,  2.124023, 2.128906, 2.133789, 2.138671, 2.143554, 2.148437, 2.15332,  2.158203, 2.163085, 2.167968, 2.172851, 2.177734, 2.182617, 2.1875, 2.192382, 2.197265, 2.202148, 2.207031, 2.211914, 2.216796, 2.221679, 2.226562, 2.231445, 2.236328, 2.24121,  2.246093, 2.250976, 2.255859, 2.260742, 2.265625, 2.270507, 2.27539,  2.280273, 2.285156, 2.290039, 2.294921, 2.299804, 2.304687, 2.30957,  2.314453, 2.319335, 2.324218, 2.329101, 2.333984, 2.338867, 2.34375,  2.348632, 2.353515, 2.358398, 2.363281, 2.368164, 2.373046, 2.377929, 2.382812, 2.387695, 2.392578, 2.39746,  2.402343, 2.407226, 2.412109, 2.416992, 2.421875, 2.426757, 2.43164,  2.436523, 2.441406, 2.446289, 2.451171, 2.456054, 2.460937, 2.46582,  2.470703, 2.475585, 2.480468, 2.485351, 2.490234, 2.495117, 2.5,  2.504882, 2.509765, 2.514648, 2.519531, 2.524414, 2.529296, 2.534179, 2.539062, 2.543945, 2.548828, 2.55371,  2.558593, 2.563476, 2.568359, 2.573242, 2.578125, 2.583007, 2.58789,  2.592773, 2.597656, 2.602539, 2.607421, 2.612304, 2.617187, 2.62207,  2.626953, 2.631835, 2.636718, 2.641601, 2.646484, 2.651367, 2.65625,  2.661132, 2.666015, 2.670898, 2.675781, 2.680664, 2.685546, 2.690429, 2.695312, 2.700195, 2.705078, 2.70996,  2.714843, 2.719726, 2.724609, 2.729492, 2.734375, 2.739257, 2.74414,  2.749023, 2.753906, 2.758789, 2.763671, 2.768554, 2.773437, 2.77832,  2.783203, 2.788085, 2.792968, 2.797851, 2.802734, 2.807617, 2.8125, 2.817382, 2.822265, 2.827148, 2.832031, 2.836914, 2.841796, 2.846679, 2.851562, 2.856445, 2.861328, 2.86621,  2.871093, 2.875976, 2.880859, 2.885742, 2.890625, 2.895507, 2.90039,  2.905273, 2.910156, 2.915039, 2.919921, 2.924804, 2.929687, 2.93457,  2.939453, 2.944335, 2.949218, 2.954101, 2.958984, 2.963867, 2.96875,  2.973632, 2.978515, 2.983398, 2.988281, 2.993164, 2.998046, 3.002929, 3.007812, 3.012695, 3.017578, 3.02246,  3.027343, 3.032226, 3.037109, 3.041992, 3.046875, 3.051757, 3.05664,  3.061523, 3.066406, 3.071289, 3.076171, 3.081054, 3.085937, 3.09082,  3.095703, 3.100585, 3.105468, 3.110351, 3.115234, 3.120117, 3.125,  3.129882, 3.134765, 3.139648, 3.144531, 3.149414, 3.154296, 3.159179, 3.164062, 3.168945, 3.173828, 3.17871,  3.183593, 3.188476, 3.193359, 3.198242, 3.203125, 3.208007, 3.21289,  3.217773, 3.222656, 3.227539, 3.232421, 3.237304, 3.242187, 3.24707,  3.251953, 3.256835, 3.261718, 3.266601, 3.271484, 3.276367, 3.28125,  3.286132, 3.291015, 3.295898, 3.300781, 3.305664, 3.310546, 3.315429, 3.320312, 3.325195, 3.330078, 3.33496,  3.339843, 3.344726, 3.349609, 3.354492, 3.359375, 3.364257, 3.36914,  3.374023, 3.378906, 3.383789, 3.388671, 3.393554, 3.398437, 3.40332,  3.408203, 3.413085, 3.417968, 3.422851, 3.427734, 3.432617, 3.4375, 3.442382, 3.447265, 3.452148, 3.457031, 3.461914, 3.466796, 3.471679, 3.476562, 3.481445, 3.486328, 3.49121,  3.496093, 3.500976, 3.505859, 3.510742, 3.515625, 3.520507, 3.52539,  3.530273, 3.535156, 3.540039, 3.544921, 3.549804, 3.554687, 3.55957,  3.564453, 3.569335, 3.574218, 3.579101, 3.583984, 3.588867, 3.59375,  3.598632, 3.603515, 3.608398, 3.613281, 3.618164, 3.623046, 3.627929, 3.632812, 3.637695, 3.642578, 3.64746,  3.652343, 3.657226, 3.662109, 3.666992, 3.671875, 3.676757, 3.68164,  3.686523, 3.691406, 3.696289, 3.701171, 3.706054, 3.710937, 3.71582,  3.720703, 3.725585, 3.730468, 3.735351, 3.740234, 3.745117, 3.75, 3.754882, 3.759765, 3.764648, 3.769531, 3.774414, 3.779296, 3.784179, 3.789062, 3.793945, 3.798828, 3.80371,  3.808593, 3.813476, 3.818359, 3.823242, 3.828125, 3.833007, 3.83789,  3.842773, 3.847656, 3.852539, 3.857421, 3.862304, 3.867187, 3.87207,  3.876953, 3.881835, 3.886718, 3.891601, 3.896484, 3.901367, 3.90625,  3.911132, 3.916015, 3.920898, 3.925781, 3.930664, 3.935546, 3.940429, 3.945312, 3.950195, 3.955078, 3.95996,  3.964843, 3.969726, 3.974609, 3.979492, 3.984375, 3.989257, 3.99414,  3.999023, 4.003906, 4.008789, 4.013671, 4.018554, 4.023437, 4.02832,  4.033203, 4.038085, 4.042968, 4.047851, 4.052734, 4.057617, 4.0625, 4.067382, 4.072265, 4.077148, 4.082031, 4.086914, 4.091796, 4.096679, 4.101562, 4.106445, 4.111328, 4.11621,  4.121093, 4.125976, 4.130859, 4.135742, 4.140625, 4.145507, 4.15039,  4.155273, 4.160156, 4.165039, 4.169921, 4.174804, 4.179687, 4.18457,  4.189453, 4.194335, 4.199218, 4.204101, 4.208984, 4.213867, 4.21875,  4.223632, 4.228515, 4.233398, 4.238281, 4.243164, 4.248046, 4.252929, 4.257812, 4.262695, 4.267578, 4.27246,  4.277343, 4.282226, 4.287109, 4.291992, 4.296875, 4.301757, 4.30664,  4.311523, 4.316406, 4.321289, 4.326171, 4.331054, 4.335937, 4.34082,  4.345703, 4.350585, 4.355468, 4.360351, 4.365234, 4.370117, 4.375,  4.379882, 4.384765, 4.389648, 4.394531, 4.399414, 4.404296, 4.409179, 4.414062, 4.418945, 4.423828, 4.42871,  4.433593, 4.438476, 4.443359, 4.448242, 4.453125, 4.458007, 4.46289,  4.467773, 4.472656, 4.477539, 4.482421, 4.487304, 4.492187, 4.49707,  4.501953, 4.506835, 4.511718, 4.516601, 4.521484, 4.526367, 4.53125,  4.536132, 4.541015, 4.545898, 4.550781, 4.555664, 4.560546, 4.565429, 4.570312, 4.575195, 4.580078, 4.58496,  4.589843, 4.594726, 4.599609, 4.604492, 4.609375, 4.614257, 4.61914,  4.624023, 4.628906, 4.633789, 4.638671, 4.643554, 4.648437, 4.65332,  4.658203, 4.663085, 4.667968, 4.672851, 4.677734, 4.682617, 4.6875, 4.692382, 4.697265, 4.702148, 4.707031, 4.711914, 4.716796, 4.721679, 4.726562, 4.731445, 4.736328, 4.74121,  4.746093, 4.750976, 4.755859, 4.760742, 4.765625, 4.770507, 4.77539,  4.780273, 4.785156, 4.790039, 4.794921, 4.799804, 4.804687, 4.80957,  4.814453, 4.819335, 4.824218, 4.829101, 4.833984, 4.838867, 4.84375,  4.848632, 4.853515, 4.858398, 4.863281, 4.868164, 4.873046, 4.877929, 4.882812, 4.887695, 4.892578, 4.89746,  4.902343, 4.907226, 4.912109, 4.916992, 4.921875, 4.926757, 4.93164,  4.936523, 4.941406, 4.946289, 4.951171, 4.956054, 4.960937, 4.96582,  4.970703, 4.975585, 4.980468, 4.985351, 4.990234, 4.995117
};
const static byte chord_table[8][4]PROGMEM = {
 {  0,  68, 119,  205,  },//Maj
 { 0,  68, 119,  187,  },//Maj7
 { 0,  68, 119,  239,  },//Majadd9
 { 0,  34, 119,  205,  },//sus2
 { 0,  51, 119,  239,  },//minadd9
 { 0,  51, 119,  170,  },//min7
 { 0,  51, 119,  205,  },//min
 { 0,  0,  0,  0,  }//root
};

void setup()
{
 startMozzi(CONTROL_RATE); // :)
}
void updateControl() {
 //chord setting
 chord = (mozziAnalogRead(3) / 128) + (mozziAnalogRead(5) / 128);
 chord = constrain(chord, 0, 7);

 //inversion setting
 inv_knob = mozziAnalogRead(1);
 inv = (inv_knob  / 64)+ (mozziAnalogRead(4) / 64);
 inv = constrain(inv, 0, 15);

 if (inv_knob < 1020) { //when selecting wave , not apply
   switch (inv) {
     case 0:
       inv_aply1 = 0;
       inv_aply2 = 0;
       inv_aply3 = 0;
       inv_aply4 = 0;
       inv_aply5 = 0;
       break;

     case 1:
       inv_aply1 = 1;
       inv_aply2 = 0;
       inv_aply3 = 0;
       inv_aply4 = 0;
       inv_aply5 = 0;
       break;

     case 2:
       inv_aply1 = 1;
       inv_aply2 = 1;
       inv_aply3 = 0;
       inv_aply4 = 0;
       inv_aply5 = 0;
       break;

     case 3:
       inv_aply1 = 1;
       inv_aply2 = 1;
       inv_aply3 = 1;
       inv_aply4 = 0;
       inv_aply5 = 0;
       break;

     case 4:
       inv_aply1 = 1;
       inv_aply2 = 1;
       inv_aply3 = 1;
       inv_aply4 = 1;
       inv_aply5 = 0;
       break;

     case 5:
       inv_aply1 = 2;
       inv_aply2 = 1;
       inv_aply3 = 1;
       inv_aply4 = 1;
       inv_aply5 = 0;
       break;

     case 6:
       inv_aply1 = 2;
       inv_aply2 = 2;
       inv_aply3 = 1;
       inv_aply4 = 1;
       inv_aply5 = 0;
       break;

     case 7:
       inv_aply1 = 2;
       inv_aply2 = 2;
       inv_aply3 = 2;
       inv_aply4 = 1;
       inv_aply5 = 0;
       break;

     case 8:
       inv_aply1 = 2;
       inv_aply2 = 2;
       inv_aply3 = 2;
       inv_aply4 = 1;
       inv_aply5 = 1;
       break;

     case 9:
       inv_aply1 = 2;
       inv_aply2 = 2;
       inv_aply3 = 1;
       inv_aply4 = 1;
       inv_aply5 = 1;
       break;

     case 10:
       inv_aply1 = 2;
       inv_aply2 = 1;
       inv_aply3 = 1;
       inv_aply4 = 1;
       inv_aply5 = 1;
       break;

     case 11:
       inv_aply1 = 1;
       inv_aply2 = 1;
       inv_aply3 = 1;
       inv_aply4 = 1;
       inv_aply5 = 1;
       break;

     case 12:
       inv_aply1 = 1;
       inv_aply2 = 1;
       inv_aply3 = 1;
       inv_aply4 = 0;
       inv_aply5 = 1;
       break;

     case 13:
       inv_aply1 = 1;
       inv_aply2 = 1;
       inv_aply3 = 0;
       inv_aply4 = 0;
       inv_aply5 = 1;
       break;

     case 14:
       inv_aply1 = 1;
       inv_aply2 = 0;
       inv_aply3 = 0;
       inv_aply4 = 0;
       inv_aply5 = 1;
       break;

     case 15:
       inv_aply1 = 0;
       inv_aply2 = 0;
       inv_aply3 = 0;
       inv_aply4 = 0;
       inv_aply5 = 1;
       break;
   }
 }
 //setting chord note
 if (inv_knob < 1020) { //when selecting wave , not apply
   note1 = (pgm_read_byte(&(chord_table[chord][0])));
   note2 = (pgm_read_byte(&(chord_table[chord][1])));
   note3 = (pgm_read_byte(&(chord_table[chord][2])));
   note4 = (pgm_read_byte(&(chord_table[chord][3])));
   note5 = (pgm_read_byte(&(chord_table[chord][0])));
 }

 //OSC frequency knob
 freq1 = mozziAnalogRead(0) / 4 ;

 //set wave
 if (inv_knob >= 1020) { //inv knob max
   wave = (mozziAnalogRead(3) / 128);
 }

 //frequency setting
 voct = mozziAnalogRead(7) ;
 freqv1 = freq1 * pow(2, (pgm_read_float(&(voctpow[voct + 205 * inv_aply1 + note1])))); //ROOT
 freqv2 = freq1 * pow(2, (pgm_read_float(&(voctpow[voct + 205 * inv_aply2 + note2])))); //2nd
 freqv3 = freq1 * pow(2, (pgm_read_float(&(voctpow[voct + 205 * inv_aply3 + note3])))); //3rd
 freqv4 = freq1 * pow(2, (pgm_read_float(&(voctpow[voct + 205 * inv_aply4 + note4])))); //4th
 freqv5 = freq1 * pow(2, (pgm_read_float(&(voctpow[voct + note5])))); //ROOT

 switch (wave) {
   case 0://saw
     aSaw1.setFreq(freqv1); // set the frequency
     aSaw2.setFreq(freqv2);
     aSaw3.setFreq(freqv3);
     aSaw4.setFreq(freqv4);
     aSaw5.setFreq(freqv5);
     break;

   case 1://squ
     aSqu1.setFreq(freqv1); // set the frequency
     aSqu2.setFreq(freqv2);
     aSqu3.setFreq(freqv3);
     aSqu4.setFreq(freqv4);
     aSqu5.setFreq(freqv5);
     break;

   case 2://tri
     aTri1.setFreq(freqv1); // set the frequency
     aTri2.setFreq(freqv2);
     aTri3.setFreq(freqv3);
     aTri4.setFreq(freqv4);
     aTri5.setFreq(freqv5);
     break;

   case 3://sin
     aSin1.setFreq(freqv1); // set the frequency
     aSin2.setFreq(freqv2);
     aSin3.setFreq(freqv3);
     aSin4.setFreq(freqv4);
     aSin5.setFreq(freqv5);
     break;

   case 4://
     aChb1.setFreq(freqv1); // set the frequency
     aChb2.setFreq(freqv2);
     aChb3.setFreq(freqv3);
     aChb4.setFreq(freqv4);
     aChb5.setFreq(freqv5);
     break;

   case 5://
     ahSin1.setFreq(freqv1); // set the frequency
     ahSin2.setFreq(freqv2);
     ahSin3.setFreq(freqv3);
     ahSin4.setFreq(freqv4);
     ahSin5.setFreq(freqv5);
     break;

   case 6://
     aSig1.setFreq(freqv1); // set the frequency
     aSig2.setFreq(freqv2);
     aSig3.setFreq(freqv3);
     aSig4.setFreq(freqv4);
     aSig5.setFreq(freqv5);
     break;

   case 7://
     aPha1.setFreq(freqv1); // set the frequency
     aPha2.setFreq(freqv2);
     aPha3.setFreq(freqv3);
     aPha4.setFreq(freqv4);
     aPha5.setFreq(freqv5);
     break;
 }
}

int updateAudio() {
 switch (wave) {

   case 0:
     return MonoOutput::from8Bit(aSaw1.next() / 32 + aSaw2.next() / 32 + aSaw3.next() / 32 + aSaw4.next() / 32 + aSaw5.next() / 32 * inv_aply5);
     break;

   case 1:
     return MonoOutput::from8Bit(aSqu1.next() / 32 + aSqu2.next() / 32 + aSqu3.next() / 32 + aSqu4.next() / 32 + aSqu5.next() / 32 * inv_aply5);
     break;

   case 2:
     return MonoOutput::from8Bit(aTri1.next() / 32 + aTri2.next() / 32 + aTri3.next() / 32 + aTri4.next() / 32 + aTri5.next() / 32 * inv_aply5);
     break;

   case 3:
     return MonoOutput::from8Bit(aSin1.next() / 32 + aSin2.next() / 32 + aSin3.next() / 32 + aSin4.next() / 32 + aSin5.next() / 32 * inv_aply5);
     break;

   case 4:
     return MonoOutput::from8Bit(aChb1.next() / 32 + aChb2.next() / 32 + aChb3.next() / 32 + aChb4.next() / 32 + aChb5.next() / 32 * inv_aply5);
     break;

   case 5:
     return MonoOutput::from8Bit(ahSin1.next() / 32 + ahSin2.next() / 32 + ahSin3.next() / 32 + ahSin4.next() / 32 + ahSin5.next() / 32 * inv_aply5);
     break;

   case 6:
     return MonoOutput::from8Bit(aSig1.next() / 32 + aSig2.next() / 32 + aSig3.next() / 32 + aSig4.next() / 32 + aSig5.next() / 32 * inv_aply5);
     break;

   case 7:
     return MonoOutput::from8Bit(aPha1.next() / 32 + aPha2.next() / 32 + aPha3.next() / 32 + aPha4.next() / 32 + aPha5.next() / 32 * inv_aply5);
     break;

 }
}
void loop() {
 audioHook(); // required here
}

(Yeah, it's still a lot...)
Any assistance in resolving this would be greatly appreciated!

I don't get a compilation error with your sketch. try to reinstall the library.

Thanks for verifying! Most people don't seem to get the error, but I do consistently (even across two different machines) and other people have hit this in the past. Maybe I should re-install the IDE?

how did you install the library?

I don't recall; I think I used the Add .zip library inside the IDE.

The IDE is an editor. Reinstalling it will not change the compilation. Delete the library in sketchbbok's library folder, download and install it again

Got it! I was downloading Mozzi from 'releases'  on GitHub rather than Mozzi-master.zip. This was what was causing the errors (though all the examples in the lib compiled correctly). All is good now. Post an answer and I'll happily mark it answered!

I don't get a compilation error with your sketch with the latest git version.
If you installed the release version, delete the library in sketchbbok's library folder and download and install the latest git version.

Perfect, thanks!

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


text:
How to turn led lights off and on in order when below a certain photovalue?
I'm making a traffic light simulation with a photoresistor but it's not working properly.
When the photovalue drops below a certain point ( a car comes by) a peeping sound should play for a second and then red light should turn into yellow light and then it should turn green and stay green until the photovalue is back to normal, and then it should turn red again and stay red until the photovalue drops below that point again ( photovalue goes back to normal when the car moves) . I tried different, but did not get the result I was hoping for, the yellow light kept pulsing instead of actually turning off, the green light was turned on but it did not turn off when it was supposed to. In my recent attempt, the green light is not turning off, while red and yellow turn off on. What have I done wrong and how do I fix it?
here's my code for the last attempt.

byte PhotoInput= 0;
int PhotoValue;
int Pin = 8;
void PlayTone( int freq,  int duration) {

delay( duration);
tone ( Pin ,freq, duration );

}

int red = 10;
int yellow= 7;
int green= 5;

 void setup() {
  pinMode(red, OUTPUT);
  pinMode( yellow, OUTPUT);
  pinMode( green, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  PhotoValue = analogRead(PhotoInput);
    ;Serial.println(PhotoValue);
    delay(50);

    if ( PhotoValue < 100 ) {
      digitalWrite  (red, HIGH);
      delay ( 500);
      digitalWrite ( red,LOW);
      digitalWrite (yellow,HIGH);
      delay(1000);
      PlayTone( 100, 50);

      digitalWrite(green,HIGH);
     digitalWrite ( yellow, LOW);

    }else if ( PhotoValue > 100) {
       digitalWrite ( red,HIGH);
      digitalWrite(yellow,LOW);
      digitalWrite(green,LOW);

    }

   if (PhotoValue > 50 ){
    PlayTone( 100, 50);
   }else if ( PhotoValue > 60 )   {
    PlayTone ( 300, 50);
   }else if ( PhotoValue > 120 )   {
    PlayTone ( 600, 50);
    }else if ( PhotoValue > 160) {
    PlayTone ( 900, 50);
    }else if ( PhotoValue < 180 )   {
    PlayTone ( 1100, 50);
    }else if ( PhotoValue > 200)   {
    PlayTone ( 1300, 50);
    }else if ( PhotoValue < 240 )   {
    PlayTone ( 1600, 50);
    }else if ( PhotoValue > 260 )   {
    PlayTone ( 1000, 50);
    }else if ( PhotoValue < 80 )   {
    PlayTone ( 600, 50);
   }
}

Just did that, thanks for pointing it. I'm new to both arduino and this community so I really don't know what's important to mention and what's not.

What happens if you remove this delay( duration) line of code?

you have no code for stay green until the photovalue is back to normal

do you understand that loop() repeats until the Arduino is reset? .... look at your code closely ... if you cover the sensor then yellow will blink and green will turn on and stay on

if you want a section of code to run only once for an action, then you have to use flags

your difficulty arises because of the way that you handle program flow after reading the sensor ... if (bright) then turn on red LED is an inflexible way of doing it .... insert a layer of separation between sensing and acting ... use flags ... try if (bright) then set isBright flag ... if (dim) then set isDim flag ... if (isDim and isBright) then unset isBright; blink yellow LED .... this way the yellow LED blinks only once whenever the sensor detects dim light

I don't really know what flags are in arduino, as said earlier I'm new to this. But assuming from what you said I need to break down the process. It first has to sense the photo value and then it will act based on what follows after the flag for both dim and bright. By creating an if statement for both dim and bright it should become more flexible.  But isn't that harder than actually making and if statement where the yellow led is dependent on the green led. Is there any youtube you recommend on how flags function. @jsotola ?

isn't that harder than actually making and if statement where the yellow led is dependent on the green led ... but what is your green LED dependent on?

what flags are in arduino ... not Arduino ... in any programming language ... a flag is just a variable that you set to a specific value to remember something, such as bool isBright = true; ... in real life it could be a note stuck on a fridge or an appointment written in a calendar ... or even a traffic light

To make this simpler I've taken away the buzzer from the code to just concentrate on the lights (from your diagram the buzzer wasn't connected anyway!). I've also tried to keep as much of your code as possible, and just introduce a single flag that is set to true when a car is detected.
When the program first starts car_detected is false and the red light is switched on in the setup() code. When the PhotoValue has a low value (<100) then it will set car_detected to true and go through the sequence of lights, with green finally switching on. Whilst the light input is low, it will see the car_detected flag remains true and won't perform any further actions.
When the car moves away and the PhotoValue is high again (>100) then the flag is cleared, and the red light is switched on again. Again - because of the flag, no further action will take place until the light level changes again.
This is a simplistic example of how you can use a flag to control the state of your program and hopefully will allow you to progress.
byte PhotoInput=0;
int PhotoValue;
bool car_detected = false ;

int red = 10;
int yellow= 7;
int green= 5;

void setup() {
  pinMode(red, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(green, OUTPUT);

  digitalWrite(red,HIGH);
  digitalWrite(yellow,LOW);
  digitalWrite(green,LOW);

  Serial.begin(9600);
}

void loop() {

  PhotoValue = analogRead(PhotoInput);
  Serial.println(PhotoValue);

  if ( PhotoValue < 100 ) {

    if ( !car_detected ) {
      car_detected = true ;

      digitalWrite(red, HIGH);
      delay (500);
      digitalWrite(red,LOW);
      digitalWrite(yellow,HIGH);
      delay(1000);

      digitalWrite(green,HIGH);
      digitalWrite(yellow, LOW);
    }
  }else if ( PhotoValue >= 100) {
    if ( car_detected ) {
      car_detected = false ;
      digitalWrite(red,HIGH);
      digitalWrite(yellow,LOW);
      digitalWrite(green,LOW);
    }
  }
}


text:
Do these bit settings all mean the same?
ADMUX  = ADMUX | _BV(REFS);  // uncompounded bitwise OR
ADMUX |= _BV(REFS0);         // #define _BV(bit) (1 << (bit))
ADMUX |= bit(REFS0);         // #define bit(b) (1UL << (b))
bitSet(ADMUX, REFS0);        // #define bitSet(value, bit) ((value) |= (1UL << (bit)))
sbi(ADMUX, REFS0);           // deprecated assembly?
ADMUX |= (1 << REFS0);       // shift operator
ADMUX |= (1 << 7);           // bit 7 is named REFS0
ADMUX |= 0b10000000;         // bin
ADMUX |= 0x80;               // hex
ADMUX |= 128;                // dec

*under normal 8 bit Arduino circumstances?

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

You already got an answer in the comments but, just to make double sure,
I tried compiling all these statements for an Uno, and they got all
translated into the exact same machine code. Well, almost: I had to do
some minor adjustments, which I believe are unrelated to the essence of
your question. Just for completeness, I changed the following:

I replaced REFS0 by REFS1: on an Uno, REFS0 is bit 6, and REFS1
is bit 7.

I replaced REFS by REFS1, as the former is not defined.

I #included <compat/deprecated.h>, otherwise I get the error
“'sbi' was not declared in this scope”.


text:
Strange problems driving an Optocoupler (PC123) with a Nano
I'm having some strange issues getting a Nano to drive a PC123 optocoupler properly.
What I'm trying to do: In the real world, I need to press a button ONCE, and have the device that I'm connecting this too, see FIVE quick button presses... (Input 1 press, and Output 5 presses, at the timing I set in the code). I am using a mix of LED "Blinking / Flashing" code to do what I need.
My connection of the Opto seems fine. It works perfectly if I run this "BLINK" code: (With the PC123 optocoupler connected to Pin13):
// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(200);                       // wait for a while
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(200);                       // wait for a while
}

When I run this, the Optocoupler turns ON and OFF as I need, and the device I am controlling is happy, but it obviously runs forever as I have no counters or anything.. (This proves my hardware is good at this point!)
But, when I try this following code, with the exact same hardware circuit, the output goes HIGH as soon as I ground Pin2, and it stays HIGH! It holds the optocoupler ON and there is no ON/OFF or "blinking or flashing". BUT, it only does this when the OPTO is connected (there is load) on the Nano output. If I disconnect the Opto, the Pin13 LED will flash as expected. And my code seems to work fine (on the on-board Pin 13 LED).
VERY interestingly and very strangley though, when the "power-up" Pin 13 LED flashes (i.e- when you power cycle the Nano, or press the reset button) this will trigger the Opto ON/OFF perfectly! But when the code starts to run, via my Pin 2 input switch, with the Opto connected to the Nano, the output locks HIGH again! What the!?
int ledPin = 13;   // LED is connected to digital pin 13
int switchPin = 2;   // switch connected to digital pin 2
int switchValue;   // a variable to keep track of when switch is pressed
int counter = 0;

void setup()
{
      pinMode(ledPin, OUTPUT);   // sets the ledPin to be an output
      pinMode(switchPin, INPUT);   // sets the switchPin to be an input
      digitalWrite(switchPin, HIGH);   // sets the default (unpressed) state of switchPin to HIGH
}

void loop()   // run over and over again
{

    switchValue = digitalRead(switchPin);   // check to see if the switch is pressed
      if ((switchValue == LOW) && (counter <= 1)) {   // if the switch is pressed then,
          for(int ii = 0; ii <= 5; ii++)   // 7 = 4 flashes, 5 = 3 flashes, etc
      {
          digitalWrite(ledPin, !digitalRead(ledPin));
          delay(100); // Length of the flashes in ms
          counter++;
      }
    }
      if (switchValue == HIGH)
      //if ((switchValue == HIGH) && (counter > 2))
      {
           counter = 0;
           delay(100); // Debounce

      }
}

I have tried filtering capacitors, diodes, resistance, pull-ups, pull-downs, everything I can think of and I am at a loss. Can anyone help me out? I'm thinking its a code issue (because I am an Arduino noob - please be gentle!), or a maybe a deficiency in the hardware of the Nano? FYI, I have done all of this on different Input and Output pins with the same results.
Any help would be greatly appreciated!

you have digitalWrite(switchPin, HIGH) which activates the internal pull-up resistor

Yes, but isn't that required for my LOW switch (D2) to trigger the code? Otherwise it will float?
Also, it works with no load (with the Opto not connected). It will flash the Pin 13 led fine. But with the load on the output (Pin13 - or any other pin I choose), the output goes HIGH when the code runs and stays HIGH.

I tried changing digitalWrite(switchPin, HIGH)  to LOW, and also removed it all together. Regardless of this, triggering the D2 input always results in the same thing...
Is the counter code correct? Maybe its getting stuck in the counter loop somehow??

just a note about comments in code ..... digitalWrite(switchPin, HIGH);   // sets the default (unpressed) state of switchPin to HIGH ... the comment is misleading ... while it is technically true, because it enables the pullup resistor, a beginner programmer may think that digitalWrite(switchPin, LOW); sets a default state of the pin to LOW

why aren't you using the same code to blink the led in the second program? ... the second program makes an assumption about the state of the output pin ... set the state instead of inverting previous state

Thanks for the reply. I understand the pull-up code and the pin state as a result. That's all ok.
Why am I not using the blink code that works? Because it doesn't do what I need.  I'm a new and I don't know how to make that code start and stop using a momentary button input, and to have it only flash five times when I do press that button...
If you can help me with that I would be most grateful. Cheers

Thank you @DrG for your excellent reply! I really appreciate the time you have taken on this. I will answer your questions here:

What am I trying to do? I am adding the Nano to a Ham Radio Transceiver, that can change frequency (via button presses on the microphone) in only 1kHz, or 10kHz frequency steps. What I am doing here, is by adding this Nano to the microphone button circuit, and selecting the "1kKz" step option, I will get a "5kHz" step! This is great for searching for SSB signals quicky (1kHz is slow, 10kHz is too big and you miss some!). So, I press 1 time, the radio will step 5 times. This is the purpose of my project. :)

How have I wired it up? Exactly the same as you have shown, and I have also used both D13 (not recommended as you said, and D10 (as you have used in your proposed answer).

Your code is great, and I really like that it will use D13 to show what it's doing on the LED, and use D10 to drive the Opto. GREAT!

Now - here is the crazy part... Even with your code, and the exact circuit (other than my PC123 vs your 4N25 (I have 4N35's here too), I get exactly the same problem I had before! As soon as the Nano drives the Opto, regardless of the GPIO I configure, it locks HIGH! The D13 LED flashes as expected, but D10 goes high and never goes low again, until a reboot or power cycle...
I now believe that even my original code is fine (not the best way to do it, but still functional) but my NANO is faulty! It's an "ELEGOO NANO" clone. And I think it's the issue!!!
Your input is not wasted as I will use your code, it is much better than mine! :) I am going to get a new NANO and try this again, and now I am pretty confident that with a new Arduino, this will work! I will report back and let you know how it goes.
Best regards,
Pez

I confess that I am not sure what you are trying to do, but I have an idea and I hope this helps. First, there are several Nanos and not all of them are AVR-based. I used an OLD Nano clone and even had to select the ATMega 328P (old bootloader) - it's been a while. I also used a 4N25 opto [this could make a difference, look at the data sheet for your device)..
You have not shown exactly how you have things wired up. Let's assume that it is like this - and I DO NOT think it is a good way of doing things (bear with me), and

Using this code, it works exactly as it should.
int ledPin = 13;
int switchPin = 2;
int nflashes=10;
void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(switchPin, INPUT);
}

void loop() {
  if ( digitalRead(switchPin)==HIGH) {
  for (int i = 0; i < nflashes; i++) {
      digitalWrite(ledPin, !digitalRead(ledPin));
      delay(100);
    }
    while (digitalRead(switchPin) == HIGH); // wait until switch is released
  }
}

The opto turns on with D13 lighting the added LED and the onboard LED also turns on. Note that the onboard LED is dimmer because you are driving TWO LEDs ; the onboard one attached to D13 and the LED inside the opto and you have no current limiting resistor on the opto LED. I'm not sure if you have it wired this way but if so, in my view, it is not a good way of doing things.
Apart from that, think about what happens when you hit reset...my guess is that the ATMega sets all GPIO to input AND the boot loader initializes the onboard LED to an output and apparently flashes that LED - I am guessing and have not gone through the code. I notice that with the above scheme, I see both the new LED and the onboard LED flash once briefly on reset, as I would expect.
Hooking up the switch as I have shown (pulled to ground) will eliminate any problems from floating states during a reset. It will only be read HIGH when you press the switch after you initialize the GPIO.

I would put the opto on a separate GPIO like this:

...and using this slightly modified code
int ledPin = 13;
int switchPin = 2;
int optoPin=10;
int nflashes=10;
void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(switchPin, INPUT);
  pinMode(optoPin, OUTPUT);
}

void loop() {
  if ( digitalRead(switchPin)==HIGH) {
  for (int i = 0; i < nflashes; i++) {
      digitalWrite(ledPin, !digitalRead(ledPin));
      digitalWrite(optoPin, !digitalRead(optoPin));
      delay(100);
    }
    while (digitalRead(switchPin) == HIGH); // wait here until switch is released
  }
}

Everything works fine and the new LED does not flash during a reset and nothing gets stuck.
I wish you had show exactly what connections you made and I apologize if I missed some point.
Again, hope it helps.

Thank you @DrG for your excellent reply!  I will answer your questions in a new "answer" because I can't type enough characters here...


text:
Why does the Arduino UNO have a separate power port if USB also powers it?
Can you power the Arduino off a USB cable alone, without using the regular power connection? If so, what's the point of the additional power connection: to provide extra power?
Also Why not just have two usb ports one for power one for connecting to the computer, or a micro usb.

As Hyperbola pointed out, the USB port function is primarily to allow for programming the board. Now, since the USB port has the power cables too, it is convenient to power the device from the USB port.
The main drawback of USB port powering, however, is that it can supply a limited current: usually the USB2 ports can deliver up to 500mA before shutting down. In order for the arduino board to be compliant with this, consequently, a 500mA fuse was put on the board just after the 5V usb input.
Now, what if your final circuit requires more than 500mA? Will you have to change board? Of course not! you can just use the external power input to power the arduino board and all the other circuitry without worrying about the 500mA limitation. Of course the onboard regulator has limits too, but you have more flexibility.
Moreover portable applications run on batteries. No battery can supply exactly 5V (usually alkaline ones deliver 1.5V per battery, while lithium have usually 3.7V/cell, but this varies over time). Consequently they put an onboard regulator for providing 5V from any 6.5V+ source.
Summarizing: the USB power is convenient, since you will usually power it from the PC when programming. An external connector, however, is very important because it gives you more flexibility when choosing the power supply. You don't have to use both: you can just choose the most suitable for your needs.

thanks this answers my question in addition to the comments and pictures by Robert Cole.

So, what's the MAX voltage I can provide to Arduino ?

@HenriquedeSousa this highly depends on your arduino board and project. For instance, on the UNO there is an NCP1117 after a silicon diode. Let's say your application draws 75mA total (so including also the arduino board). Let's suppose the board will stay at max 30°C; this means that the junction can rise by 120°C.
The calculations are: Rth = 160°C/W -> MaxPower = 120°C/160°C/W = 0.75W -> MaxDeltaV = 0.75W/75mA = 10V; Max input voltage = 5V + 10V + 0.7V = 15.7V. The input voltage of the regulator is max 20V, so the power one is the max one.

@HenriquedeSousa please consider that the calculations provided are just one example. For instance, if the current is 250mA instead of 75 the max voltage gets down to 8,7V. If, on the other hand, you change the board this will also change: for instance if you use a pro mini 5v instead of uno, at 75mA you will be able to use max 10,7V (since the regulator is different)

Can you power the Arduino off a USB cable alone, without using the
  regular power connection?

You can use the USB cable alone to power the board.

If so, what's the point of the additional power connection: to provide
  extra power?

You can use either to power the board. By using just the power plug you can make your Arduino portable by using a battery box or power it via a wall plug.

Also Why not just have two usb ports one for power one for connecting
  to the computer, or a micro usb.

Only ONE USB is needed to power and program.

Arduino, in its very esence, is an embedded system and can be used as a standalone device. The USB port is provided for:

To power up the device.
To program it through a computer i.e. dump the sketch on it which one can program in the Arduino IDE.

Once you have dumped the program on it, it will stay on it forever unless you change/erase it and hence you can use the Arduino anywhere without actually bringing a computer (USB port) along.

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


text:
nrf24l01 (8pin) + adapter board (10pin) oops?
I just got my first arduino boards and have been learning the basics (so I know very little). I got the 2.4GHz NRF24L01+ (this one: NRF24L01+) and along with it a breakout board (this one: NRF24L01+ board) which I didn't realize was 10pin (nor that there is an 8pin version) vs the wireless board's 8pin. So my question is, is it safe to connect the module to this adapter board in some way? From the pinout of both I would assume not, since for example the bottom two pins on the board are ground (and therefore connected together) and the ground pin on the NRF24L01+ is next to the VCC (NRF24L01+ pinout) and the top two on the board are both VCC 3.3 and from what I can tell by looking at the etched lines, it seems it leads to the resistors (not sure if they are resistors or what, like I said, I know very little still). There seems to be an LED on this board as well, connected to the AMS1117 chip (that's a voltage regulator, correct?).
So, I am guessing I cannot just connect the NRF24L01+ to the adapter board straight in, right? But, can it with some wires? Would that even make sense? Also, is this board even necessary for anything? I bought it having read something somewhere (been reading too much to keep track of where exactly) that recommended it, but a tutorial I saw today didn't make use of it, instead just soldering a capacitor to two of the pins saying some other place recommended it to reduce noise.

To be honest, I don't see much added value for this breakout board.
First, as you mentioned, you won't be able to plug your NRF24 directly into it because the pinout is not compatible; hence, you will have to use wires for that. But you could as well use wires directly from your Arduino to the NRF24 module.
Second, regarding power (you are right, AMS1117 is a voltage regulator), the Arduino 3.3V pin is enough (50mA for UNO) to power your NRF24 as its current consumption is low (max 13.5mA as per the datasheet):

Please note these are specifications for the chip itself not for the board, which may need a bit more current, but not much more according to my own experiments.
As a side note, I have created my own very simple breakout for the NRF24 board, with just a tiny piece of stripboard, that's something you can easily do by yourself if you have the right tools (saw, cutter, soldering iron), a few pin headers and some stripboard scrap:

Last, the only utility I see with your breakout board is to be used as 3.3V supply for higher currents in future experiments.
EDIT:
as commented by @Hans-Neve, a capacitor would be useful between 3.3V and GND pins, as near the NRF24L01 board as possible, so that short consumption peaks do not impact correct function of the board. The breakout board has one (or more exactly 2: 100nF and 10uF) It is advised you add those two (at least the large 10uF cap) in your circuit. I saw some people directly soldering one cap on the pins of the NRF24 board, but if you use short enough wires to connect it, you can perfectly put this cap on a breadboard during your experiments.

The 3v3 supply from arduino should be OK for this module yes, only that some burst transmission might benefit a capacitor close to the power pins on the module. The higher power modules will work with power from arduino but will under perform due to drawing too much, here the capacitor is needed as it will smooth out the current bursts.

@HansNeve thanks I have edited my answer accordingly.

So does the breakout board have that capacitor already in the right spot? say if I use wires from the NRF to the board, will that have the correct effect?

@insaner from the breakout picture, I'd say yes, but as soon as you use wires to connect to your NRF24, it won't be as good. At least, you'll need to use short wires (10cm should be the maximum, those are easy to find with the right M/F connectors). Note that it is not possible to provide a "mathematical" rule to this, the only rules that prevail are "the nearer the cap the better" and "if it fails, try to shorten distance further (and possibly change cap values)". This is often a "trial and error" approach here.

It's also worth mentioning that Megas tend to have especially crappy 3.3V regulators and you should really use a capacitor (fairly large one 100+uF electrolytic) to ensure smooth operation.

OK, I will have all those things in mind. Thanks everyone!


text:
How to connect to AWS iot?
I am trying to connect esp8266-12f to aws iot core following this tutorial. Below is my code.
main.cpp
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "config.h"
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>

#define wifi_status_led_pin 14
#define server_status_led_pin 12

using string = std::string;

#define AWS_IOT_MQTT_PORT 8883

WiFiClientSecure net;
BearSSL::X509List cert(AWS_CERT_CA);
BearSSL::X509List client_crt(AWS_CERT_CRT);
BearSSL::PrivateKey key(AWS_CERT_PRIVATE);
PubSubClient client(net);

void configAWS()
{
  // net.setInsecure();
  net.setTrustAnchors(&cert);
  net.setClientRSACert(&client_crt, &key);
  client.setServer(AWS_IOT_ENDPOINT, AWS_IOT_MQTT_PORT);

  while (!client.connected(THINGNAME))
  {
    Serial.println("Connecting to AWS");
    digitalWrite(server_status_led_pin, HIGH);
    delay(500);
    digitalWrite(server_status_led_pin, LOW);
    delay(500);
  }

  if (client.connected() && client.connect(THINGNAME))
  {
    client.subscribe(AWS_IOT_SUBSCRIBE_TOPIC);
    client.setCallback(messageHandler);
    Serial.println("AWS IoT connected!");
    digitalWrite(server_status_led_pin, HIGH);
  }
}

void setup() {
  Serial.println("setup");
  pinMode(wifi_status_led_pin, OUTPUT);
  pinMode(server_status_led_pin, OUTPUT);
  Serial.begin(9600);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.println("wifi connecting");
    digitalWrite(wifi_status_led_pin, HIGH);
    delay(300);
    digitalWrite(wifi_status_led_pin, LOW);
    delay(300);
  }
  digitalWrite(wifi_status_led_pin, HIGH);
  Serial.println("connected network");
  configAWS();
  pinMode(door1_open_pin, OUTPUT);
  pinMode(door1_status_pin, INPUT);
  door1_previous_state = digitalRead(door1_status_pin);
}

void loop() {
}

config.h
#include <pgmspace.h>

#define SECRET
#define THINGNAME "THINGNAME " // change this

const char WIFI_SSID[] = "mywifi";     // change this
const char WIFI_PASSWORD[] = "password"; // change this
const char AWS_IOT_ENDPOINT[] = "XXXXXXXXX-ats.iot.us-east-2.amazonaws.com";

// Amazon Root CA 1
static const char AWS_CERT_CA[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
ca cert
-----END CERTIFICATE-----
)EOF";

// Device Certificate
static const char AWS_CERT_CRT[] PROGMEM = R"KEY(
-----BEGIN CERTIFICATE-----
my cert
-----END CERTIFICATE-----
)KEY";

// Device Private Key
static const char AWS_CERT_PRIVATE[] PROGMEM = R"KEY(
-----BEGIN RSA PRIVATE KEY-----
mykey
-----END RSA PRIVATE KEY-----
)KEY";

The cert should have no problem since I also tried esp32 with same cert and thing and it success. But in esp8266, I cannot connect to aws and keep logging "Connecting to AWS".
I am not sure it matters, but I am using platformio and only board esp12e instead of 12f is avaliable.
my ini file below,
[env:esp12e]
platform = espressif8266
board = esp12e
framework = arduino
lib_deps =
    bblanchon/ArduinoJson@^6.20.1
    knolleary/PubSubClient@^2.8
    ESP8266WiFi @ ^1.0


text:
IOT-GA6 gsm module Arduino +CME error 58
I've recently bought a IOT-GA6 gsm module . I want to use it to send an mms but doesn't work.
The SMS and call work.
When I execute the void function (mms) the monitor shows the error message +CME EYROR:58.
Does anybody know what this means and how to solve it?

this is my code
include SoftwareSerial.h
include SD.h

define  CS    4

SoftwareSerial A6Module(2, 3);

File dataFile;

int i;

unsigned char data=0;

void setup()
{
  pinMode(PWR,OUTPUT);
  pinMode(CS,OUTPUT);

  A6Module.begin(115200);
  Serial.begin(115200);

  digitalWrite(PWR,LOW);
  delay(10);

  digitalWrite(PWR,HIGH);
  delay(10);

  if (!SD.begin(CS)) Serial.println("initialization failed!");
  else Serial.println("initialization done.");
}

void loop()
{
  if(Serial.available())
  {
    while(Serial.available())
    {
      data=Serial.read();
      Serial.write(data);
      Serial.println("\n");
    }
    //data=0;
  }

  if(Serial.available())
  {
    data=Serial.read();
  }

  if(data=='1')
  {
    A6Module.println("AT+CGMI\r"); //Manufacturer identification
  }

  if(data=='2')
  {
    A6Module.println("AT+CGMM\r"); //Model identification
  }

  if(data=='3')
  {
    A6Module.println("AT+CGMR\r"); //Software version
  }

  if(data=='4')
  {
    A6Module.println("AT+CGSN\r"); //IMEI number
  }

  if(data=='5')
  {
    A6Module.println("ATD+21369682909;\r"); //Calling
  }

  if(data=='6')
  {
    A6Module.println("ATH\r"); //Hang Up
  }

  if(data=='7')
  {
    A6Module.println("AT+CMGF=1");
    delay(2000);
    A6Module.print("AT+CMGS=\"+213696829093");
    A6Module.print(char(34));  // "
    A6Module.print(char(13));  // CR
    A6Module.print('\r');  // hex equivalent of newline
    delay(2000);
    A6Module.print("A6 test message");
    delay(500);
    A6Module.println (char(26));  //ctrl_z
  }

  if(data=='8')
  {
    A6Module.println("AT+CMGR=1\r"); //Read message
  }

  if(data=='9')
  {
   A6Module.println("AT+CMGD=1,0\r"); //Delete message
  }

  if(data=='s') sendMMS();
  data=0;
}

void sendMMS()
{
  A6Module.print("AT+CMMSINIT");
  delay(100);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
  A6Module.print("AT+CMMSCURL=\"http://mms.itelcel.com/servlets/mms\"");
  delay(100);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
  A6Module.print("AT+CMMSCID=1\r");
  delay(100);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
  A6Module.print("AT+CMMSPROTO=\"148.233.151.240\",8080");
  delay(100);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
  A6Module.print("AT+CMMSSENDCFG=6,3,0,0,2,4\r");
  delay(100);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
  A6Module.print("AT+SAPBR=3,1,\"CONTYPE\",\"MMS\"\r");
  delay(100);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
  A6Module.print("AT+SAPBR=3,1,\"APN\",\"mms.itelcel.com\"");
  delay(100);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
  A6Module.print("AT+SAPBR=1,1");
  delay(4000);
  if(A6Module.available())

  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
  A6Module.print("AT+SAPBR=2,1");
  delay(4000);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
  A6Module.print("AT+CMMSEDIT=1");
  delay(100);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
  A6Module.print("AT+CMMSDOWN=\"PIC\",19293,2000000,\"test.jpg\"\r");
  delay(1000);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }

  dataFile=SD.open("test.jpg");
  i=0;
  if(dataFile)
  {
    while(dataFile.available())
    {
      data=dataFile.read();
      if(data<0x10) Serial.print("0");
      Serial.print(data,HEX);
      i++;
      if((i%40)==0) Serial.println();
      A6Module.write(data);
    }
    dataFile.close();
  }
  else
  {
    Serial.println("error opening test.jpg");
  }

  delay(1000);
  A6Module.print("AT+CMMSRECP=\"+213696829093");
  delay(100);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
  A6Module.print("AT+CMMSVIEW\r");
  delay(2000);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
  A6Module.print("AT+CMMSSEND\r");
  delay(2000);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
  A6Module.print("AT+CMMSEDIT=0\r");
  delay(2000);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
  A6Module.print("AT+CMMSTERM\r");
  delay(2000);

  if(A6Module.available())
  {
    while(A6Module.available()) Serial.write(A6Module.read());
  }
}

which line causes the error? ... use print statements to debug the program flow

all commands beginning as 'AT+CMMS' to A6 receives +cme error 58 I dont' know why!

The Arduino Uno does not support the maximum current requested by GA6, try an external source for the gprs module of at least 6V using common ground between the gprs module and the arduino.


text:
Where should unit tests go in the Arduino IDE
I have an Arduino project where the file structure looks like this
myProject/
    myProject.ino
    ImportantClass1.hpp
    ImportantClass1.cpp
    ImportantClass2.hpp
    ImportantClass2.cpp
    Etc….

It compiles and runs fine. No problem pulling the cpp and hpp files into the ino program. However to really make sure of reliability I want to make additional ino files for unit testing of importantClass1 & etc. I have made files importantClass1UnitTest.ino & importantClass2UnitTest.ino however these can’t be in the same dir as the respective source files as the arduino compiler requires the ino file and the dir to have the same name.
The tests run when I move the files around. But I am not happy with that, I want to be able to run the tests at any time with the standard arduino compiler without having to script filecopy commands.
If I put the unit test in its own dir separate to the class source and #include using the full path it also works. However this solutions is not portable, when I (or any collaborator) pull the project from git hub on any other computer the paths are wrong and it doesn’t work.
Where am I going wrong? How can I do this so as to avoid moving/copying files and also avoid using full paths?

I do not think there is a standard “Arduino way” of storing unit tests, and this is a great question that may, hopefully, help reveal best practices. I would suggest to #include a relative (rather than absolute) path.

Thanks @EdgarBonet I have tried relative paths and can’t get them to work. If the path is relative to the location of unitTest.ino file then the relative path has to start with ../../location of source. But this doesn’t work for me. Where would the relative path be relative to?

Without a working environment, I would use "../myProject", if "myProject" is on the same level as "importantClass1UnitTest".

@EdgarBonet, Arduino IDE/CLI compiles and builds in a temporary folder. relative paths don't work.

Confirmed. Relative paths don't work.

Can you use symbolic links?

OK. Thank you @EdgarBonet. Have found a way to do it based on sym-links. Will write an answer below...

One way to do it is to use preprocessor conditionals. Name your project file and unit-test files with .cpp extensions and put them in a subfolder (called "sources" in my example). Then your .ino file would only be used to instruct the preprocessor which of the several "main" file to start compiling with:
myProject.ino:
/*
 * myProject.ino
 * define which "main" CPP file to compile:
 */

#define PRODUCTION
// #define UNITTEST1
// #define UNITTEST2
// #define UNITTEST3

// The compilation starts here with the requested "main" file:
#if defined PRODUCTION
#include "sources/myProject.cpp"

#elif defined UNITTEST1
#include "sources/unitTest1.cpp"

#elif defined UNITTEST2
#include "sources/unitTest2.cpp"

#elif defined UNITTEST3
#include "sources/unitTest3.cpp"

#else
// If nothing defined, compile for production
#include "sources/myProject.cpp"
#endif

/* END */

Only the .ino file would need to be edited to compile one of the unit tests, and only one project file would be needed.
Update:
"did you try it? "
Yes, and it does work. The only caveat I'd add is: don't name your subfolder "src" - that seems to be a magic-name to the IDE, and you'll get complaints of compilation errors (multiple definitions) if you use it. And further, if you try it, you can't get back simply by changing the folder's name (on disk and in the code); you'll have to restart the IDE as well.
I tested it with v1.8.19 of the IDE.

Given that the two files I placed in the folder were a complete Arduino 'blink' sketch and a complete 'Hello, World' sketch, but with .cpp extensions,, and that selecting one or the other as I showed in the my answer and compiling and downloading produced the expected results, than, yeah, I can definitely say they were compiled. But don't take my word for it; try it yourself.

sorry. yes. the cpp was not a cpp. it was just an included file. it could have txt or ino as filename extension.

Thanks for the answer. I am not going to do it this way though. Looks like I will have to make test runner scripts that overcome the lack of support for relative paths by copying files from the project dir to the unit test dir and maybe running the unit tests with the Arduino CLI.

@HubertB, it would be great if you can share an example when you can of your intended alternative solution as another answer here.

OK. Update, better late than never. I used soft links to overcome this problem.
The final directory structure is like this:
myProject/
    .git/
    myProject.ino
    Class1.hpp
    Class1.cpp
    Class2.hpp
    Class2.cpp
    ...
    UnitTests/TestClass1/TestClass1.ino
    UnitTests/TestClass1/Class1.cpp -> ../../Class1.cpp
    UnitTests/TestClass1/Class1.h   -> ../../Class1.h
    ...

Both the main program and all the unit tests run fine when compiled in the Arduino compiler and there is only one copy of the class files that I want to test.