text:
My program is using too much memory
I work in a warehouse and I was tasked to make a device which will show the location of any product when Product ID is given. All of our product has 3 things. Product ID, Rack Number and Gap number.
So the basic program is like that When I enter Product ID: 1640
The program will show in display that it is located in RCK 113 GAP 88
For this I used Arduino Mega, 4x3 Keypad and 16x2 LCD Display with I2C adapter.
I found a Arduino Keypad Calculator code on the Internet and modify my code from there.
So currently my code is working fine and everything
What I noticed is Arduino mega has only 2% memory left with all that string value (For that I couldn't use Arduino Uno at first). Now due to new products are added I need more space or ways to store data elsewhere.
I can not use internet or WIFI as Another team has already made a device using ESP8266 Nodemcu which shows data from a Google sheet but since my device stores data in itself it is very fast (almost instant) to show any result on the other hand the device with NODEMCU ESP8266 can be easily updated and doesn't bother about size yet it is very slow to show result and needs good wifi connection so it is not efficient in warehouse environment. So every staff use my device on the go and other device as a backup
Currently I have around 1000 product address stored in my device but a new shipment of almost 3000 product is coming and my mega has only 2% memory left.
So any genius here can you help me to compress my program more ? or any fault I made during my coding ? Also this is my first post and sorry for my bad English.
My Code is given below. It is huge please take your time to understand it.
Even I can't copy my code here
Body is limited to 30000 characters; you entered 132142.
This is a sample of my code for you to understand
Here is full code uploaded. Download
What I want to know is, if it is possible to add a Arduino SD card module and keep portion of my string memory in there.
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 4;
unsigned int integerValue=0;
//define the keymap
char keys [ROWS] [COLS] = {
  {'1', '2', '3', 'X'},
  {'4', '5', '6', '*'},
  {'7', '8', '9', '='},
  {'/', '0', '-', '+'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};

//create the keypad
Keypad myKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
LiquidCrystal_I2C lcd(0x27, 16, 2);

//variables declaration
boolean valOnePresent = false;
boolean result = false;
String num1;
int ans;
boolean getvalue = false;

void setup(){
  Serial.begin(9600);
  lcd.init(); // initialize the lcd
  lcd.backlight();
  frstscreen();
  //lcd.clear();

}

void loop(){
  char key = myKeypad.getKey();

  if (key != NO_KEY && (key=='1'||key=='2'||key=='3'||key=='4'||key=='5'||key=='6'||key=='7'||key=='8'||key=='9'||key=='0')){
      num1 = num1 + key;
      int numLength = num1.length();
      lcd.setCursor(15 - numLength, 1);
      lcd.print(num1);
      valOnePresent = true;
  }

  else if (valOnePresent == true && key != NO_KEY && key == '='){

      ans = num1.toInt();

      lcd.clear();
      lcd.setCursor(15,1);
      lcd.autoscroll();
      lcd.print(ans);
      lcd.noAutoscroll();
      result = true;

  }
  else if (key != NO_KEY && key == 'X'){
    lcd.clear();
    valOnePresent = false;
    num1 = "";
    frstscreen();
    getvalue = false;
}

    integerValue = ans;

if (result == true) {

if (integerValue ==  9   ) { IDScrn(); lcd.print("109");lcd.setCursor(12,1);lcd.print("63 "); delayfunc();}
if (integerValue == 15    ) { IDScrn(); lcd.print("107");lcd.setCursor(12,1);lcd.print("60 "); delayfunc();}
if (integerValue == 15    ) { IDScrn(); lcd.print("109");lcd.setCursor(12,1);lcd.print("63 "); delayfunc();}
if (integerValue == 20    ) { IDScrn(); lcd.print("109");lcd.setCursor(12,1);lcd.print("63 "); delayfunc();}
if (integerValue == 22    ) { IDScrn(); lcd.print("110");lcd.setCursor(12,1);lcd.print("68 "); delayfunc();}
if (integerValue == 23    ) { IDScrn(); lcd.print("109");lcd.setCursor(12,1);lcd.print("63 "); delayfunc();}

//TOP and components

if (integerValue ==  1001   ) { IDScrn(); lcd.print("RCK 115 COL A                  "); delayfunc();}
if (integerValue == 1002   ) { IDScrn(); lcd.print("RCK 115 COL A                  "); delayfunc();}
if (integerValue == 1003   ) { IDScrn(); lcd.print("RCK 115 COL A                  "); delayfunc();}

//Stock and CBOX

if (integerValue ==   376    ) { ComScrn(); lcd.print(" Stock Box 1"); delayfunc();}
if (integerValue ==   15     ) { ComScrn(); lcd.print(" Stock Box 1"); delayfunc();}
if (integerValue ==   919    ) { ComScrn(); lcd.print(" Stock Box 1"); delayfunc();}

//CBOX

if (integerValue ==   245    ) { ComScrn(); lcd.print(" 39K COL I "); delayfunc();}
if (integerValue ==   245    ) { ComScrn(); lcd.print(" 10K COL I "); delayfunc();}
if (integerValue ==   245    ) { ComScrn(); lcd.print(" 47k COL I "); delayfunc();}
if (integerValue ==   245    ) { ComScrn(); lcd.print(" 1k  COL I "); delayfunc();}
if (integerValue ==   245    ) { ComScrn(); lcd.print(" 2k  COL I "); delayfunc();}
if (integerValue ==   245    ) { ComScrn(); lcd.print(" 4.7k  COL I "); delayfunc();}
if (integerValue ==   245    ) { ComScrn(); lcd.print(" 27k COL I "); delayfunc();}
if (integerValue ==   766    ) { ComScrn(); lcd.print(" 0 ohm   COL I "); delayfunc();}
if (integerValue ==   766    ) { ComScrn(); lcd.print(" 220 ohm COL I "); delayfunc();}
if (integerValue ==   766    ) { ComScrn(); lcd.print(" 560 ohm COL I "); delayfunc();}
if (integerValue ==   766    ) { ComScrn(); lcd.print(" 470 ohm COL I "); delayfunc();}
if (integerValue ==   766    ) { ComScrn(); lcd.print(" 330 ohm COL I "); delayfunc();}
if (integerValue ==   766    ) { ComScrn(); lcd.print(" 100 ohm COL I "); delayfunc();}
if (integerValue ==   1291     ) { ComScrn(); lcd.print(" Cbox 1  GAP 101 "); delayfunc();}
if (integerValue ==   1314     ) { ComScrn(); lcd.print(" Cbox 1  GAP 101 "); delayfunc();}

if (getvalue == false) { noproduct(); }

}
 }
void frstscreen()
{
  lcd1stline();
  lcd.print("Warehouse Stock");
  lcd.setCursor(0,1);
  lcd.print("Enter ID: ");
}
void pressA(){

  lcd.clear();
  lcd.setCursor(0,1);
  lcd.print("Press A again");
}
void noproduct(){

  lcd1stline();
  lcd.print("Not Found");
  lcd.setCursor(0,1);
  lcd.print("Press A again");
  result= false;
}
void delayfunc(){
  result = false;
  delay (2000);
  pressA();
  getvalue = true;

}
void lcd1stline(){
lcd.clear();
lcd.setCursor(0,0);
}
void IDScrn(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("ID: ");
  lcd.setCursor(4,0);
  lcd.print(integerValue);
  lcd.setCursor(0,1);
  lcd.print("RCK     GAP");
  lcd.setCursor(4,1);
}

void ComScrn(){
    lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("ID: ");
  lcd.setCursor(4,0);
  lcd.print(integerValue);
  lcd.setCursor(1,1);
}

Have you thought about storing the data on an SD card? Fast, no internet needed, and easy to update. And no memory problems.

Using an SD card as memory to build your database is the way to go here, because it is future proof. As the number of items in the warehouse increases you might get to the memory limit of the Mega at some point. With an SD card you will never reach that with a simple text database of items. Additionally that will force you to write ONE function to get ANY entry form the database. Every time you see yourself writing basically the same code lines many times you should really think about a better code structure

the question is "What I want to know is, if it is possible to add a Arduino SD card module and keep portion of my string memory in there."

Warehouse... commercial... operations... don't use an Arduino.  Seriously. It's a toy.  There are far more suitable SBCs and micro controllers out there with vastly more resources to deal with scaling real-world problems.  You're trying to solve a business problem.  Scrimping for RAM is NOT a problem you need to burden yourself with when you have a real job to get done.  This isn't hobby time any longer - there's business depending on this.  Don't hobble yourself with weak and inappropriate tools.

@J... I'm not sure Arduinos shouldn't be used for commercial operations, especially as a prototype (which this clearly is).

you could also consider upgrading to a Raspberry Pi, which has more gigabytes of memory than you'll ever need for this program, but also uses more power and you have to deal with Linux

@user253751 Prototyping on a platform you'll need to throw out and start over with when you realize that database-connected business inventory problems don't fit in 8kB of RAM is absolutely pointless.  It's not 1980 any more.  We don't need to make our lives difficult on purpose by using absurdly overpriced and underpowered hardware.  An Arduino isn't even cheap - it's just a brutal handicap with no defensible justification for choosing it.  You'll do nothing but fight to squeeze the solution into that tiny chip  and leave yourself zero room to grow and expand.  Why?

@user253751I think a Raspberry Pi would be a much better platform if this "device" needs to be compact. Much easier to update, can have the entire database in memory, and application may be easier to develop for non-embedded devs

Your repeated comments sound like you have a X for Y problem and you don't understand that people are pointing out that the real solution to the problem presented is Y.

There are lots of repetitions in your code. This is something you should
generally avoid, not only because of memory usage, but also, and most
importantly, because of maintainability.
The most common way of getting rid of repetitions is to write a loop
that walks through an array. For the first part of your program (the
rack/gap scheme), that array could look like this:
// Data structure describing a recorded location.
struct Location {
    uint16_t id;
    uint8_t rack;
    uint8_t gap;
};

// List of recorded product locations.
const Location locations[] = {
    {  9, 109, 63 },
    { 15, 109, 63 },
    { 20, 109, 63 },
    { 22, 110, 68 },
    { 23, 109, 63 },
    // etc...
};

// Number of items in the above list.
const size_t nb_locations = sizeof locations / sizeof locations[0];

Note that the structure uses the smallest possible integers for each
field, in order to save memory. The main benefit, however, is that the
data is now in a format that is easier to update: a simple list of
numbers.
Then, all the code that handles this data becomes a loop, instead of a
repetition. For example, the following function can print the location
of any item on the LCD. It returns true or false to let you know
whether it did find the requested item:
// If the item is found, print its location and return true.
// Otherwise return false.
bool print_location(uint16_t id) {
    for (size_t i = 0; i < nb_locations; i++) {
        if (locations[i].id == id) {
            IDScrn();
            lcd.print(locations[i].rack);
            lcd.setCursor(12,1);
            lcd.print(locations[i].gap);
            delayfunc();
            return true;  // found
        }
    }
    return false;  // not found
}

This scheme still has the problem that all the data is copied to RAM at
initialization. If you have 4,000 items, that would require
16,000 bytes of RAM, or about twice the RAM of your Mega. You can
save RAM by keeping all constant data in flash, using the PROGMEM
qualifier. You have 32 times more flash than RAM. You
would then need, however, to bring each item back to RAM in order to use
it, which can be done with the memcpy_P() function. Here
is a version of the previous code that stores the array in flash:
// List of recorded product locations.
PROGMEM const Location locations[] = {
    {  9, 109, 63 },
    { 15, 109, 63 },
    { 20, 109, 63 },
    { 22, 110, 68 },
    { 23, 109, 63 },
    // etc...
};

// Number of items in the above list.
const size_t nb_locations = sizeof locations / sizeof locations[0];

// If the item is found, print its location and return true.
// Otherwise return false.
bool print_location(uint16_t id) {
    for (size_t i = 0; i < nb_locations; i++) {
        Location location;  // RAM copy of locations[i]
        memcpy_P(&location, &locations[i], sizeof location);
        if (location.id == id) {
            IDScrn();
            lcd.print(location.rack);
            lcd.setCursor(12,1);
            lcd.print(location.gap);
            delayfunc();
            return true;  // found
        }
    }
    return false;  // not found
}

This approach should enable you to store all the database in the flash
of your Mega, and maybe even on an Uno. That being said, I second the
commenters that say that using an SD card should make upgrading the
database a lot more convenient.

I didn't know about the memcpy_p ... upvoted

Did you try using the (PROGMEM)  F macro. It is described in the official Arduino documentation at the end of https://www.arduino.cc/reference/en/language/variables/utilities/progmem/
This forces all strings to be stored in Flash memory instead of the scarce SRAM memory.
You can try with a few strings to see if the memory lowers and calculate if it would be enough (to fit in Flash). If even Flash is not enough, than SD card would be an alternative.
Also some refactorings that might clean up the code (not necessarily reduce the memory used):

instead of the many if (integerValue == xxx) constructs, use  switch/case statements.
A possible bug are the identical values within (like 245 and 766 used many times, but for different products)
Move the function lcd.print("...") inside function ComScrn and pass the string (using F(..))
Similar as above but for IDScrn, using two strings and set the cursor inside IDScrn as well.
(key != NO_KEY && key == 'X') ... if key is 'X' it can never be NO_KEY so the first check can be removed.
if (result == true) can be written as if (result).

the question is "What I want to know is, if it is possible to add a Arduino SD card module and keep portion of my string memory in there."

@Juraj Simply: yes (but my alternative possibly makes this unnecessary.

What I want to know is, if it is possible to add a Arduino SD card module and keep portion of my string memory in there
Well, given that two contributors have already gave a handful of advices to both improving your code and the benefits of using an SD card. I find nothing else to say except answering your very specific question.
The answer is simple, and it is a yes.
There is no problem in dividing your data into two parts, one part on your microcontroller/Arduino and the other part on your SD card, you will have to know which part is where so you can access it without any problems and almost instantly as well.
I hope that answers your question fully.

In order to put the data on an SD card, the OP would still first have to write the program to have the data in a data structure rather than repeated if/print statements.  So the other answers still apply.

Indeed they do, this is why I stated very clearly at the beginning of my answer, that the other answers already gave a handful of advices on how to improve the code, which surely mentioned the usage of data structures, however he kept commenting on those answers and with the same question again.
What I want to know is, if it is possible to add a Arduino SD card module and keep portion of my string memory in there
So basically, yeah.

The Arduino Uno uses a rather old, weak processor. It is still a perfectly cromulent microcontroller - it does just fine - but much newer ones do exist.
You mentioned the ESP8266. Did you know it has 40kB of RAM compared to the Uno's 2kB? And the successor, the ESP32, has 320kB of RAM.
Since your application is basically a miniature computer, with a keyboard and screen, have you considered using something that's designed as a miniature computer? A Raspberry Pi (any model) has more gigabytes of RAM than you know what to do with. But it does use a lot more power. But you can also write the software in a normal Linux way (if you happen to like Linux programming). Or, you could consider writing an app for your Android cellphone.
If you insist on using the Uno, another option is to add an SPI RAM expansion chip, for example this 1-euro chip with 32kB (they do go bigger). Now, the Uno has no built-in RAM expansion ability, so you can't just access it with pointers or something, but you can still use the SPI bus to tell the chip to read or write certain bytes, kinda like you can with an SD card.
After writing this, I realized SPI RAM is not so useful for your application, because you don't want to store the data only while the device is turned on. You could use a SPI FRAM or SPI EEPROM chip instead which can store data while it's powered off. The Arduino IDE doesn't have a way to automatically put data into any of these chips... so to input the data you'd probably have to send it over the serial port, into a separate program you wrote, which writes it to the chip. Or you could make a user interface that allows the user to edit the data directly on the device.
Or you can use an SD card, yes. Honestly that's probably the simplest way.


text:
Unable to use rising edge interrupt for external clock Arduino 2650
I'm messing about with an Arduino Mega2560r3 and failing to get timer 4 to trigger on the rising edge of an external clock. It only ever triggers on the falling edge.
I've tried
     TCCR4B = (1 << CS42) | (1 << CS41) | (1 << CS40);

and
     TCCR4B = (1 << CS42) | (1 << CS41);

... one of which should do the trick, but now I've pulled all my hair out and I'm turning to the wider community to see what I'm not seeing!
void setup() {
  DDRE = (1 << PE5);   //Dig pin 3 as output

  noInterrupts();
// Configure Timer 4 (only ICP4 (pin 49) and ICP5 (pin 48) are connected with Arduino MEGA2560 r3)
  TCCR4A = 0;
  TCCR4B = 0;
  TCCR4B = (1 << CS42) | (1 << CS41) | (1 << CS40);    // CTC mode does not reset when using force
  TIMSK4 = (1 << ICIE4);    // enable capture interrupt
  interrupts();
}

ISR(TIMER4_CAPT_vect)
{
  PORTE ^= (1 << PE5);  // Toggle PE5
}

Scope output below - blue is external clock (yes I know it's a sine wave!) and magenta is pin 3 output

You seem to be mixing up two very different things.

You can use an external signal to drive the timer. That is, the timer
will “tick” on the edges of that signal. In this mode, the timer
behavior could be more accurately described as being a “counter”,
since it is counting the external signal's edges. The external signal
has to be fed to pin Tn (for timer n). Only the pins T0 (38) and T5
(47) are routed out on the Arduino Mega2560.

You can use a timer to timestamp the edges of an external signal.
This is called “input capture”. When an edge is detected, the current
value of the counter register is immediately copied to the input
capture register ICRn, and an interrupt can be delivered. The
external signal has to be fed to pin ICPn (ICP4 = 49, ICP5 = 48).

If you want to use input capture, you most likely want to clock the
timer from the system clock, maybe through a prescaler. And you want to
read the ICRn register within the ISR. The edge that triggers the
capture is selected via the bit ICESn (Input Capture Edge Select) of the
control register TCCRnB.

Thanks for your help - I mistakenly thought ICPn was also the ext timer input. I'll have to use timer 5 to use get the external clock working, but now you've explained this, I'm not sure which will be more elegant for this aplication... (I tried to upvote your answer but I'm too noob here)

source: Stack Exchange

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

sort: votes


text:
Arduino Micro: 69 is supposed to show up when I press 1 on the keypad, however some weird number (15 in this case) is showing up
// **I AM ALSO GETTING WEIRD CLUELESS DELAYS WHEN I PRESS BUTTONS ON THE MODE MENU**

/*
   Jebediah's Launch Control System for Kerbal Space Program
   Alpha Build 0.70
   An Open-Source Project by John Seong
*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 3;

char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

int timeV, thrustV, massV, gravityV;

byte rowPins[ROWS] = {12, 11, 10, 9};
byte colPins[COLS] = {8, 7, 6};

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

bool keyDetect = false;
bool menuKeyDetect = false;
bool goHomeDetect = false;

bool countDownDetect = false;
bool countDownOutput = false;
bool twrCalDetect = false;

String timeValue, thrustValue, massValue, gravityValue;

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.clear();

  Startup();

  timeV = constrain(timeV, 15, 120);
}

void loop() {
  PressKey();

  if (menuKeyDetect == true) {
    PressMenuKey();
  }

  if (goHomeDetect == true) {
    GoHome();
  }

  if (countDownDetect == true) {
    CountDownSequence();
  }

  if (countDownOutput == true) {
    CountDownOutputSequence();
  }
}

// Pages & Sections
void Startup() {
  lcd.print("Jeb's Launch");

  lcd.setCursor(0, 1);
  lcd.print("Control System");

  delay(3000);

  lcd.clear();
  lcd.print("Alpha Build 0.70");

  lcd.setCursor(0, 1);
  lcd.print(" STUDIO HORIZON");

  delay(3000);

  lcd.clear();
  lcd.print("Welcome, Kerman");

  lcd.setCursor(0, 1);
  lcd.print("Press any key...");

  keyDetect = true;
}

void ModeMenu() {
  menuKeyDetect = true;

  lcd.clear();
  lcd.print("1. Countdown");

  lcd.setCursor(0, 1);
  lcd.print("2. TWR");
}

void CountDown() {
  lcd.print("Time (sec): ");

  lcd.setCursor(0, 1);
  lcd.print("# to continue...");

  goHomeDetect = true;
  countDownDetect = true;
}

void TwrCal() {
  lcd.print("Thrust: ");

  lcd.setCursor(0, 1);
  lcd.print("# to continue...");

  goHomeDetect = true;
}

// Actions & Behaviours
void PressKey() {
  char key = keypad.getKey();
  if (key) {
    Serial.println(key);
    if (keyDetect == true) {
      lcd.clear();
      ModeMenu();
      keyDetect = false;
    }
  }
}

void PressMenuKey() {
  char key = keypad.getKey();
  if (key == '1') {
    Serial.println(key);
    if (menuKeyDetect == true) {
      lcd.clear();
      CountDown();
      menuKeyDetect = false;
    }
  } else if (key == '2') {
    Serial.println(key);
    if (menuKeyDetect == true) {
      lcd.clear();
      TwrCal();
      menuKeyDetect = false;
    }
  }
}

void GoHome() {
  char key = keypad.getKey();
  if (key == '*') {
    lcd.clear();
    ModeMenu();
  }
}

void CountDownSequence() {
  char key = keypad.getKey();

  if (key == '0') {
    timeV = timeV + 0;
  }

  if (key == '1') {
    timeV = 69;
  }

  countDownDetect = false;
  countDownOutput = true;
}

void CountDownOutputSequence() {
    lcd.setCursor(13, 0);
    Serial.println(timeV);
    lcd.print(timeV);
}

According to the documentation, the getKey() function is
non blocking. This means it does not wait for a key to be pressed:
it instead returns immediately whether a key has been pressed or not. If
no key has been pressed (i.e. most of the time), it returns a NUL
character, which has the numeric value zero and evaluates to false in
a boolean context. Hence the idiom:
char key = keypad.getKey();
if (key) {  // if a key has actually been pressed
    // handle it
}

The CountDownSequence() function fails to account for this:
void CountDownSequence() {
  char key = keypad.getKey();  // no check for NUL

  if (key == '0') {
    timeV = timeV + 0;  // this has no effect at all
  }

  if (key == '1') {
    timeV = 69;  // this is what you would expect to be executed
  }

  countDownDetect = false;  // these two lines tell the rest of the
  countDownOutput = true;   // program that we are done.
}

Since key will almost certainly be '\0', the program will move to
the next step without ever initializing timeV.
As a side note, I recommend you try to rewrite your program as a finite
state machine. A single state variable would make it less
confusing and easier to understand than the current collections of
booleans.

Edit: Expanding on the idea of the finite state machine. I tried an
implementation of your concept based on it.
For handling a menu system, where the user can navigate through several
on-screen “pages”, the most obvious first approach is to have one state
per page displayed. For this program, these states could be:

MENU, which offers the choice to move to either of the following two
pages
SET_COUNT allows the user to set the countdown duration
TWR allows him to compute the thrust/weight ratio
COUNT_DOWN actually runs the countdown timer

In the following, I added an extra transitional state called START
that comes right before MENU. This is not required, and its only
purpose is to avoid code repetition by having a single transition
(START → MENU) responsible for actually drawing the menu.
When implementing a finite state machine, my first recommendation would
be to start by drawing a state diagram like this:

In this diagram, each transition is labeled with the event that triggers
it. The events are key presses, save for “finished” which means that the
countdown is done. The state diagram can become significantly more
complex than this as you add new functionality. It is, however, a very
good way of designing your system from the point of view of user
interaction.
Once you are happy with the state diagram, the coding is just a matter
of translating it to a switch/case construct, with one case per
state. Here is my take at it:
/*
   Jebediah's Launch Control System for Kerbal Space Program
   Alpha Build 0.70
   An Open-Source Project by John Seong
*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 3;

char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {12, 11, 10, 9};
byte colPins[COLS] = {8, 7, 6};

Keypad keypad=Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// Show a two-line message on the LCD.
void lcdShow(const char *line0, const char *line1) {
  lcd.clear();
  lcd.print(line0);
  lcd.setCursor(0, 1);
  lcd.print(line1);
}

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcdShow("Jeb's Launch", "Control System");
  delay(3000);
  lcdShow("Alpha Build 0.70", " STUDIO HORIZON");
  delay(3000);
  lcdShow("Welcome, Kerman", "Press any key...");
  while (!keypad.getKey()) ;  // wait for key press
}

void loop() {
  static enum {START, MENU, SET_COUNT, COUNT_DOWN, TWR} state = START;
  static uint32_t last_second;  // millis() value on last full second
  static int count;             // countdown value

  char key = keypad.getKey();

  switch (state) {
    case START:  // transitional state
      lcdShow("1. Countdown", "2. TWR");
      state = MENU;
      /* fallthrough */
    case MENU:
      if (key == '1') {  // Countdown
        lcdShow("Enter time", "seconds: ");
        count = 0;
        state = SET_COUNT;
      } else if (key == '2') {  // TWR
        lcdShow("Thrust:", "# to continue...");
        state = TWR;
      }
      break;
    case SET_COUNT:
      if (key >= '0' && key <= '9' && count <= 99) {
        lcd.print(key);
        count = 10 * count + (key - '0');
      } else if (key == '#') {
        lcdShow("Take off in", "     seconds");
        // Force a refresh on entering COUNT_DOWN:
        last_second = millis() - 1000;
        count++;
        state = COUNT_DOWN;
      } else if (key == '*') {
        state = START;
      }
      break;
    case COUNT_DOWN:
      if (millis() - last_second >= 1000) {
        last_second += 1000;
        count--;
        if (count == 0) {
          Serial.println("Take off!");
        } else if (count < 0) {
          state = START;
          break;
        }
        lcd.setCursor(1, 1);
        lcd.print(count<10 ? "  " : count<100 ? " " : "");  // pad
        lcd.print(count);
      } else if (key == '*') {
        state = START;
      }
      break;
    case TWR:
      if (key == '*' || key == '#') {
        state = START;
      }
      break;
  }
}

Note the comment “fallthrough” between START and MENU. This
indicates that the lack of break at this place is intended: the
processing of the MENU case will follow right after the processing of
the START case, in the same loop iteration. The purpose of the fall
through is to not loose the current key press, if any. If this is not
important, you could put a regular break here and defer the handling
of MENU to the next loop iteration.
Note also that the key presses are checked with tests of the form
if (key == SOME_VALUE), which means there is no need for an extra
if (key) to test whether there was an actual key press.

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


text:
Digital Read Serial tutorial - calculating the resistor value
The Arduino Digital Read Serial tutorial guides you through the wiring of a simple button. My questions are centered around the resistor.
Why is the resistor necessary?
I think I understand this, but correct me if I am wrong. To ensure that the input pin reads a low signal, and does not float, we should connect the pin to ground when the button is not pushed. When the button gets pushed, we will have a 5V signal flowing to both the pin and to ground. Kirchhoff's voltage law states that total voltage in closed loop must equal zero, so we have to deal with this 5V that is flowing directly to ground. That is why we put a resistor between the button and ground.
How was the resistor value chosen?
This is what I am unclear on. Ohm's law states that...
resistance = voltage / current

This is a 5V supply and the Arduino Uno spec says that the pin provides 40 mA of DC current. So..
resistance = 5V / 0.04A = 125 Ohms

In the Digital Read Serial tutorial, why do we have a 10K Ohms resistor? That is way overkill, right? Which leads to another question: Can you ever put too much resistance in place, if your only goal is to obliterate voltage?
Thanks in advance for any feedback!

You're very close. The resistor is there to act as a pull down resistor; If the input pin is floating it is just an antenna picking up random static. The key is that when positive is supplied (by pressing the button) the positive source needs to "overwhelm" the pull down resistor so that the input pin reads positive.
If there were no resistance, than the input pin would be reading in the middle of a direct path that does not favor positive or negative. Asside from the direct short that would be occurring, Which state the arduino would read I suspect would either be random or some property of the power supply; It would probably still read ground.
With the resistor, the signal is read directly connected to positive, before the load resistance. This way it will be sure to get a HIGH signal.
The exact size of the resistor is of little consequence. Too small and you waste current, but too much resistance is effectively just disconnecting ground again. There is a very wide range of values that will work fine between those.
I would like to note that when an arduino pin is set to input mode, it will effectively supply no current. It can be moddeled is being in series with a 100 megaOhm resistor. see http://arduino.cc/en/Tutorial/DigitalPins
for details.

The key thing here is that if you don't use a resistor, when the switch is closed, you have shorted the +5 volt to ground. A direct short will overload the power supply and trip the protection circuit on the power supply, causing the whole Arduino to shut down. You want a resistor of high enough impedance to keep the current flow low. I usually use a 100k resistor, which is plenty to pull the input signal to 0 volts when the switch is open, and only allows .00005 pas to flow, a trivial amount of current. A 10k resistor works too, but that allows 10 times as much current to flow.

You've already gotten a couple of good answers on why a pull-down resistor is needed.
To summarize, you need to connect the input to ground to keep the input from floating semi-randomly between high and low. You use a resistor so that when you close the switch, you don't create a short circuit between the +5V supply and ground.
Another point, though. The Arduino's inputs include an optional internal, software-controlled pull-up resistor. If you first set up the pin as an input, then write a HIGH value to that port, it activates the pull-up resistor. That causes the pin to read as HIGH when nothing is connected to it.
You can then connect your switch to ground instead of +5V. You then need to change your code logic to treat a HIGH value as not pressed, and a LOW value as pressed. This lets you simplify your wiring a little, since you don't need an external resistor.

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


text:
splitable jumper wires question
I just received my starter kit from oddwires.com today and it came with a split-able ribbon cable for prototyping. I was curious if it is possible to split each wire off and use only what I need to for the tutorials or is that a bad idea? I am very excited to start playing around and learning this as it has been a interest of mine for many years.

Which starter kit? None of the ones under "oddWires Kits for Arduino" has (or shows) a ribbon cable.

the uno deluxe, but they called it "Perfect premium jumper wire pack - combinations female/male, male/male in 6"/10" lengths (40 wires)". This is what was sent to me though link

Each wire in the Dupont ribbon cable is is independent, and does not hold onto its neighbors with any real force. You can split them or join multiple wires together using larger connectors as desired.

Okay I didn't want to accidentally damage anything before I had a chance to use it. (I would hit the checkmark, but I am sure my rep isn't high enough)

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


text:
Confusion around LEDs on a breadboard
I am just starting out with an Arduino Diecimila and am playing around with LEDs, and am confused by why some circuits result in an LED not lighting up.
Successful Scenarios:

Yellow LED from pin13 to 16B on the breadboard, Green LED from 16A to GND. This works both LEDS light up.
Yellow LED from pin13 to 16A on the breadboard. Wire from 16E to 14E. Green LED from 14A to GND. This works and both LEDs light up.

Failed Scenarios:

Yellow LED from pin13 to 16A. Green LED from 16E to 14E. Yellow LED from 14A to GND. No LEDs light up. I would assume that all the LEDS are in series, and all 3 should light up, I assumed this would be exactly the same as my second successful scenario where the LED is acting the same as the wire.
Yellow LED from pin13 to 16A. Wire from 16E to 14E. Yellow LED from 15A to GND. Green LED from 16B to 14B. Here I have both Yellow LEDS lit, but the Green LED is not lit. I was expecting that the Green LED would have been in parallel and should have lit up.

In both failed scenarios I have swapped around the LEDs and proved that all the LEDs function.
There must be some basic concept that I am not understanding with the circuits, any ideas?

Of course we assume you know which way round you are connecting the LED's (Hint ... they are not light bulbs that don't care)

Scenario 1 fails because yellow and green LEDs have forward voltages of about 2V each, so when putting 3 in series, you need a forward voltage to light them that exceeds the 5V available.
Scenario 2 fails because the wire you have in parallel with the LED provides a path with a very low voltage drop (close to 0V), so the path through the LED with a ~2V voltage drop is not taken (and if you remove the wire, the same reasoning as in scenario 1 applies, so nothing would work).
BTW, you should never run LEDs without a series resistor, as your experiments will surely demonstrate to you soon ;-)

s/a series resistor/some form of current limiting, which may be but is not limited to a simple series resistor/

@IgnacioVazquez-Abrams, you forgot the opening  tag, but otherwise, you're, of course, right.


text:
HC-05 will NOT pair in Master mode (AT+ROLE=1). Same module will pair in slave mode (AT+ROLE=0)
I have a HC-05 Bluetooth module Version (+VERSION:2.0-20100601).
I am using Linux Mint Rosa on an Acer laptop
Section 1 - How it's wired
Wiring
HC-05       Arduino
VCC         5V
GND         GND
TX          pin 1
RX          GND via voltage divider (GND to 2k resistor{2k to HC-05 RX and a 1k resistor} 1k to pin 0)

Section 2 - Sequence to get into AT command state
The sequence I use to get the BT module in AT command state

Unplug the Arduino Uno
Unplug both the RX and TX
Press the button on the HC-05
Plug in the Arduino
HC-05 LED flashes 1 time every 2 seconds
Initialize com ports via Linux terminal - sudo chmod 0777 /dev/ttyACM*
Upload an empty sketch
Plug in the HC-05 RX to Arduino pin 0, and TX to pin 1
Open the Serial monitor
Set Both NL & CR  and 38400 baud

Section 3 - AT commands issued
I use the following AT commands with the noted results.
AT                                  > OK
AT+ORGL                             > OK
AT+RMAAD                            > OK
AT+VERSION  +VERSION:2.0-20100601   > OK
AT+ADDR     +ADDR:98d3:b1:fd85b0    > OK
AT+NAME=Master1                     > OK
AT+UART  +UART:38400,0,0            > OK
AT+ROLE  +ROLE:0                    > OK

NOTE:HC-05 is set to slave and it will pair (see Section 4 below)
THE PROBLEM IS AFTER PAIRING, I RETURN TO AT COMMAND MODE (Section 2) and SET ROLE=1 (Section 5) BUT IT WILL NOT PAIR IN MASTER MODE.
Section 4 - Pairing
I do the following to pair the HC-05 to my phone

Unplug the Arduino
Plug the Arduino back in
HC-05 LED flashes quickly blink/blink/blink
Android phone>settings>connections>Bluetooth>Scan
1 device found > Master1 > pair 1234
Android app > Serial BT terminal>device>Master1>connected
Once Android app connects:
HC-05 LED flashes blink/blink 2 seconds then blink/blink
Remove the RX and TX cables from Arduino and put a jumper to connect HC-05 TX to RX (loopback)
Serial BT terminal>hello>send
Output both green and blue - which means the data was sent via RX and returned via TX.

Section 5 - change ROLE=0 (slave) to ROLE=1 (Master)
I then follow the same sequence that I used previously in Section 2 to return to AT command state.
Issue the following AT commands
AT                      > OK
AT+ROLE  +ROLE:0        > OK
AT+ROLE=1               > OK

Since I changed the configuration I unpair the device on my phone.
I then follow the same sequence that I previously used in Section 4 to pair the HC-05 to my phone

HC-05 LED flashes quickly blink/blink/blink
Android phone>settings>connections>Bluetooth>Scan - CAN'T FIND THE DEVICE.

If I return to AT Command mode and change AT+ROLE=0 it will Pair.
In Master mode:

I tried to swap the TX and RX pins - won't pair.
I tried to pair with the TX and RX removed from the Arduino - won't pair.
I tried NOT UNpairing the device on the phone but it won't communicate with it via the android app once I change it to Master (Section 5).
As I mentioned above if I return to AT Command mode and change AT+ROLE=0 it will Pair.

Lastly I have 2 other HC-05 modules and they all fail to pair when set to Master mode, so I'm thinking I'm missing something but can't figure out what it is.
I would appreciate hearing from anyone with the same problem and anyone who can determine what I'm doing incorrectly.

You might have already solved your problem, but I just wanted to say that a HC-05 Blueooth module will only connect to a phone when it is in slave mode. The phone acts like a master, and therefore, it can't connect to another master.

I observed that these device do very well in slave more, however, in Master mode, they only connect to themselves ( I mean other HC-05).
I have sevceral slave devices ( gamepads, GPS modules, ...)  that never get connected, thoug the HC-05 sees them through the INQ  command, & accurately returns their address, class, signal force, and their name even.
Though, I never succeeded to pair them !!
As if they were designed to be used together and never tested with other slave devices !!?

Not an answer...


text:
How can I increase the torque or speed of the stepper motor with Arduino
I run 28BYJ-48 12 Volt Motor with ULN 2003 Driver using Arduino UNO.
I am also using external 12 volt power outside.
I aim for the syringe pump to move back and forth with the rotation of the motor.
I'm using the code below.
The code is running but the motor cannot move the syringe back and forth.
How do I change to be able to move the syringe pump
const int motorPin1 = 8;
const int motorPin2 = 9;
const int motorPin3 = 10;
const int motorPin4 = 11;

int bekleme =2
;
// bekleme süresini değiştirerek step motorun hızlı veya yavaş ilerlemesini sağlayabilirsiniz.
//1sn=1000

void adim1() {
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay(bekleme);
}

void adim2() {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay(bekleme);
}

void adim3() {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
delay(bekleme);
}

void adim4() {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
delay(bekleme);
}

void setup() {

pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);

}

void loop() {

for (int i = 0; i < 2048 ; i++)
{
adim1();
adim2();
adim3();
adim4();
}
{

exit(0);
}
}

İleri
// Meraklı Mühendis Sayfasının hazırlığı kodlar kullanılmıştır.
//Dilerseniz farklı fonksiyonlar kullanabilirsiniz.

const int motorPin1 = 8;
const int motorPin2 = 9;
const int motorPin3 = 10;
const int motorPin4 = 11;

int bekleme =2;
// bekleme süresini değiştirerek step motorun hızlı veya yavaş ilerlemesini sağlayabilirsiniz.
//1sn=1000

void adim1() {
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay(bekleme);
}

void adim2() {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay(bekleme);
}

void adim3() {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
delay(bekleme);
}

void adim4() {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
delay(bekleme);
}

void setup() {

pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);

}

void loop() {

for (int i = 0; i <2048; i++)   // buradaki 512 değerleri step motorun tam bir tur dönmesini sağlıyor. dilerseniz bu sayıyı değiştirebilirsiniz
{
adim4();
adim3();
adim2();
adim1();

}
{

exit(0);
}
}

You haven't given much detail, that we can work with. Though I'm seeing, that you are only activating 1 phase at a time. For full steps you need to activate 2 at a time. Maybe my answer to this question is helpful here.

@chrisl I think OP is using an unipolar stepper motor. Though you could add a step in between where two coils are active, creating a crude form of micro-stepping.

@Gerben This is purely experience with the exact same motor and driver combination. I also had problems driving the motor with the phase combinations 1000,0100,0010 and 0001. Instead I tried 1100, 0110, 0011 and 1001. That worked for me. Or for half steps 1000,1100,0100,0110,0010,0011,0001,1001. Don't really know, why, but I wanted to share the experience

To increase torque of 28BYJ-48 you have to perform a simple mod (cup one path on the PCB) to change it from unipolar to bipolar and then use it with an H-bridge like the A4988 or the DRV8825 driver.

Sources:

https://ardufocus.com/howto/28byj-48-bipolar-hw-mod/
https://coeleveld.com/wp-content/uploads/2016/10/Modifying-a-28BYJ-48-step-motor-from-unipolar-to-bipolar.pdf
https://everythingsmarthome.co.uk/howto/converting-the-28byj-48-stepper-motor-for-more-torque/
http://www.jangeox.be/2013/10/change-unipolar-28byj-48-to-bipolar.html
https://www.youtube.com/watch?v=hkxnQIKybiI
https://www.youtube.com/watch?v=jHLyJbNgcDo

Assuming you are driving your motor correctly (And it sounds from Chris like you are not) and that you are using a power supply with enough current and a motor driver with a low internal resistance, you could put a reduction gear on the motor to reduce the rotation speed and increase the torque. It would take more rotations to push the syringe the same distance, but it will have more force.
If you use a 4:1 reduction gear, for example, you'd need 4 times more rotations, and you'd get 4 times as much force.


text:
Trouble Uploading Sketch - Issues with SPISettings
Full disclosure - I'm very new to Arduino. I am probably missing something simple. However, I've scoured the internet and can't seem to figure it out. I am trying to use an Arduino Duo Wifi rev2 to install a bootloader onto my Ender 3 (3D printer) - see: https://howchoo.com/g/mge1mdfkzjv/ender-3-bootloader-firmware-update-marlin
When I try to upload the ArduinoISP sketch, I get the following error:
Arduino: 1.8.12 (Mac OS X), Board: "Arduino Uno WiFi Rev2, ATMEGA328"

/Applications/Arduino.app/Contents/Java/arduino-builder -dump-prefs -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/brandonbarks/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/brandonbarks/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/brandonbarks/Documents/Arduino/libraries -fqbn=arduino:megaavr:uno2018:mode=on -vid-pid=0000_0000 -ide-version=10812 -build-path /var/folders/sc/1v4cm6053k7bmhv2bd02k44w0000gn/T/arduino_build_226513 -warnings=none -build-cache /var/folders/sc/1v4cm6053k7bmhv2bd02k44w0000gn/T/arduino_cache_822969 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avrdude.path=/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.arduinoOTA.path=/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -prefs=runtime.tools.avr-gcc.path=/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -verbose /Applications/Arduino.app/Contents/Java/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino
/Applications/Arduino.app/Contents/Java/arduino-builder -compile -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/brandonbarks/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/brandonbarks/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/brandonbarks/Documents/Arduino/libraries -fqbn=arduino:megaavr:uno2018:mode=on -vid-pid=0000_0000 -ide-version=10812 -build-path /var/folders/sc/1v4cm6053k7bmhv2bd02k44w0000gn/T/arduino_build_226513 -warnings=none -build-cache /var/folders/sc/1v4cm6053k7bmhv2bd02k44w0000gn/T/arduino_cache_822969 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avrdude.path=/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.arduinoOTA.path=/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -prefs=runtime.tools.avr-gcc.path=/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -verbose /Applications/Arduino.app/Contents/Java/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino
Using board 'uno2018' from platform in folder: /Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6
Using core 'arduino' from platform in folder: /Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6
Detecting libraries used...
/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega4809 -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_UNO_WIFI_REV2 -DARDUINO_ARCH_MEGAAVR -DUNO_WIFI_REV2_328MODE -DMILLIS_USE_TIMERB3 -I/Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino/api/deprecated -I/Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino -I/Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/variants/uno2018 /var/folders/sc/1v4cm6053k7bmhv2bd02k44w0000gn/T/arduino_build_226513/sketch/ArduinoISP.ino.cpp -o /dev/null
Generating function prototypes...
/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega4809 -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_UNO_WIFI_REV2 -DARDUINO_ARCH_MEGAAVR -DUNO_WIFI_REV2_328MODE -DMILLIS_USE_TIMERB3 -I/Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino/api/deprecated -I/Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino -I/Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/variants/uno2018 /var/folders/sc/1v4cm6053k7bmhv2bd02k44w0000gn/T/arduino_build_226513/sketch/ArduinoISP.ino.cpp -o /var/folders/sc/1v4cm6053k7bmhv2bd02k44w0000gn/T/arduino_build_226513/preproc/ctags_target_for_gcc_minus_e.cpp
/Applications/Arduino.app/Contents/Java/tools-builder/ctags/5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives /var/folders/sc/1v4cm6053k7bmhv2bd02k44w0000gn/T/arduino_build_226513/preproc/ctags_target_for_gcc_minus_e.cpp
Compiling sketch...
/Users/brandonbarks/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega4809 -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_UNO_WIFI_REV2 -DARDUINO_ARCH_MEGAAVR -DUNO_WIFI_REV2_328MODE -DMILLIS_USE_TIMERB3 -I/Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino/api/deprecated -I/Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino -I/Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/variants/uno2018 /var/folders/sc/1v4cm6053k7bmhv2bd02k44w0000gn/T/arduino_build_226513/sketch/ArduinoISP.ino.cpp -o /var/folders/sc/1v4cm6053k7bmhv2bd02k44w0000gn/T/arduino_build_226513/sketch/ArduinoISP.ino.cpp.o

ArduinoISP:191:27: error: reference to 'SPISettings' is ambiguous
     void beginTransaction(SPISettings settings) {
                           ^~~~~~~~~~~
/Applications/Arduino.app/Contents/Java/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino:167:7: note: candidates are: class SPISettings
 class SPISettings {
       ^~~~~~~~~~~
In file included from /Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino/api/ArduinoAPI.h:31:0,
                 from /Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino/Arduino.h:23,
                 from /Applications/Arduino.app/Contents/Java/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino:39:
/Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino/api/HardwareSPI.h:37:7: note:                 class arduino::SPISettings
 class SPISettings {
       ^~~~~~~~~~~
ArduinoISP:191:27: error: 'SPISettings' has not been declared
     void beginTransaction(SPISettings settings) {
                           ^~~~~~~~~~~
/Applications/Arduino.app/Contents/Java/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino: In member function 'void BitBangedSPI::beginTransaction(int)':
ArduinoISP:192:39: error: request for member 'clock' in 'settings', which is of non-class type 'int'
       pulseWidth = (500000 + settings.clock - 1) / settings.clock;
                                       ^~~~~
ArduinoISP:192:61: error: request for member 'clock' in 'settings', which is of non-class type 'int'
       pulseWidth = (500000 + settings.clock - 1) / settings.clock;
                                                             ^~~~~
/Applications/Arduino.app/Contents/Java/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino: In function 'void start_pmode()':
ArduinoISP:410:24: error: reference to 'SPISettings' is ambiguous
   SPI.beginTransaction(SPISettings(SPI_CLOCK, MSBFIRST, SPI_MODE0));
                        ^~~~~~~~~~~
/Applications/Arduino.app/Contents/Java/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino:167:7: note: candidates are: class SPISettings
 class SPISettings {
       ^~~~~~~~~~~
In file included from /Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino/api/ArduinoAPI.h:31:0,
                 from /Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino/Arduino.h:23,
                 from /Applications/Arduino.app/Contents/Java/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino:39:
/Users/brandonbarks/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino/api/HardwareSPI.h:37:7: note:                 class arduino::SPISettings
 class SPISettings {
       ^~~~~~~~~~~
exit status 1
reference to 'SPISettings' is ambiguous

If anyone has any advice, I'd really appreciate it. Thanks!

What type of Arduino are you actually using? There is no Arduino Duo. Possibly you meant Arduino Uno or Arduino Due, though you tagged the question with Arduino Mega. Which one is it?

update the megaavr core


text:
motor controll holding ir remote button
im controlling some small dc motors using arduino uno and tle94112el shield. currently, i can independently controll motors by pressing remote's buttons, but i wanna keep one motor rotating by holding a button. for example, by holding "unu" button, i wanna power the motor with 50% duty cycle, as i currently do by just pressing "unu".
thank you!
#include <TLE94112.h>
#include <Tle94112Motor.h>
#include <IRremote.h>

#define unu 0x1
#define patru 0x4
#define sapte 0x7

int RECV_PIN = 2;

// Tle94112 Object
Tle94112 controller = Tle94112();

// Tle94112Motor Objects
Tle94112Motor motor1(controller);
Tle94112Motor motor2(controller);
Tle94112Motor motor3(controller);

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  // Enable MotorController Tle94112
  // Note: Required to be done before starting to configure the motor

   irrecv.enableIRIn();
  controller.begin();

   // Connect motor1 to HB1 and HB3
  motor1.connect(motor1.HIGHSIDE, controller.TLE_HB1);
  motor1.connect(motor1.LOWSIDE, controller.TLE_HB2);

  // Drive HB1 with signal from PWM1
  // Note: This allows to control the speed of the motor

  motor1.setPwm(motor1.HIGHSIDE, controller.TLE_PWM2);

  // Set PWM Frequency, default is 80 Hz
  motor1.setPwmFreq(motor1.HIGHSIDE, controller.TLE_FREQ200HZ);

  motor1.begin();
}

void loop()
{
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value

    if (results.value == unu)
    {
      motor1.start(127);
    }

    if (results.value == patru)
    {
      motor1.start(255);
    }

    if (results.value == sapte)
    {
      motor1.start(0);
    }
  }

}

thanks for replying. i followed your instructures. when i hold the button, my remote sends continuously the same code it sends for a single press too. so in the brackets of second "if", i used the same condition that i used in first "if". following your instructions, when i prees the button, motor starts, even if i release or keep holding the button, the motor keeps rotating, but when i press the same button second time, the motor stops. so instead of "timestamp = millis()", i used "timestamp < millis()", so in this situation, the motor was rotating as long as i kept the button pressed. now the problem is that the motor is powered with pulses, aprox. 2 impulses per second, it doesnt rotate smoothly. i tryed incresing and decreasing TIMEOUT with no effects. i also used all the pwm frequencies (80, 100, 200 hz) that the shield provides, and different duty cycles, also with no effects. but when i add 2 more motors, to controll them in the same way, each with it's own button, the pulses period was even bigger, with aprox one impuls on second. do you have any ideea about this? sorry, but its my first arduino project, i also have no experience on engineering forums. thaks for your time.
here is the code im using now:
#include <TLE94112.h>
#include <Tle94112Motor.h>
#include <IRremote.h>

#define unu 0x1

unsigned long timestamp = 0;
#define TIMEOUT   200

int RECV_PIN = 2;

// Tle94112 Object
Tle94112 controller = Tle94112();

// Tle94112Motor Objects
Tle94112Motor motor1(controller);

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  // Enable MotorController Tle94112
  // Note: Required to be done before starting to configure the motor

   irrecv.enableIRIn();
  controller.begin();

   // Connect motor1 to HB1 and HB3
  motor1.connect(motor1.HIGHSIDE, controller.TLE_HB1);
  motor1.connect(motor1.LOWSIDE, controller.TLE_HB2);

  // Drive HB1 with signal from PWM1
  // Note: This allows to control the speed of the motor

  motor1.setPwm(motor1.HIGHSIDE, controller.TLE_PWM2);

  // Set PWM Frequency, default is 80 Hz
  motor1.setPwmFreq(motor1.HIGHSIDE, controller.TLE_FREQ200HZ);

  motor1.begin();
}

void loop()
{
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value

    if (results.value == unu)
    {
      motor1.start(127);
      timestamp < millis();

    }

    if(results.value == unu){
      timestamp < millis();
    }

    if(millis() - timestamp > TIMEOUT){
      motor1.start(0);
    }
  }
}

Please format your code correctly, so that it gets readable. In the question editor select the code and click the {}button or press control+K

Replacing the assignment = with a comparison < breaks the logic of my solution. You are doing something else wrong. Please add your new code to the question

i understood now the logic of your solution, and i understood that replacing = with < breacks the logic, but it worked as i described.

I formatted the code for you and put the old part of the question back in. That way future readers can understand the thoughts and learnings behind the question.

I edited my question to address the problems of the new code

As I understood you want the motor to run only while you are pressing the button, stopping as you release the button. IR remote controls normally don't send a "release" signal. But they often send a "repeat" signal in a defined frequency. The value of this signal depends on the remote, that you use. A quick search showed this forum thread, where the value is 0xFFFFFFFF.
So to check, if the button is still pressed, you need to regularly check, if the repeat code was received. When receiving the unu signal, turn on the motor and start a timeout counter. Every time you receive the repeat signal, you reset the timeout counter. If the timeout hits (meaning, that no repeat signal was received anymore), stop the motor.
The timeout counter is best done with the millis() function, which returns the number of milliseconds since startup. Refer to the BlinkWithoutDelay example, that comes with the Arduino IDE. Basically you save the time in a variable, when the unu code is received (the receive if statement is pseudo code). You reset the timestamp in the same way for every repeat code. Then you check, if the different between the current time (returned by millis() and the timestamp is over the timeout value (here 200ms). If yes, turn the motor off.
unsigned long timestamp = 0;
#define TIMEOUT   200

void loop(){
    if(unu was received){
        // turn on motor here
        timestamp = millis(); //take timestamp
    }
    if(repeat was received){
        timestamp = millis();
    }

    if(millis() - timestamp > TIMEOUT){
        // turn off motor here
    }
}

In your new version you replaces the = with a < to make it work. That is wrong. The lines, where you did it,  will just do nothing then. Instead the problem lies at a different place:
The millis() if statement
if(millis() - timestamp > TIMEOUT)

has to be placed directly in void loop(), outside of the receive if statement. In your current version the timeout will only take effect, when something was received, which was not unu. But you want it to take effect also when nothing is received. In that case the receive if statement will not execute. So just move the millis() if statement outside of that receive if statement:
#include <TLE94112.h>
#include <Tle94112Motor.h>
#include <IRremote.h>

#define unu 0x1

unsigned long timestamp = 0;
#define TIMEOUT   700

int RECV_PIN = 2;

// Tle94112 Object
Tle94112 controller = Tle94112();

// Tle94112Motor Objects
Tle94112Motor motor1(controller);

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  // Enable MotorController Tle94112
  // Note: Required to be done before starting to configure the motor

   irrecv.enableIRIn();
  controller.begin();

   // Connect motor1 to HB1 and HB3
  motor1.connect(motor1.HIGHSIDE, controller.TLE_HB1);
  motor1.connect(motor1.LOWSIDE, controller.TLE_HB2);

  // Drive HB1 with signal from PWM1
  // Note: This allows to control the speed of the motor

  motor1.setPwm(motor1.HIGHSIDE, controller.TLE_PWM2);

  // Set PWM Frequency, default is 80 Hz
  motor1.setPwmFreq(motor1.HIGHSIDE, controller.TLE_FREQ200HZ);

  motor1.begin();
}

void loop()
{
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value

    if (results.value == unu)
    {
      motor1.start(127);
      timestamp < millis();

    }

    if(results.value == unu){
      timestamp < millis();
    }
  }

  if(millis() - timestamp > TIMEOUT){
    motor1.start(0);
  }
}

That way the timeout will be checked at every loop() iteration. As you described, that you get the code about 2 times per second, I increased the timeout value here to 700ms, which then should be enough to not let the motor stop between the receiving of the unu command.

Btw: To stop the motor you are using motor.start(0);. While it works perfectly, you might want to write your code more speaking. The used library internally just calls it's motor.coast(); function, when the parameter is zero. So to make it more obvious in your code, what you are doing there, you could replace motor.start(0); by motor.coast(). That can help others to understand your code better and also yourself, when you are revising the code yourself after some time, when you may have forgotten, what you thought at that time about the code. It is always better to write code, that speaks by itself about what it is doing.

oh thanks!!!!
it works now!!


text:
Relay board not working with nodemcu

This is the relay board
I am using nodemcu to make a home automation project which is controlled by google assistant. This is the code i am using is this one
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

#define Relay1            D0
#define Relay2            D1
#define Relay3            D2
#define Relay4            D3

#define WLAN_SSID       "Subhodip"             // Your SSID
#define WLAN_PASS       "09003244135"        // Your password

/************************* Adafruit.io Setup *********************************/

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883                   // use 8883 for SSL
#define AIO_USERNAME    "SubhodipRoy"            // Replace it with your username
#define AIO_KEY         "50a98bb44f6b48b69e645badadf8fb577894"   // Replace with your Project Auth Key

/************ Global State (you don't need to change this!) ******************/

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
// or... use WiFiFlientSecure for SSL
//WiFiClientSecure client;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

/****************************** Feeds ***************************************/

// Setup a feed called 'onoff' for subscribing to changes.
Adafruit_MQTT_Subscribe Light1 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME"/feeds/Relay1"); // FeedName
Adafruit_MQTT_Subscribe Light2 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Relay2");
Adafruit_MQTT_Subscribe Light3 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Relay3");
Adafruit_MQTT_Subscribe Light4 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Relay4");

void MQTT_connect();

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

  pinMode(Relay1, OUTPUT);
  pinMode(Relay2, OUTPUT);
  pinMode(Relay3, OUTPUT);
  pinMode(Relay4, OUTPUT);

  // Connect to WiFi access point.
  Serial.println(); Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);

  WiFi.begin(WLAN_SSID, WLAN_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Setup MQTT subscription for onoff feed.
  mqtt.subscribe(&Light1);
  mqtt.subscribe(&Light3);
  mqtt.subscribe(&Light2);
  mqtt.subscribe(&Light4);
}

void loop() {

  MQTT_connect();

  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(20000))) {
    if (subscription == &Light1) {
      Serial.print(F("Got: "));
      Serial.println((char *)Light1.lastread);
      int Light1_State = atoi((char *)Light1.lastread);
      digitalWrite(Relay1, Light1_State);

    }
    if (subscription == &Light2) {
      Serial.print(F("Got: "));
      Serial.println((char *)Light2.lastread);
      int Light2_State = atoi((char *)Light2.lastread);
      digitalWrite(Relay2, Light2_State);
    }
    if (subscription == &Light3) {
      Serial.print(F("Got: "));
      Serial.println((char *)Light3.lastread);
      int Light3_State = atoi((char *)Light3.lastread);
      digitalWrite(Relay3, Light3_State);
    }
    if (subscription == &Light4) {
      Serial.print(F("Got: "));
      Serial.println((char *)Light4.lastread);
      int Light4_State = atoi((char *)Light4.lastread);
      digitalWrite(Relay4, Light4_State);

    }
  }

}

void MQTT_connect() {
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  uint8_t retries = 3;

  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
    Serial.println(mqtt.connectErrorString(ret));
    Serial.println("Retrying MQTT connection in 5 seconds...");
    mqtt.disconnect();
    delay(5000);  // wait 5 seconds
    retries--;
    if (retries == 0) {
      // basically die and wait for WDT to reset me
      while (1);
    }
  }
  Serial.println("MQTT Connected!");

}

Connecting the pins as stated below
VIN-->VCC
D0--> IN1
D1--> IN2
D2-->IN3
D3-->IN4
Gnd-->Gnd
But only IN2,IN3 and IN4 led of relay board are only glowing the IN1 is not glowing and the relays are not switching on/off...
Anyone please help....
Please give any solution... Why the relays are not switch-on?
Please reply as soon as possible... I am very disturbed... Even cant sleep at night....

not working how? how is it wired? you power the relays with 3.3 V?

Is the signal from the cloud really getting received? Please check that, by doing Serial prints in that case. If the cloud signal is received correctly, please provide a smaller test code without all the MQTT and Wifi stuff, only switching the relays. That would make it way easier to debug

why do you say that your connection uses 6 wires, when the picture shows only 5 wires?

I power relay with the nodemcu with 5v and dine the connections as mentioned above...

Yes data is being recieved from the cloud the led on the relay board are turning on/off except the IN1 LED which is not glowing except that the other 3 led on the relay board are working but the relays are not working

Sorry... I forgot the last pin

Yes I am having no new update anyone please predict the reason of it.

draw a picture with the wiring. this relay board enables a completely separate circuit for relays, signaled over optocouplers.

https://arduino.stackexchange.com/questions/60471/5v-10a-4-channel-relay-to-2-lights15w-light-in-series-in-220v-ac-supply/60484#60484

You can try connecting each relay input individually first to the 3V pin of the nodemcu and then to ground. The relay should switch. Place your ear closely to the relay and try to hear the click. If this does not happen, try with 5V. Check, if ground and Vcc are correctly connected to the relay board. If still nothing happens, your relay board might be broken

From the description and comments it looks like the problem is HW related. I recommend you to do a relay module test (wthout NodeMCU):

Try to switch the relays on/off  just by connecting the power source you are using for powering the NodeMCU. Connect VCC–5V, GND–GND and one of the IN channels directly to 5V pin. If the relay switches on, try another channel. If not, try to connect IN to GND instead of 5V (inverted logic).
If 1. did not worked, check the yellow jumper on the right side of the relay board. The jumper must be attached (in case you don't want to use another independent power source just for relays).
If 2. did not worked, check if the relay board is not intended for use with 12 V DC power source (check the relay marking).

At this point you should know if all channels of the relay module are working and also the switching logic (inverted/noninverted). The next step should be connecting the relay module to the NodeMCU and run a "blink" example for all channels. If all is working well, we will be sure the problem is NOT HW related...

1.I am using a power bank how will i connect the jumper wire with the power bank.                2. Where the yellow wire should be connected. 3. Its 5v I am sure.

There is more ways how to connect the power source. The easiest probably is to connect power source to NodeMCU and use GND and 5V pin.
Not a wire, a jumper. It is the yellow thingy on the right bottom corner of the relay board.


text:
Control 2 ESC with a potentiometer with arduino
I have 2 ESC (electronic speed controller) which control these brushless motors: Hobbyking Donkey ST3511 Brushless Motor
I would like to make them work with a poentiometer, under arduino.
I have a program but it only works with one engine. Here is the program :
#include <Servo.h>//Using servo library to control ESC

Servo esc;
Servo esc2;
//Creating a servo class with name as esc

void setup()

{

esc.attach(9); //Specify the esc signal pin,Here as D8

esc.writeMicroseconds(1000); //initialize the signal to 1000

Serial.begin(9600);

esc2.attach(9); //Specify the esc signal pin,Here as D8

esc2.writeMicroseconds(1000); //initialize the signal to 1000

Serial.begin(9600);

}

void loop()

{

int val; //Creating a variable val

val= analogRead(A0); //Read input from analog pin a0 and store in val

val= map(val, 0, 1023,1000,2000); //mapping val to minimum and maximum(Change if needed)

esc.writeMicroseconds(val); //using val as the signal to esc
esc2.writeMicroseconds(val);
}

I did not find help on the internet, thank you in advance.

In your code you are attaching both esc objects to the same pin ( pin 9 ). That cannot be, what you indented. Use two different pins.

Oh, and you are beginning the Serial interface also twice. CopyPaste problem?

I'd say yes, it's a copy-paste problem as in the OP just duplicated the code without understanding what needs to be changed.

You need to assign 2 different hardware pins to your two different speed controllers. Do you want one pot (potentiometer) to control both motors, or a separate pot for each motor?

If you want one potentiometer to handle BOTH ESCs' speed, you could use this code:
//Using servo library to control ESC
#include <Servo.h>

//Starting the servos
Servo esc1;
Servo esc2;

void setup() {
    esc1.attach(9); // Use a PWM pin to the Servo, in this case 9
    esc1.writeMicroseconds(1000); //initialize the signal to 1000
    esc2.attach(10); // Pick another PWM to the other, in this case 10
    esc2.writeMicroseconds(1000); //initialize the signal to 1000

    Serial.begin(9600);
}

void loop() {
    int val; //Creating a variable val
    val= analogRead(A0); //Read input from analog pin a0 and store in val
    val= map(val, 0, 1023,1000,2000); //mapping val to minimum and maximum(analogRead's goes from 0-1023 and analogWrite's goes from 0-255, check your servo's specs)
    esc1.writeMicroseconds(val); // write to the first ESC
    esc2.writeMicroseconds(val); // write to the second ESC
    delay(100); // We usually set a small delay to avoid excessive readings or over-heating, but thats optional...
}

If you need to use two potentiometers, one for each ESC, then you would have to start another variable to read the 2nd pot value and use it to write on the 2nd ESC, simple as that! :)


text:
Multiple slave(sender) to one master (receiver)
I beg your help to my project
I wish to send the data from slave to master but only one data is receive out of two slaves.
//master

#include <Wire.h>

void setup() {
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output

}

void loop() {
  Wire.requestFrom(8, 1);    // request 6 bytes from slave device #8

  while (Wire.available()) { // slave may send less than requested
    char c= Wire.read(); // receive a byte as character
    char q= Wire.read();

  Serial.print(c);         // print the character
  Serial.print(q);
  }

  delay(1500);
}

////slave 1
#include <Wire.h>

void setup() {
  Serial.begin(9600); // Starting Serial Terminal
  Wire.begin(8);                // join i2c bus with address #8
}

void loop(){
  Wire.onRequest(requestEvent); // register event

  delay(1500);
}
void requestEvent() {

  Wire.write('Q');
  Serial.println("Sent");
}

////slave 2
#include <Wire.h>

void setup() {
  Serial.begin(9600); // Starting Serial Terminal
  Wire.begin(8);                // join i2c bus with address #8
}

void loop() {
  Wire.onRequest(requestEvent); // register event

  delay(1500);
}
void requestEvent() {

  Wire.write('Y');
  Serial.println("Sent");
}

I think both slaves has same address that's why you are facing this issues, because master communicate with both slave with same address and receive only one data, that might be slave 1 or 2. You need to change slave address and synchronize the communication of both slave with master.

What hardware, i.e. microcontroller, are you using?

You cannot have 2 devices with the same address at the I2C bus. If they both try to send at the same time with different data, the data will either get corrupted, or one of the slaves will stop to send. You cannot request data from more than 1 device at once with I2C.
You have to give the slaves different addresses. Then you have to do the requests sequentially, first a request (with the corresponding read) to the first slave and after that is done, you can start a second request (with the corresponding read).

Besides that, the reading code is not good. You are testing in the condition of the while loop, if there is anything to read (which can be only 1 byte), but then you read 2 bytes. In your case you only have to read 1 byte, since you also request only 1 byte. In the case, when you request more than 1 byte, you can either check, if there are enough bytes in the buffer (with something like if(Wire.available()>=2) ), or you can just work through the buffer byte by byte (with while(Wire.available()){ data = Wire.read();} , note the single read in the while loop).


text:
feather 32u4 servo
I am attempting a project where I use a feather 32u4 to control a servo. It is controlled using the buttons on an attached oled featherwing to set the servo to 3 different values. The code that was provided to me produces an error for this board. After messing with similar code, it appears the statement #include <Servo.h> produces an error. There is also a note in the messages about Wire.h but that appears to not be a problem any other time.
The error messages are as follows:
Arduino: 1.6.13 (Mac OS X), Board: "Adafruit Feather 32u4"

libraries/Servo/avr/Servo.cpp.o (symbol from plugin): In function `ServoCount':
(.text+0x0): multiple definition of `__vector_17'
libraries/RadioHead-master/RH_ASK.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
Multiple libraries were found for "Wire.h"
 Used: /Users/bsd194.lab102/Library/Arduino15/packages/adafruit/hardware/avr/1.4.13/libraries/Wire
 Not used: /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/Wire
exit status 1
Error compiling for board Adafruit Feather 32u4.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

I would attach the code but I don't know how to post it without it appearing oddly.

The message multiple definition of __vector_17 means, that in your code the interrupt vector 17 is defined multiple times. Often this happens, because 2 used libraries use the same hardware peripherals like the timers. Only one library can configure and use the hardware. If 2 try it, you get a compiler error.
On the Atmega32u4 the interrupt with number 17 is the TIMER1 CAPT (Capture interrupt of Timer1)(see the datasheet of the Atmega32u4, chapter "Interrupts"). The error message says, that the Servo library and the RadioHead library both define this interrupt. They both try to use the hardware Timer1.
The consequence is, that you cannot simply use these two libraries together. So what to do? This can get rather difficult. You could change one of the libraries to use a different timer (the Atmega32u4 has 4 timers). This may involve extensive changes (mostly changing the register names, but sometimes more complex changes, if the new timer is not the same type). Some libraries directly provide the possibility to use a different timer, but most don't. Fortunate for you, the RadioHead library provides a simple way to change the used timer to Timer2, tough you cannot simply do this, since on the 32u4 the next 16bit Timer is Timer3. This Adafruit forum thread mentions how to set the RadioHead library for Timer2 (by uncommenting the define RH_ASK_ARDUINO_USE_TIMER2 in RH_ASK.cpp) and give a hint on how to then change to Timer3: Effectively by Changing all the 2s in the timer register and bit names to 3s. To be sure please check everytime, that the corresponding register/bit names really exist (you can see this in the register descriptions in the datasheet).


text:
Serial communication between nodemcu and Arduino Uno
For the last days, I am trying to establish serial communication between nodemcu and Arduino Uno but I failed to do this. Currently, I am working on a Home Automation project. I receive data from nodemcu and send it to Arduino Uno, but some dummy data also receive with original data. Please help.
Nodemcu code:
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

#define Automated   D0
#define Led         D1
#define Fan         D2

#define WLAN_SSID       "JioFi2_1EAFF8"
#define WLAN_PASS       "Ode9c@,1S%31ja$1xANkeL"

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883
#define AIO_USERNAME    "_inishu"
#define AIO_KEY        "aio_HZUG00TupkcsC2dvraQM7HLHrCd4"

WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

Adafruit_MQTT_Subscribe speed = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME"/feeds/Fan");
Adafruit_MQTT_Subscribe inten = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Led");
Adafruit_MQTT_Subscribe autom = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Automate");

void MQTT_connect();
void datatransfer(int);

int on_off;
int sliderval1;
int sliderval2;
void setup(){
    Serial.begin(9600);
    pinMode(Automated, OUTPUT);
    pinMode(Led, OUTPUT);
    pinMode(Fan, OUTPUT);

    WiFi.begin(WLAN_SSID, WLAN_PASS);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
    }

    mqtt.subscribe(&autom);
    mqtt.subscribe(&speed);
    mqtt.subscribe(&inten);
}

void loop (){
    MQTT_connect();

    Adafruit_MQTT_Subscribe *subscription;
    while ((subscription = mqtt.readSubscription(5000))){
        if (subscription == &autom){
            on_off = atoi((char *)autom.lastread);
            if (on_off == 1)   digitalWrite(Automated,HIGH);
            if (on_off == 0)   digitalWrite(Automated,LOW);
        }

        if (subscription == &speed){
            sliderval1 = atoi((char *)speed.lastread);
            analogWrite(Fan, sliderval1);
        }

        if (subscription == &inten){
            sliderval2 = atoi((char *)inten.lastread);
            analogWrite(Led, sliderval2);
        }
    }
    datatransfer(on_off);
    datatransfer(sliderval1);
    datatransfer(sliderval2);
}

void MQTT_connect() {
    if (mqtt.connected()) {
         return;
    }

    while (mqtt.connect() != 0) {
        mqtt.disconnect();
        delay(2000);
    }
}

void datatransfer(int value){
    Serial.println(value);
    delay(500);
}

Arduino Uno code:
int x = A0, y = A1, z = 1;
int fan = 11, led = 10;
float temp, lux;
int autom = 1;
int inten = 0;
int speed = 0;
int fanspeed, light;

int datareceive(){
    int receiver = 0;
    while(Serial.available()==0 );
    String s = Serial.readStringUntil('\r');
    receiver = s.toInt();
    Serial.println(receiver);
    delay(1000);
    return receiver;
}

void setup(){
    Serial.begin(9600);
    pinMode(fan,OUTPUT);
    pinMode(led,OUTPUT);
    pinMode(x,INPUT);
    pinMode(y,INPUT);
    pinMode(z,INPUT);
}

void loop(){
    autom = datareceive();
    speed = datareceive();
    inten = datareceive();
    if(autom == 1){
        fanspeed = 255 - speed;
        light = 255 - inten;
        analogWrite(fan,fanspeed);
        analogWrite(led,light);
    }
    else {
        temp = analogRead(x);
        if (temp >= 52 && temp <= 104){
            int fanspeed = -4.90384615*temp + 510;
            analogWrite(fan, fanspeed);
        }
        else if(temp > 104)  digitalWrite(fan,LOW);
        else digitalWrite(fan,HIGH);
        lux = analogRead(y);
        if (lux >= 430 && lux <= 594){
            int light = 1.342657*lux-577.342657;
            analogWrite(led,light);
        }
        else if (lux < 430) digitalWrite(led, LOW);
        else digitalWrite(led,HIGH);
    }
}

You didn't describe, what actually happens, just that it doesn't work. Please add this description to your question. At the first glance I see, that you send up to every halve second, while you receive only once a second, since you delay for 1s. Why are you even delaying there? That doesn't fit any purpose

I agree with @chrisl, don't use delay, bad practice, search for "Arduino millis delay" that's a better way. And why do you transfer a value without a tag, when I have done similar tasks I have used a transfer format like ", ", example "speed, 200".

And to trouble shoot, create a simple KISS program so you learn how to do transfer over serial first before you do a more complex program.

Delete you AIO details from sketch.

give us example of data and what is extra. I for one have noticed that you use println, so after each message you are getting a newline symbol. (extra data at the end).
Although NODEMCU sends some data to serial every time it starts.
Also dont forget the difference between number and symbols of numbers. print sends numbers as their symbols, while "write" sends numbers as numbers

Arduino UNO is 5v logic and esp8266 is 3.3v logic.  You need a level shifter for them to be able to have bidirectional serial link. Alternatively you can just use a voltage divider between Arduino Tx and ESP Rx pin to protect the rx pin of the esp.

It would be a preferencial but arduino is more then capable of handling the ESP8266 input and while not ideal, esp is designed to STRESS handle up-to 5.1 volt. Full shifter is an overkill. So if you extend your message to show a simple ressistive divider to protect nodemcu, dropping message voltage from arduino tx towards nodemcu RX, your note (rather then answer) might become useful


text:
How to change variable/sketch through a GUI
Over the past few months, I've been working on a wearable computer mouse using an Arduino and a 9-dof sensor. Most of the sketch is complete, and works as expected.
Recently, I started investigating how to enable a non-technical user to adjust the sensitivity of the device. Currently, I do this by changing a couple of variables in the sketch. My goal is to be able to create a basic GUI, with some buttons (perhaps unsurprisingly), to accomplish the same.
Requirements:

ability to adjust sensitivity (couple of variables inside sketch) of arduino device through a GUI
does not slow down sketch (I read that you can use serial, but wouldn't constantly checking for serial slow down the operation of the microcontroller?)
can be saved as an executable (easy to set up for a nonprogrammer)

It's fine for the solution to upload a new sketch to the microcontroller, or change variables in the EEPROM. Whatever you suggest is best. I came across this, and a few other similar topics, but due to my inexperience was unable to judge whether that's the best way forward.
I'm not looking for a complete solution, of course. Rather, I would really appreciate any guidance on what the basic "structure" of the solution should be. Then I can determine which parts I can do myself, and which I'll need to seek help on.
Thank you very much for looking at this.

As its a wearable mouse, how does it communicate with the PC? What Arduino are you using?

There's 2 devices. A custom PCB handheld with the sensor, ATSAMD21 microprocessor, nrf24 module. That sends the information through the radio module to a USB dongle. The dongle has the same module, and uses the ATMEGA32U4. It has the arduino leonardo bootloader uploaded.

I guess your dongle is configured as HID device for the PC.

I don't think this question should be closed. It is focused enough in my eyes. The OP already has some basic approaches and we just need explain the obvious misunderstandings. I was about to write an answer when the question was closed

ok @chrisl, I still think it is too broad but if you can write an answer I reopened

Reflashing (and with that recompiling) the sketch for every variable change is very over-the-top.
As you already want to write your own program for the PC I would suggest using Serial. That will be the easiest to implement. This would work like the following:

On the Arduino: You regularly check if there is data in the Serial buffer, read if in that case. You read until a newline character \n, which acts as message delimiter (to distinguish one message from the other). If a full message was received (meaning: you read the newline character) you process the message and write the new values to EEPROM (for saving them permanently).

On the PC application: Let the user determine each value. You open the Arduinos COM port (the user will have to select the correct one) to communicate via Serial. Then you send each value, that you want to write to the Arduino, in a specific format. For example <value_name>:<value>. And don't forget the newline character at the end. Then you can close the COM port and exit the application.

This requires the user to choose the corresponding COM port. With using a custom USB profile (I think a custom HID profile should also be able to receive data) you could eliminate that, but this is a big step in difficulty for you to program.

I read that you can use serial, but wouldn't constantly checking for serial slow down the operation of the microcontroller?

No, not really. The actual receiving of data is done by the USB hardware. As processing load you only have the placing of data in the buffer (happens inside an ISR), which only is done when actual data is received, and the checking if there is data in the buffer. That also needs very short time. It should not interfere with your sampling rate. The 9-DoF sensor is most likely way slower. The actual processing of the data is also only done when you actually send data. Here the longest will be saving the data in EEPROM.
So all in all you have little to no impact on performance.

Hi Chris,
Thank you very much for taking the time to respond. This is what I was looking for; gives me a fairly good idea of the next steps of research to take.
So for the arduino code, would I be writing the code that checks for serial data in a ISR? I'm not sure what you mean by:
"As processing load you only have the placing of data in the buffer (happens inside an ISR), which only is done when actual data is received"

Do you know what interrupts and ISR are? If not I can include a short explanation about that

@ZhelyazkoGrudov: Re “would I be writing the code that checks for serial data in a ISR?”: No. That ISR is provided by the Arduino core library. You would just have to check for Serial.available() within your loop().

No thank you Chris, I don't to waste your time; will do some research first. Already familiar with interrupts, just need to check out ISRs. I think my main concern, perhaps unfounded as you mentioned, is that checking for serial using the serialUSB library for custom PCB will slow the device now.
@Edgar Bonet, thank you Edgar. So the serial.available() is an ISR? A bit confusingly, the arduino website suggests that ISRs shouldn't return anything, but this one does. https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

I'm not sure if you both remember me, but this must be like the 5th question I've had that you've answered. I really appreciate it :)

About ISR: The actual data receiving is done with ISRs in the background. You don't have to do anything with them (since that is all hidden in the Serial object). You only use Serial.available(), which checks if you have new data in the buffer. And as described: This works that fast, that it won't really change your performance. It just takes a few clock cycles. Your 9-DoF sensor will be way slower.

Also: If it would make an impact, then you would get problems at other places too. The way to go in such a case would be to use a faster microcontroller. But you already have a fast microcontroller (depending on how you are clocking it on your PCB up to 48MHz). Checking Serial isn't a problem on the Uno, which is only 16MHz. You should try it out.

Thank you, Chris! Makes sense.

Hi Chris. Just in case this pops up as a notification, I've started implementing this.


text:
Sequencing air pistons proble - Help please?
I am a beginner trying to activate 2 sets of 3 air pistons sequentially by going through the YouTube Tutorials... Help, please, pretty please?? :-)
There are 3 sets of 2 pistons, each set working in opposition.
So I have P1/P2, P3/P4, and P5/P6, each set working in opposition to squeeze at the center sequentially -
Initial state at turn-on/Reset must be:
// Step 1 Run Once:
P1 Down/P2 Up  // Move simultaneously (joining at the center) and HOLD in position -
P2 Up/P3 Down  // Move simultaneously and HOLD -
P5 Up/P6 Down  // Move simultaneously and HOLD -
// Wait for Start button -

I need to start/stop the sequencing with a toggle push-button -
I have reed-switch sensors that will give me a set of two TRANSIENT contact closure for each piston moving to the Up and Down positions -
Once started, the sequence needs to be as follows:
// Loop until Reset button is pushed -
// STEP 2: -
P1 Down/P2 Up (HOLD) // Old Initial State, unchanged -
P3 Down/P4 Up (MOVE) // Piston 3 moves Down/Piston 4 moves Up and HOLDS -
P5 Up/P6 Down (HOLD) // Still Old Initial State, unchanged -

// PROBLEM:  P3 Down AND P4 Sensors only give me a TRANSIENT closure:  These two transients MUST occur to initiate Step 3, but  they are not always exactly synched together, so my initial try by putting them in series fails... -
// I need to use that set of contact closures to trigger the next command: -
// Step 3: -
// The transient closures of P3 Down/P4 Up Sensors is the trigger needed for -
P5 Down/P6 Up (MOVE) // P5 moves Down/P6 moves Up and HOLD -
P1 Up/P2 Down (MOVE) // P1 moves Up/P2 moves Down and HOLD -
P3 Down/P4 Up (HOLD)  // P3/P4 HOLD -

// Back to Step 2 until the Reset button is pushed -

I can send you my attempt at coding for this, but it does not work unless the two sensors close simultaneously, which only happens in simulation...  ARGH..  :-(
Can someone send me a piece of code that will work for this, please?
I would really, really appreciate that...  Very frustrated right now!
You can email me at XXXXXXX.XXXX@XXXXX.XXX or text/call at (XXX)XXX-XXXX
Thanks either way.
Sincerely,
Michael
PS:  I tried to wire for a separate toggle switching for each sensor, but I run out of pins on my Arduino UNO R3... Looking into it via YouTube https://www.youtube.com/watch?v=cAT07gy4DII "Increase the digital outputs on an Arduino (PART 1 & 2)" but that is way more complex...  Trying to wade my way through that now...

do not expect two sensors to close simultaneously ... that does not happen in real life ... also, please review step 1 ... it does not make sense

When you say simultaneously, what does that means in precision? down to microsecond? or millisecond? Without code and diagram it is hard to comment on how to improve it or solve your problem. All I could think of right now is that 1) you need to have a state machine to manage all the states and transitions, 2) to make sure all actuators acts together, you probably need to directly access the registers of the MCU for activating each pin than using Arduino commands like digitalWrite().

why do you have separate signals for opposing pistons?

Writing your email address and phone number in clear text into an online site begs for receiving tons of spam and robot calls. When using this site, please also use this site for the communication. Simple Q&A

Please include your code into the question.

it does not work unless the two sensors close simultaneously

If I understand correctly, the problem is that when your Arduino detects
the second transient signal, the first one is not active anymore, and
your program doesn't remember it has already seen that first signal.
Your Arduino has memory. Thousands of bits of memory! So it can remember
quite a few things. The solution to your problem is to simply make use
of that memory. When you detect a signal that should be useful for a
future decision, take note, store it in a variable. In order for the
variable to be remembered across calls of the function where you set it,
it has to be global. Or, better yet, static local.
Here is how that could look like in code:
// A `static' variable is a variable that remembers its state across
// calls of the function. A global variable would do the same, but
// code is usually clearer when variables are defined close to where
// they are used. A `bool' (for "boolean") is a variable that can only
// be either `true' or `false'.
static bool P5_is_up, P6_is_down;

// If the sensor tells us that the P5 piston went all the way up, take
// note of the fact and remember it.
if (digitalRead(P5_up_sensor) == LOW)
    P5_is_up = true;

// Same for P6 going down.
if (digitalRead(P6_down_sensor) == LOW)
    P6_is_down = true;

// If both pistons finished their travel, we can move to the next
// step. `&&' means "and".
if (P5_is_up && P6_is_down)
    goto_step_3();

You will need to reset those variables to false at the appropriate
time. The example code above doesn't show that as it only deals with the
logic for deciding when it is time to start step 3.
You will probably end up with many of these variables, and lots of
repetitive code. So you will need to structure your program in order to
avoid excessive repetition. But that is not your immediate problem. For
now, try to make the logic work for a single step transition. Once you
get the logic right, you can worry about generalizing the logic to any
transition.