text:
Print to console
I am trying to get the string ("Enter an Integer : ") to print to the serial, then have the user enter a string of numbers which is then converted to an array of chars then ints.
The problem is the string will not display on the serial monitor when opened, and when the numbers are entered by the user, and  the conversion is done I need the string to be displayed again. So when the user inputs a number and presses enter it should be the end of that conversion, and prompt a new one.
Code below:
int convert(void) {
  while (Serial.available() > 0) {
    char ch = Serial.read();
    if (ch >= '0' && ch <= '9' || ch == '-') {
      // Collect digits, only works if minus is first.
      strValue[index] = ch;
      index++;
    } else {
      strValue[index] = '\0';
      blinkRate = atoi(strValue);
      Serial.println(blinkRate);
      Serial.print("Enter integer : ");
      index = 0;
    }
  }
}

What does the serial monitor display when you run this code and type a number?

The number does not register until I enter a letter, which is one problem. I would like the number to register when the user presses enter.

Why are you checking for '\0' instead of '\n'?

The biggest problem I see is that when your convert() function is called, if the user hasn't already typed something, then Serial.available() is going to return 0 (zero) and the while statement will never get executed.
Second, your print statement that prints the prompt to the console will only get called after you have already read a string from the user.
Third, you're trying to reinvent the wheel by writing your own function to read a string from the serial input. I suggest you use ReadStringUntil().

The problem is, the Arduino serial monitor is way too crude to understand what you're trying to do.  Using a real terminal emulator (Teraterm for example) will probably give you better results (but you will also need to echo back the characters typed so you can see what you're typing) - either that or don't try and do things "in-line" like a prompt, instead print a message including the line feed (i.e., use println() instead of print()) so that the serial monitor can output a new line with the message text in it.

It seems likely to me that you have not configured your serial monitor to send a newline. See the bottom line of the Serial Monitor.

If it is set to "no line ending" then when you send the line, you get the line only and no newline.


text:
Issue with simple project
I'm new to Arduino and today I have a problem with this code:
int led_1 = 10;
int led_2 = 11;
int led_3 = 12;
int button = 3;
int time = 0;
byte val = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(led_1, OUTPUT);
  pinMode(led_2, OUTPUT);
  pinMode(led_3, OUTPUT);
  pinMode(button, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  val = digitalRead(button);

  if (val == HIGH){
    time = millis();
    while (digitalRead(button) == HIGH) {
      if (millis() - time < 1000) {digitalWrite(led_1, HIGH);}
      else if (millis() -time > 1000 && millis()-time <2000) {digitalWrite(led_2, HIGH);}
      else if (millis()-time >2000) {digitalWrite(led_3, HIGH);}
    }
  } else {
    time =0;
    digitalWrite(led_1, LOW);
    digitalWrite(led_2, LOW);
    digitalWrite(led_3, LOW);
    }
}

The code should work like this: If I press the button less than one second, led_1 will turn on. If I press it between one and two seconds, led_2 will turn on; and if I press the button more than 2 seconds, led_3 will turn on. If I don't press a button, the LEDs remain off. The time variable is used to take the time when I start to press the button and then the control millis()- time should give how long I press the button.
It works for a while, then after a random time (I think) if I push the button, only the led_3 turns on. Why?

Please explain what your code is supposed to do. You can't just dump the code on us, an expecting us to decipher what it does. Also, what is a casual?

edited the question with more informations

Thank you. Just use unsigned long time = 0; instead. What I also see, is that led 1 remains on, even if the button is pressed for more that one second. Idem for led 2 after two seconds.

time should be an unsigned int.  As soon as millis reaches 32768, it will be stored as -32768 in time, and your comparisons will not work. This happens after 32.768 seconds.  Here's a short sketch to illustrate:
int time = 0;

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

void loop() {
    time = millis();
    if (time % 1000 == 0) {
      Serial.println( time );
      delay( 2 ); // let millis() increment
    }
}

To see the difference, just change the first line to
unsigned int time = 0;

Note how time rolls over to 0 after 65535 (well, only 65000 is printed).
I would recommend using unsigned constants by adding a "U" after the digits: 1000U.  In your if statements, you must cast the millis to the same (smaller) type: (unsigned int)millis().  Also, parentheses make the expression more clear:
      else if (((unsigned int)millis() - time > 1000U) && ((unsigned int)millis() - tempo < 2000U)) {digitalWrite(led_2, HIGH);}

32768 will actually become -32768 not -1. I also think this will create a new problem after 65 seconds. Better to just use the same type that millis return. I.e. unsigned long.

Oopsies, edited -1 above.  However, he can use any size of unsigned int.  The key is to compare a difference with the desired interval: (unsigned int)millis()-start > interval, all unsigned numbers.  If he were watching for intervals < 256, he could have used unsigned char.

Thank you for the replies,I have solved the problem, but I have a question: I see that int time reaches 32768 and then becomes -32768, but after that it returns positive again. If I wait for 65 seconds (so time is positive) the LED still doesn't work. Why?
What does U mean?

Yes, I forgot that you need to cast the millis() to the smaller type.  My example does an implicit cast by assigning to the smaller unsigned int.  Edited answer and comment.

This is getting a bit silly. Casting the millis to an int?! Just use the proper type that is returned by millis, and use unsigned long time = 0;. This makes the code a lot more readable.

If millis is called just once and stored in a byte or word, like my example, there is no explicit cast (no impact on readability).  One would normally do this when grabbing a timestamp for comparison.  It does change the subtraction and comparison to a smaller type.  When the interval is small and the polling frequency is high, it can have significant run-time savings.  Another handy technique is to use the byte-sized TCNT0 directly and simply compare the elapsed ticks with interval/4.  This allows intervals up to ~1s and is efficient enough to use in an ISR or busy-wait loop.

Your code seems inefficient and there is a tempo variable that doesn't appear elsewhere.
  if (val == HIGH) {
    time = millis();
    while (digitalRead(button) == HIGH) {
      int time0=millis();
      if (time0 - time < 1000) {
        digitalWrite(led_1, HIGH);
      } else if (time0 - time < 2000) {
        digitalWrite(led_2, HIGH);
      } else if (time0 - time > 2000) {
        digitalWrite(led_3, HIGH);
      }
    }
  }

Note that this code will turn on all LEDs, one by one. If you want to turn off the other, you'll have to had code for that in the tests.

source: Stack Exchange

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

sort: votes


text:
Replacing delay() with millis()
I'm currently attempting to replace delay() in my project so that i may perform other tasks while waiting on a particular event to fire.
The issue I'm having, is every example i've found using millis / elapsedmillis has everything inside the loop, where I'm trying to use it inside void buttons(). needless to say, either it's not going to work outside of loop, or I'm doing something ridiculous, and too tired, or too ignorant to see what i'm doing wrong..
The end goal is to have the button draw over the top of the existing one, wait 1000ms then draw the next button.
(time interval will be changed later to sync with hardware spin down etc)
Here is the complete sketch, perhaps someone can show me a reliable way to replace delay in the buttons funciton:
#include <Adafruit_GFX.h>
#include <TouchScreen.h>
#include <stdint.h>
#include <SPI.h>
#include <SD.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#include <elapsedMillis.h>

elapsedMillis timer0;
elapsedMillis sinceTime1;
elapsedMillis sinceTime2;
elapsedMillis sinceTime3;

#define debug = false;
//#define debug = true;

#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif

// most mcufriend shields use these pins and Portrait mode:
uint8_t YP = A1;  // must be an analog pin, use "An" notation!
uint8_t XM = A2;  // must be an analog pin, use "An" notation!
uint8_t YM = 6;   // can be a digital pin
uint8_t XP = 7;   // can be a digital pin
uint8_t Landscape = 0;

uint16_t TS_LEFT = 120;
uint16_t TS_RT = 940;
uint16_t TS_TOP = 940;
uint16_t TS_BOT = 180;
#define MINPRESSURE 10
#define MAXPRESSURE 1000

// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 250 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0

// Assign human-readable names to some common 16-bit color values:
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

int16_t BOXSIZE;
int16_t PENRADIUS = 3;
uint16_t oldcolor, currentcolor;

#define SD_SCK 13
#define SD_MISO 12
#define SD_MOSI 11
#define SD_CS 10
// In the SD card, place 24 bit color BMP files (be sure they are 24-bit!)

void setup() {
  // Init TouchScreen
    ts = TouchScreen(XP, YP, XM, YM, 300);     //call the constructor AGAIN with new values.

    BOXSIZE = tft.width() / 6;
    tft.fillScreen(BLACK);

  // put your setup code here, to run once:
    Serial.begin(9600);

  tft.reset();

  uint16_t identifier = tft.readID();
if (identifier == 0x7789) {
        //Serial.println(F("Found ST7789V LCD driver"));
        TS_LEFT = 120; TS_RT = 940; TS_TOP = 940; TS_BOT = 180;
        Landscape = 1;
    } else {
        //Serial.print(F("Unknown LCD driver chip: "));
        //Serial.println(identifier, HEX);
        return;
    }

    //Serial.print(F("Found LCD driver chip ID: "));
    //Serial.println(identifier, HEX);

  tft.begin(identifier);

  //Serial.print(F("Initializing SD card..."));
  if (!SD.begin(SD_CS, SD_MOSI, SD_MISO, SD_SCK)) {
    Serial.println(F("failed!"));
    return;
  }
  //Serial.println(F("OK!"));
  tft.begin(identifier);
  tft.setRotation(3);
  BOXSIZE = tft.width() / 6;
  tft.fillScreen(BLACK);
  bmpDraw("splash.bmp", 80, 20);
  delay(5000);
  loadhome();

}

void loop() {
//DO STUFF HERE

//Testing Text stuff here
  tft.setTextColor(BLACK);
  tft.setTextSize(2);
  tft.setCursor(15, 33);
  tft.print("123.456");
  tft.setTextColor(BLACK);
  tft.setCursor(115, 33);
  tft.print("543.210");
  tft.setTextColor(BLACK);
  tft.setCursor(215, 33);
  tft.print("789.654");
  buttons();
}

void loadhome(){
  tft.setRotation(3);
  BOXSIZE = tft.width() / 6;
  tft.fillScreen(BLACK);
  bmpDraw("cell.bmp", 10, 25);
  bmpDraw("cell.bmp", 110, 25);
  bmpDraw("cell.bmp", 210, 25);
  bmpDraw("stop.bmp", 15, 175);
  bmpDraw("locked.bmp", 90, 175);
  bmpDraw("play.bmp", 165, 175);
  bmpDraw("home.bmp", 240, 175);
  bmpDraw("coolstp.bmp", 15, 105);
  bmpDraw("spinstp.bmp", 240, 105);

  tft.setTextColor(RED);
  tft.setTextSize(3);
  tft.setCursor(50, 3);
  tft.print("X");
  tft.setTextColor(RED);
  tft.setCursor(150, 3);
  tft.print("Y");
  tft.setTextColor(RED);
  tft.setCursor(250, 3);
  tft.print("Z");

}

int homer = 0;
int play = 1;
int lock = 0;
int cool = 0;
int spin = 0;

const int interval = 1000;
unsigned long curMillis; //Current millis

void buttons(){
  //Touchscreen stuff
    TSPoint p = ts.getPoint();

    // if sharing pins, you'll need to fix the directions of the touchscreen pins
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);

    p.x = map(p.x, TS_LEFT, TS_RT, 0, tft.width());
    p.y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
/*
//Use to map buttons
//Be sure to mark out button code before use!!
 if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
    Serial.print(F("p.y ="));
    Serial.print(p.y);
    Serial.println("");
    Serial.print(F("p.x ="));
    Serial.print(p.x);
    Serial.println("");
 }
*/
// Begin Buttons
//Coolant Button
if (p.y > 110 && p.y < 170 && p.x > 250 && p.x < 300) { // if stop area is pressed
  if(cool == 0){
   bmpDraw("coolen.bmp", 15, 105);
   //Serial.println(F("Coolant Button Pressed!"));
   cool = 1;
  } else {
   bmpDraw("coolerr.bmp", 15, 105);
   sinceTime1 = 0;
   //delay(500); //replacing with millis()
   if (sinceTime1 >= 1000) {
   bmpDraw("coolstp.bmp", 15, 105);
   //Serial.println(F("Coolant Button Pressed!"));
   cool = 0;
   }
  }
}

//Stop Button
if (p.y > 185 && p.y < 235 && p.x > 250 && p.x < 300) { // if stop area is pressed
   //Serial.println(F("Stop Button Pressed!"));
   Serial.write(0x18);
   Serial.print("\n");
}

//Lock Button
if (p.y > 185 && p.y < 235 && p.x > 182 && p.x < 234) { // if stop area is pressed
  if(lock == 0){
    Serial.print("$X\n");
   bmpDraw("unlocked.bmp", 90, 175);
   //Serial.println(F("Lock/Unlock Button Pressed!"));
   lock = 1;
  } else {
    Serial.print("$X\n");
   bmpDraw("locked.bmp", 90, 175);
   //Serial.println(F("Lock/Unlock Button Pressed!"));
   lock = 0;
  }
}

//Play-Pause Button
if (p.y > 185 && p.y < 235 && p.x > 110 && p.x < 160) { // if stop area is pressed
  if(play == 0){
   Serial.print("~\n");
   bmpDraw("play.bmp", 165, 175);
   //Serial.println(F("Play/Pause Button Pressed!"));
   play = 1;
  } else {
   Serial.print("!\n");
   bmpDraw("pause.bmp", 165, 175);
   //Serial.println(F("Play/Pause Button Pressed!"));
   play = 0;
  }
}

//Home Button
if (p.y > 185 && p.y < 235 && p.x > 35 && p.x < 90) { // if stop area is pressed
  if(homer == 0){
   bmpDraw("homeg.bmp", 240, 175);
   //Serial.println(F("Home Button Pressed!"));
   homer = 1;
  } else {
   Serial.print("$H\n");
   bmpDraw("homey.bmp", 240, 175);
   sinceTime2 = 0;
   //delay(500); //replacing with millis()
   if (sinceTime2 >= 1000) {
   bmpDraw("homer.bmp", 240, 175);
   }
   //delay(500); //replacing with millis()
   sinceTime2 = 0;
   if (sinceTime2 >= 1000) {
   //delay(750);
   bmpDraw("homeg.bmp", 240, 175);
   //Serial.println(F("Home Button Pressed!"));
   }
   homer = 1;
  }
}

//Spindle Button
if (p.y > 110 && p.y < 170 && p.x > 35 && p.x < 90) { // if stop area is pressed
  if(spin == 0){
   bmpDraw("spinen.bmp", 240, 105);
   //Serial.println(F("Spindle Button Pressed!"));
   spin = 1;
  } else {
   bmpDraw("spinerr.bmp", 240, 105);
   sinceTime3 = 0;
   //delay(500); //replacing with millis()
   if (sinceTime3 >= 1000) {
   bmpDraw("spinstp.bmp", 240, 105);
   //Serial.println(F("Spindle Button Pressed!"));
   }
   spin = 0;
  }
}

}

#define BUFFPIXEL 15

void bmpDraw(char *filename, int x, int y) {

  File     bmpFile;
  int      bmpWidth, bmpHeight;   // W+H in pixels
  uint8_t  bmpDepth;              // Bit depth (currently must be 24)
  uint32_t bmpImageoffset;        // Start of image data in file
  uint32_t rowSize;               // Not always = bmpWidth; may have padding
  uint8_t  sdbuffer[3*BUFFPIXEL]; // pixel in buffer (R+G+B per pixel)
  uint16_t lcdbuffer[BUFFPIXEL];  // pixel out buffer (16-bit per pixel)
  uint8_t  buffidx = sizeof(sdbuffer); // Current position in sdbuffer
  boolean  goodBmp = false;       // Set to true on valid header parse
  boolean  flip    = true;        // BMP is stored bottom-to-top
  int      w, h, row, col;
  uint8_t  r, g, b;
  uint32_t pos = 0, startTime = millis();
  uint8_t  lcdidx = 0;
  boolean  first = true;

  if((x >= tft.width()) || (y >= tft.height())) return;

  //Serial.println();
  //Serial.print(F("Loading image '"));
  //Serial.print(filename);
  //Serial.println('\'');
  // Open requested file on SD card
  if ((bmpFile = SD.open(filename)) == NULL) {
    Serial.println(F("File not found"));
    return;
  }

  // Parse BMP header
  if(read16(bmpFile) == 0x4D42) { // BMP signature
    read32(bmpFile);
    //Serial.println(F("File size: "));
    //Serial.println(read32(bmpFile));
    (void)read32(bmpFile); // Read & ignore creator bytes
    bmpImageoffset = read32(bmpFile); // Start of image data
    //Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
    // Read DIB header
    read32(bmpFile);
    //Serial.print(F("Header size: "));
    //Serial.println(read32(bmpFile));

    bmpWidth  = read32(bmpFile);
    bmpHeight = read32(bmpFile);
    if(read16(bmpFile) == 1) { // # planes -- must be '1'
      bmpDepth = read16(bmpFile); // bits per pixel
      //Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
      if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed

        goodBmp = true; // Supported BMP format -- proceed!
       // Serial.print(F("Image size: "));
       // Serial.print(bmpWidth);
       // Serial.print('x');
       // Serial.println(bmpHeight);

        // BMP rows are padded (if needed) to 4-byte boundary
        rowSize = (bmpWidth * 3 + 3) & ~3;

        // If bmpHeight is negative, image is in top-down order.
        // This is not canon but has been observed in the wild.
        if(bmpHeight < 0) {
          bmpHeight = -bmpHeight;
          flip      = false;
        }

        // Crop area to be loaded
        w = bmpWidth;
        h = bmpHeight;
        if((x+w-1) >= tft.width())  w = tft.width()  - x;
        if((y+h-1) >= tft.height()) h = tft.height() - y;

        // Set TFT address window to clipped image bounds
        tft.setAddrWindow(x, y, x+w-1, y+h-1);

        for (row=0; row<h; row++) { // For each scanline...
          // Seek to start of scan line.  It might seem labor-
          // intensive to be doing this on every line, but this
          // method covers a lot of gritty details like cropping
          // and scanline padding.  Also, the seek only takes
          // place if the file position actually needs to change
          // (avoids a lot of cluster math in SD library).
          if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
            pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
          else     // Bitmap is stored top-to-bottom
            pos = bmpImageoffset + row * rowSize;
          if(bmpFile.position() != pos) { // Need seek?
            bmpFile.seek(pos);
            buffidx = sizeof(sdbuffer); // Force buffer reload
          }

          for (col=0; col<w; col++) { // For each column...
            // Time to read more pixel data?
            if (buffidx >= sizeof(sdbuffer)) { // Indeed
              // Push LCD buffer to the display first
              if(lcdidx > 0) {
                tft.pushColors(lcdbuffer, lcdidx, first);
                lcdidx = 0;
                first  = false;
              }
              bmpFile.read(sdbuffer, sizeof(sdbuffer));
              buffidx = 0; // Set index to beginning
            }

            // Convert pixel from BMP to TFT format
            b = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];
            lcdbuffer[lcdidx++] = tft.color565(r,g,b);
          } // end pixel
        } // end scanline
        // Write any remaining data to LCD
        if(lcdidx > 0) {
          tft.pushColors(lcdbuffer, lcdidx, first);
        }
       // Serial.print(F("Loaded in "));
        //Serial.print(millis() - startTime);
        //Serial.println(" ms");
      } // end goodBmp
    }
  }

  bmpFile.close();
  if(!goodBmp) Serial.println(F("BMP format not recognized."));
}

// These read 16- and 32-bit types from the SD card file.
// BMP data is stored little-endian, Arduino is little-endian too.
// May need to reverse subscript order if porting elsewhere.

uint16_t read16(File f) {
  uint16_t result;
  ((uint8_t *)&result)[0] = f.read(); // LSB
  ((uint8_t *)&result)[1] = f.read(); // MSB
  return result;
}

uint32_t read32(File f) {
  uint32_t result;
  ((uint8_t *)&result)[0] = f.read(); // LSB
  ((uint8_t *)&result)[1] = f.read();
  ((uint8_t *)&result)[2] = f.read();
  ((uint8_t *)&result)[3] = f.read(); // MSB
  return result;
}

Please edit your code down to the minimum required to demonstrate and debug the problem.

Do you want the buttons and processes to act independently from each other, or do you want some kind of blocking?  Like "Press Coolant" runs does the coolant for 1000ms, but does or does not allow "Stop" to be pressed?  do the buttons block each other?

For "Spindle Button" should what should happen if you hold your finger on it for 10 seconds?  Start up spin, make the button be 'spinen.bmp' for one loop(), then display 'spinerr.bmp' for 1000ms, then display 'spinstp.bmp', shut off the spin, and repeat?  I'd keep a state variable for the screen handling a touch so you don't cycle/race, and add it to the if(p...) condition.  I think I'd move the button-de-animation out of the if(p....) condifional.

The whole idea is to give a visual representation of the device doing "something".
My thinking was to time how long it takes the spindle to spin down and stop, use that time for the timer..
So an example would be, the spinde takes 5 seconds to slow down and stop, when user push the button, the command to stop the spindle is sent, the button is redrawn from green(on) to yellow(slowing) then to red(stopped) after 5secs. same for coolant, and homing.
I'm trying to use something other than delay, as i need serial to update the X, Y and Z positions. and have access to stop in case of emergency

The usual technique at this scale of technology is to keep loop() pretty short, mostly making frequent calls to a timer function that keeps a list of things to be done (implemented with callback-functions) and the times at which to do them, and which calls those functions at the appropriate times. The upper level(s) of your sketch would schedule tasks by registering one or more callback-functions to be run at a given time or periodically.
When the timer function is called, if there is nothing to do, or when a callback-function returns, the timer function returns immediately to its caller (probably loop()). loop() can do other work, as long as it can still call the timer function as frequently as your task dispatching requires.
The SimpleTimer library at Arduino Playground is an implementation of such a timer-function.

Taking JRobert's advice, i checked out the simpletimer library.. the final solution was to set up three timers and change the way the buttons functioned.
as per documentation of the simpletimer library, added the following global:
#include <SimpleTimer.h>
SimpleTimer timer;
...

Then to setup, i added my three timers
timer.setInterval(7000, spindle); //times based on hardware reality
timer.setInterval(2000, coolant);
timer.setInterval(21500, homer);
...

Then started the timers in loop by adding:
timer.run();
...

Finally, i edited the buttons and added variables to denote state of button.
i.e.
/*
0 == on,
1 == transitional1
2 == transitional2
3 == stopped
*/
int homeb = 0;
int cool = 0;
int spin = 0;

Changed the touch screen code for each button to kick off the timers...
//Coolant Button
if (p.y > 110 && p.y < 170 && p.x > 250 && p.x < 300) { // if stop area is pressed
  if(cool == 3){
   bmpDraw("coolen.bmp", 15, 105);
   //PWM the spindle pin on
   cool = 0;
  } else {
    if(cool == 0){
      //PWM the spindle pin off
      cool = 1; //Start the timer sequence for stopping coolant
    }
  }
}

then i added a void for each timer, this is where i redraw the buttons
void coolant() {
  if (cool == 1){
   bmpDraw("coolerr.bmp", 15, 105);
   cool = 2;
  } else {
    if (cool = 2){
   bmpDraw("coolstp.bmp", 15, 105);
   cool = 3;
    }
  }
}

Hope this helps someone else in the future, as it was a real pickle for me to figure out at first.. Thanks again, and credit goes to JRobert, his advice pointed me directly to the solution.

Glad to have helped - and thanks for posting your implementation.

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


text:
Scrolling an I2C text
I want tried to make a programm to display a text on an I2C LCD-Display.
The text should be scrolled for one position every time the function is called.
On the internet I saw a lot of solutions but there were all diffrent from what I need.
So I tried to make my own code.
The code works well except of the part where I try to scroll in the Text from the left.
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);

char Str[12] = {'T', 'r', 'u', 'e', 't', 'z', 's', 'c', 'h', 'l', 'e', 'r'};
int pos = 0;
int posretry = 0;
bool ledon = false;

void setup()
{
  pinMode(13, OUTPUT);

  lcd.init();
  lcd.backlight(); //lcd.noBacklight();
}

void scroll()
{
  for (int i = 0; i < 12; i++)
  {
    //Print text
    lcd.setCursor(i + pos, 0);
    lcd.print(Str[i]);

    //Move in text from the left

    if (pos >= 6)
    {
      lcd.setCursor(i + pos, 0);
      lcd.print(Str[i]);

      lcd.setCursor(posretry, 0);
      lcd.print(Str[11 - posretry]);

      posretry++;
    }
  }
  delay(500);
  lcd.clear();

  pos++;
}

void changeled()
{
  if (ledon == false)
  {
    digitalWrite(13, LOW);
  }
  else
  {
    digitalWrite(13, HIGH);
  }

  ledon = !ledon;
}

void loop()
{
  scroll();
  changeled();  //Example Event
}

The goal is to move the text to the right and show the not displayed letters on the left.
Example:
|er    Truetzschl|  -->
|                |

A Video about the error can be found here:
https://data.jonas-heinze.de/shares/stackexchange/lcd/
Thanks for your help.

What doesn’t work about it?  You didn’t give us a symptom.  You did describe your expected behavior so good job on that.  Now you need to say what actually happens and how that’s different from your expectations.

Oh im so sorry I forget to describe the problem. I added a video of the problem to my post.

OK, I would have helped if you could have described it, but I can't see the video on this device.  Good luck.

A diffrent Text seems to randomly shown up. Sometimes in the first other times in the second row. The often are strange characters. Its hard to explain. Cause of that I added the Video.

Hmm, should be an easy task where you just need to increment a string index and handle its overflow. What do you achieve by checking if(pos>=6)? Do you really need posretry (for what)? A serious problem is that you never reset pos and posretry, so they will exceed the allowed range and even become negative when the int overflows itself. Definitely not right

Not so easy to nail it down just by seeing the video and without having your hardware to actually test it, but I'm sure you are doing it way more complicated than neccessary.

I understand its difficult to nail it down. What would the way you do it?

The word should come in from the left if (pos >= 6): Cause if the first letter is around that position the last letter is cut of by the display limitation. So its like:
if (pos >=6){start coming in from left}.
The posretry was just a workaround to print the last letter(s) in the first position(s).
Do you understand what I mean?

You do some strange things that I, at least, don't understand (e.g. I don't see what you need posretry for), but you might have a reason for doing so.
But you don't reset posretry and pos, which means they will very soon be out of a reasonable range. At some point the int will actually overflow to negative values, which is definitely not going to work!
To make it less complicate, you should write a function that prints the char array shifted by a desired value as a beginning.
The below code is completely untested as I don't have your hardware and I'm aware that it does not include all your desired features. But it should give you an idea of how scrolling can be implemented in principle and it's up to you to improve/fix it.
#define LCD_SIZE 16
#define STR_LEN 12
char str_to_print[STR_LEN]={'T', 'r', 'u', 'e', 't', 'z', 's', 'c', 'h', 'l', 'e', 'r'};

void print_scrolled (uint8_t scrolled_by) {
  for (uint8_t i=0;i<LCD_SIZE;i++) {
    lcd.set_cursor(i,0);
    if (scrolled_by>=LCD_SIZE) scrolled_by=0;

    if (scrolled_by<STR_SIZE) lcd.print(str_to_print[scrolled_by]);
    else lcd.print(' ');
    scrolled_by++;
  }
}

You could call it like this:
for (uint8_t i=0;i<STR_LEN;i++) {
  print_scrolled(i);
  delay(500);
}

Once you are familiar with my approach you should be able to enhance it with additional features (end of text coming in from the other side, spaces between end and beginning, etc).

Thank you very much. I will do some testing tomorrow. Have a nice day

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


text:
Trying to move servo motor via 3 buttons

I am having some difficulties in trying to make my servo motor move to a specific angle based on the button pressed.
For example, having the motor start at 0 degrees and then having it move to 180 when the 3rd button is pressed, have it return to 0 degrees when the first button is pressed, and have it go to 90 degrees when the second button is pressed, etc, etc.
I can't tell if I am going about this all wrong or not with my code, so if anyone could provide some assistance with this it would be a great help
EDIT: Added the wiring as a just in case
#include <Servo.h>

Servo myservo;
int angle = 0;
int anglestep = 10;

#define FIRST 2 // pin 2 is connected to 1st floor button
#define SECOND 3 // pin 3 is connected to 2nd floor button
#define THIRD 4 // pin 4 is connected to 3rd floor button
#define SIGNAL 10

void setup()
{
Serial.begin(9600);
myservo.attach(10);
myservo.write(angle);
pinMode(2,INPUT_PULLUP);
pinMode(3,INPUT_PULLUP);
pinMode(4,INPUT_PULLUP);
Serial.println("Lift/Descend");
}

void loop()
{
while (digitalRead(FIRST) == LOW)
    {
    if (angle > 0 && angle <= 90) //2to1
        {
        angle = angle - anglestep;
            if (angle < 0)
            {
            angle = 0;
            }
            else
            {
            myservo.write(angle);
            Serial.print("Moved to: ");
            Serial.print(angle);
            Serial.println(" degree");
            }
        }
    else if (angle > 90 && angle <= 180) //3to1
    {
        angle = angle - anglestep;
            if (angle < 0)
            {
            angle = 0;
            }
            else
            {
            myservo.write(angle);
            Serial.print("Moved to: ");
            Serial.print(angle);
            Serial.println(" degree");
            }
    }
    else //1on1
    {
        angle = 0;
    }

}
while (digitalRead(SECOND) == LOW)
    {
    if (angle > 90 && angle <= 180) //3to2
        {
        angle = angle - anglestep;
        if (angle > 90)
            {
            angle = 90;
            }
        else
        {
        myservo.write(angle);
        Serial.print("Moved to: ");
        Serial.print(angle);
        Serial.println(" degree");
        }
    }
    else if (angle > 0 && angle < 90) //1to2
        {
        angle = angle + anglestep;
        if (angle < 90)
            {
            angle = 90;
            }
        else
        {
        myservo.write(angle);
        Serial.print("Moved to: ");
        Serial.print(angle);
        Serial.println(" degree");
        }
    }
    else
    {//2on2//
    angle = 90;
    }
}

while (digitalRead(THIRD) == LOW)
{
    if (angle > 0 && angle <= 90) //1to3
    {
        angle = angle + anglestep;
        if (angle > 180)
            {
            angle = 180;
            }
        else
        {
        myservo.write(angle);
        Serial.print("Moved to: ");
        Serial.print(angle);
        Serial.println(" degree");
        }
    }
    else if (angle > 90 && angle < 180)
    {//2to3
        angle = angle + anglestep;
        if (angle > 180)
            {
            angle = 180;
            }
        else
        {
        myservo.write(angle);
        Serial.print("Moved to: ");
        Serial.print(angle);
        Serial.println(" degree");
        }
    }
    else
        {
        angle = 180;
        }
    }
}

And what is the problem? You forgot to describe, what  does not work as expected and how.

You are really overthinking things there. A servo will move to an angle if you just give it the final angle to move to. You don't need to nudge it to the final angle by visiting every angle in between, and you don't need to know what angle it's at currently.
You can simply do:
if (digitalRead(FIRST) == LOW) {
    myservo.write(0);
}

if (digitalRead(SECOND) == LOW) {
    myservo.write(90);
}

if (digitalRead(THIRD) == LOW) {
    myservo.write(180);
}

However if you wanted to slow the movement down, which would entail moving the servo in smaller steps, I would separate out the current angle and positioning from the buttons, which would set a desired angle.  Something more like:
static uint8_t desiredAngle = 0;
static uint8_t currentAngle = 0;
static uint32_t timestamp = millis();

// Choose a new desired angle
if (digitalRead(FIRST) == LOW) {
    desiredAngle = 0;
}

if (digitalRead(SECOND) == LOW) {
    desiredAngle = 90;
}

if (digitalRead(THIRD) == LOW) {
    desiredAngle = 180;
}

// Every 10ms "tick" the servo towards the desired
// angle by 1 degree
if (millis() - timestamp >= 10) {
    timestamp = millis();
    if (desiredAngle > currentAngle) {
        currentAngle++;
        myservo.write(currentAngle);
    } else if (desiredAngle < currentAngle) {
        currentAngle--;
        myservo.write(currentAngle);
    }
}

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


text:
What's the 2nd ICSP header for in Arduino Uno R3?
Looking at my Arduino Uno R3 board and its reference design schematic I noticed that there's a second ICSP 6-pin header. In the schematic, the connector I'm referring to is named ICSP1.
What's that for?
What useful things can an average Arduino user like me do with it?
The relevant part of the schematic is below (marked in red).

I've been wondering a similar thing, not so much what it's for, but what else we could do with it. It has to be asked: http://arduino.stackexchange.com/questions/991/can-the-2nd-mcu-on-the-uno-r3-be-used-for-keyboard-emulation

It's for the other MCU on the board.
The main MCU on the Uno is labelled "ZIC1". This is the one that is programmed when you press "Upload" in the IDE. But unlike other Arduinos that use a FTDI chip to connect to the serial port on the main MCU, the Uno uses another MCU instead, labelled "U3" on the left. This MCU runs a small bit of code that acts as a serial port via USB and passes through the bytes to its USART1. This then connects to the USART on the main MCU, where the bootloader on that chip accepts the bytes coming through and writes to flash and EEPROM on the main MCU.
You can use this additional MCU as you would any other, but the only I/O it has available are the USB connection, the SPI connection via its ICSP header, the UART1 connection to both the main MCU and pins 0 and 1, and two LEDs on PD4 and PD5.

that's really interesting! Thanks for the info. +1

I noticed this only yesterday after trying to utilise the TX and RX LEDs in my project. I pulled out the schematic to realise they weren't connected where I expected.


text:
Two motors in one set of pins/plugs
I have been putting together a small robot using an Arduino Motor Shield R3. The shield has two sockets for motors, however the wheel carriage I bought has four motors. I tried putting both right side motors in one socket set, and the left side motors in the other socket set.
When I turn on the Arduino, the left side motors turn together according to how I coded the board, however the right side behaves differently.
One of the motors does not start. If I push it a little it will start turning. Though not always. When I plugged in the misbehaving motor by itself, it runs correctly.
I am wondering about cause of the problem here. Is it likely the second motor on the right side is faulty? Or am I trying to use up too much power and disrupting the current?

What are the ratings of the motors you are using?

This is the info I have from a website, the motors themselves did not come with this.Operating voltage: 3V~12VDC (recommended operating voltage of about 6 to 8V)

Maximum torque: 800gf cm min (3V)
No-load speed: 1:48 (3V time)
the load current: 70mA (250mA MAX) (3V)
This motor with EMC, anti-interference ability. The microcontroller without interference.

Sometimes two motors in parallel causes this problem - the stall current of one motor causes the overall voltage to drop under load and stops the other motor from starting. So that second motor is probably NOT faulty. You might need a higher current battery (but the same voltage), it also might help to make sure the power supply to the arduino and the shield are separate - that shield seems to have a jumper for that. Best, but expensive solution would be to have separate drivers for each motor...

Do you have a DMM (digital multi-meter) available? It would help to take the guesswork out of troubleshooting problems like this. Even a cheap one is better than no meter.

@radiobrain77, one other thing. What voltage battery are you using? (The motor driver you are using may drop a little bit of voltage before it gets to the motors.) Also is there a "Stall current" for your motors,and if so what is it?

The drive capacity of the Motor Shield should match the motors – two of the motors. The shield was probably designed for a load of one motor, and you're giving two, so it is possible that neither of the motors on that side is getting enough current to get started. Here are somethings to check to get started:

Find the drive capacity of the Motor Shield and compare it to the motors (if you don't have specs for the motors you could measure the current they draw if you have an DMM). It might be wise to measure the current anyway, just in case you have a defective motor or shield.
If the capacity or the current draw is out of line, that's your problem. You can probably just add a power transistor to the circuit to drive the motors in this case.
Try it with just one motor on each output and see if they run normally. If they do, that would suggest a loading problem or a defective motor or shield. You can sort out which is which by swapping sides – if one motor runs and the other doesn't, swap them. If the problem follows the motor, then blame the motor, otherwise blame the shield.


text:
How to add new pins in the Arduino Due
I want to modify (extend) g_APinDescription array defined in the variant.cpp.
It is necessary for new pin addition. I want to use PB0-PB7 ports as an external interrupts.
I tried the following code:
g_APinDescription = (const PinDescription *) realloc(g_APinDescription, (103 * sizeof(const PinDescription)));

I have a compilation errors:

invalid use of array with unspecified bounds

I'm not C expert and don't know what is wrong here.
I want to use several pins which are unconnected on the DUE.
Usual read and write is simple to implement but if I want to use the interrupts then difficulties arrive.

Are you editing the variant or trying to modify it from within your sketch? How do you realloc a constant...?

I don't want to edit any existing files. I want to do everything from my sketch.

For mega seems it is easier:
ISR(EXT_INT0_vect)
{
}
I didn't find anything similar for due


text:
ISR not working as it is supposed to
For a battery charging project, i am using an ARDUINO UNO which is driving a buck converter to provide the battery with the charging current. I am using external ADCs to measure the battery's charging voltage and current. The test setup is working fine, but right now i am just measuring the voltage and current at random time instants. However to measure it correctly, battery voltage reading should be done at an instant when the controller's PWM output is LOW (OFF duty cycle), and battery current reading should be done when PWM output is HIGH (ON duty cycle).
I looked into interrupts and learned about them that there are 2 types of interrupts in Arduino namely "external", and "pin change". So i downloaded the "PinChangeInt Library" to test it. I wrote a small test program where a PWM of 62.5kHz is being generated on pin3, and i am calling rising and falling edge triggered interrupts on this pin, i.e to display one value when rising edge occurs, and other value when falling edge occurs.  My code looks like following:
    #include <PinChangeInt.h>
    #define pw 3
    int pwm;

    void setup() {
      // put your setup code here, to run once:
      pinMode(pw, OUTPUT) ;
      pwm_setup();             // Set PWM to a frequency of 62.5kHz

      PCintPort::attachInterrupt(pw,rise,RISING);    // call void rise() when PWM is HIGH
      PCintPort::attachInterrupt(pw,fall,FALLING);   // call void fall() when PWM is LOW

      Serial.begin(9600);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      pwm = 127;                                                // 50% duty cycle
      pwm_on(pwm);

    }
    void pwm_setup()
    {

      TCCR2A = 0x23 ;
      TCCR2B = 0x09 ; // mode 7, clock prescale by 1
      OCR2A = 256-1 ;  // 256 clock periods = 16us per cycle
      OCR2B =0 ;
      TCNT2 =0 ;

    }
    void pwm_on(double)
     {
        OCR2B = pwm ;
     }

    void rise()
    {
      Serial.println("RISE");
    }

void fall()
{
  Serial.println("fall");
}

But it is not working the way i think it should. It keeps on displaying "fall" every time, whereas according to me it should display "RISE" and "fall" alternatively, right ? However if i remove the "PCintPort::attachInterrupt(pw,fall,FALLING); " line, it starts to display "RISE" as it is supposed to.
Since its my first time programming with Arduino, and i am just a beginning level programmer, i might be making some stupid mistake here. So can anyone point it out please ?
Your helpful comments and suggestions would be appreciated.
Thankyou!

I'm totally against big interrupt service routines. They are against everything ISR represent. So, in my opinion, you'd better throw away the library and start coding yourself. Register on the proper ISR (you can attach to the interrupt INT1, for instance, or to the portD pin change) and, in this ISR, check the pin value. Then set a flag and, in the loop, call the serial function. NEVER use serial inside an ISR, since serial functions are really slow (and you should stay in ISRs the minimum time you need)

Here are a few items to consider.

From #define pw 3 you are working with PD3, INT1.  As one of the Atmega328 Uno's two external interrupts, INT1 supports RISING and FALLING events separately.  Pin change interrupts (PCIs) on pins other than 2 or 3 of the Uno won't separate them and in the interrupt routine (one interrupt routine in that case, not two) you will need to test which occurs by reading the pin.
Serial communication depends on interrupts and won't work in an interrupt handler.  Instead, set a flag (via a volatile byte variable) to test in your loop().
For testing, put pwm_on(pwm) in setup() instead of loop().
In loop(), compute seconds = milli()/1000 and if seconds != prevsec, set prevsec=seconds, enable your PCI or external interrupt, then enter a loop that waits for a flag and takes a reading.  Or, in the interrupt handler, both set a flag and take a reading into a volatile variable.
If you only need to measure the quantities a few times per second, or a few times per minute, you could just busy-wait for the condition, then trigger a sample-and-hold, then convert analog to digital via analogRead().

Regarding sample-and-hold: Unless you change the ADC sampling rate, analogRead() will take up to 100 microseconds per reading.  If your input waveform is 62.5 KHz, it will toggle about about six times while being measured, which if measured directly is likely to give a random result.  However, if you use a sample-and-hold circuit, you can hold the ADC input constant until your measurement completes.
An alternative to using a sample-and-hold is changing the ADC sampling speed. See post #5 in thread Faster Analog Read? on forum.arduino.cc.  If you get the sample time down to 8 to 12 microseconds you can do ok with a busy-wait method.  Ie, when your code wants a reading, it has a loop that measures the PWM line over and over, and starts an ADC conversion shortly after the PWM gets to the state desired for the measurement.

1 applies (partly) to standard interrupt handling. The OP is using a library that handles the pinchange events checking the pin values. Your sentence, however, is wrong, since the arduino interrupt handling does not allow for multiple functions in the ISR, so if you attach both rising and falling you won't be able to use the former you attached

The PinChangeInt library checking pin values is one thing that makes it slow; I used it a few months ago but found it too slow, so used ISR()'s instead.  ... At the hardware level, PCI doesn't distinguish rising/falling, merely detects changes. ... I didn't imply "multiple functions in the ISR", but instead reading a pin and branching to one section of the ISR or another depending on its value.  Thanks for the comment!


text:
Serve currently uploaded code from Arduino
I'm creating a project where multiple ESP8266 12-E's are connected together. I want to use ArduinoOTA with the HTTP option (described here) and I want to have one ESP be able to send its code to another. I just need to figure out how to get the currently uploaded code in the form of cpp.bin in the Arduino language from the Arduino, without using an external computer, and then serve it (I can figure out the serving part though). How could I go about this?

see the ESP8266httpUpdate example

I've already seen that example, I just want to figure out a way to get the code uploaded to the ESP from the ESP. Thanks though!

I am not sure what the problem is? use SPIFFS to store the bin

OK, that's a good idea. I can't access the code without storing it though?

you want to clone the program of the esp to other esp?

Exactly, but I can't figure out how to get an ESP's own uploaded code


text:
Set up mesh network with RF Transceivers
I would like to set up a mesh network of Arduinos with the following features/capabilities:

No master node
Arduinos capable of bootloading other Arduinos through RFs
Capable of communicating over TCP/IP
More than 255 possible network addresses

Is this possible, or infeasible? If it is, what are some software packages that meet these requirements. I was looking at RF24Gateway, RF24Mesh, RF24Network, etc., but as far as I can tell these require having a master node, and they only support 255 IP addresses. Is this correct? I was also looking at an Optiboot clone that works with RF24 modules here but it seems like it requires the other Arduino to be connected to a USB.
Any suggestions/clarifications are appreciated. Thanks!

How far have you come in reading about what functionality the NRF24L01 can support (such as addressing, network topology, etc)?

You always can make your own 'protocol' with nRF24L01, you don't have to use the Master/Slave protocol which is built in. These do not work with IP addresses, but they use addressing, not sure how many.


text:
Get IR Signal and its strength
Using an IR sensor, how can I get and decode signals from other IR devices? I've seen the IRRemote library and its forks, but it doesn't fulfill my second requirement which is that I need to be able to tell the signal strength of the IR signal.
In addition, do I have to use a higher-end TSOP module? Or could I just use one of these?
Thank you!

An IR signal is modulated. To understand the data you need to demodulate the signal. The simplest way is with an IR receiver module.  However they condition the signal into a digital signal - it's impossible (on the majority of modules) to get the signal strength.
The devices you link to are IR Photodiodes. They form the optical receiver portion of the IR modules. You need to couple them with some form of demodulating system - either in hardware or, if your MCU is powerful enough, in software.  However, you can get at the raw analog voltages that the photodiode generates to get a signal strength value.
So you have either an easy time of it but no signal strength, or signal strength but a very hard job of interfacing.
So why not take the best bits of both?  Use an IR module to demodulate the signal and give you the data, and next to it use a photodiode and op-amp (to boost the tiny signal) to give you the raw optical intensity?  Yes, it would cost you more, and the circuitry would be more complex, but it's really the only way that you can do it without using specialist modules.
But of course, it begs the question: why do you really want to get this kind of information? Of what use can it be? The "signal strength" is of little benefit since there are so many factors that influence it - incidence angle, distance, transmitter battery voltage, etc.

I want to be able to estimate distance. I was hoping to be able to create something like Pololu's IR Beacon because to buy one is way out of my price range.

Do you think I could build one with 360 degree vision + demodulation for under $5, or is it hopeless ;)?

If all you care about is the distance and there is no data in the signal then yes, you can just shine infra-red light at a photodiode and the generated voltage will be proportional to the distance. It's crude, but works.

But I probably couldn't with a signal?

As in the output of a remote control? Not easily, no.

The pololu beacons doesn’t measure distance. Only direction as far as I can see.

Unmodulated infrared light measured with a simple photodiode would not give you reliable distance measuring dependent in the circumstances. For example if you have too much sunlight, the diode will not make a difference between the suns IR and the beacons IR light. In direct sunlight this also might stop working at all. Under controlled circumstances this might work with a relative low precision (depends also on the noise in your analog signal.


text:
What are these 18 extra ports on the adafruit-gfx 2.8"
I recently got the Adafruit gfx 2.8" display, which works fine.
It's quite obvious that it requires almost all of the pins on the UNO. However, I don't understand what are the 18 avaliable "soldier ports" are at the bottom of the Adafruit shield.
Can these ports be used with sensors, ie: push button, so you wouldn't need to plug anything else into the UNO board? What do these holes do?
I'm unable to find out, as it doesn't seem to be a common shield, most Adafruit shields don't seem to have those ports.
If these ports do nothing, should I saw them off - save space?

Can you provide a link to that exact product? I searched for it on Adafruit and found this one, but it doesn't have these solder points (its PCB is exactly as big as the screen itself). Maybe you have a different product

It somewhat resembles a standard Hitachi parallel port LCD interface.  It has a few more connections.  But that could be for the back light.  I agree w/chrisl, you need to provide a link to the product.  I may be wrong, but I think GFX is a generic term Adafruit uses when referring to their graphics library.

@chrisl I've checked the model on my current one. HX8347 2.8" TFT LCD Shield

the holes are for soldering a pin header so that a ribbon cable can be plugged in

Am I able to remove it, if I don't need to plug in a ribbon cable?

Those are an alternative way of connecting to the screen. Basically they mirror the connections to the "shield" pins.
To save costs the manufacturer will have made a PCB that can be used in multiple different ways just by soldering different connectors. In this case either as an Arduino shield or as a board on the end of a ribbon cable. You have the version with the Arduino shield pins soldered in.
They are of no use to you unless you should want to put the screen on the end of a ribbon cable. Can you remove them? Possibly, possibly not. It depends on how the PCB traces are routed. Cutting the board may cut important PCB traces that connect the screen to the Arduino shield pins.
Only close inspection of the board and understanding the routing of the traces will be able to tell you yes or no. If in doubt, though, no you don't want to be randomly cutting off chunks of the circuit.


text:
Comparison of a bit vs. setting a bit
Simple question really, I just want to be sure that I understand it correctly. I understand this isn't necessarily Arduino specific.
With regards to the ATmega2560 I'm doing 3 back-to-back A/D conversions - one immediately after the previous finishes. I'm accomplishing this by calling a Single Conversion each time.
I stumbled across this useful code to wait for the conversion to finish:
while(ADCSRA & (1<<ADSC))

I understand that it is waiting for the conversion to finish and that when this is done the ADSC will be set to 0. (Conversely, I could wait for ADIF to be set to 1.) I'm not as clear on how exactly this line is interpreted.
Normally when I see something along the lines of (1<<ADSC) it means write a 1 to the ADSC bit.
But, in this instance, that isn't the case.
Why not just write:
while(ADSC);

You misunderstand the meaning of:
1 << ADSC

That actually means Bit-shift 1 left by the number of bits specified by the value ADSC.
ADSC in this case is 6:
#define ADSC    6

So if you did:
while(ADSC);

you would actually be doing:
while(6);

Which of course will never end, since 6 is not 0, so is true.
Instead you shift 1 left 6 times, which in binary would be:
00000001
    << 6
01000000

That, of course, is 64, or 0x40 in hexadecimal.  That is then ANDed with the value of the ADCSRA register to return the value of one single bit within that register.  It's then the result of that AND that you control the while with.  So it ends up as:
while(ADCSRA & 0x40);

Which will either equate to:
while(0x40);

if the 7th bit is set, or if it's not set:
while(0x00);

And since 0x00 is 0 it will equate to false when the bit isn't set and the while will finish.

I should've specified because I think it will make a difference, my apologies, ADSC is a flag in the ADCSRA register.

It is also a #define for a number. In this instance it is the number of the ADSC bit in the register. You use it to manipulate the register - you can't (easily) manipulate the bit by itself.

There is great support for this in the AVR library. Please see http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr.html. This also helps explain the AVR MCU registers and bit field symbols and usage. loop_until_bit_clear(ADCSRA, ADSC);


text:
Transistors to switch monitor inputs
I am using the following setup on my Arduino UNO to measure cpu fan RPMs:

The code is set to bring the trigger pin for each transistor high when it is checking that fan's RPM and FreqMeasure.h is then used to check the frequency of the signal on pin 8 which is then translated to RPM and sent to the LCD display.
I am experiencing reading issues and suspect that the signal is remaining on the measuring bus during the subsequent reads, however before revamping my code I simply wonder:
Is my circuit logic sturdy? I am just getting my feet back under me with microprocessors and have always found transistors to be a tricky subject, thanks in advance for your help!
If you'd like to see more info all can be found on GitHub.

I'm not sure I follow the logic of what your circuit is supposed to do. Why do you need the transistors - why don't you just have each fan's HE output connected to its own input pin with a pullup resistor on each one?

I have setup as such because the FreqMonitor.h library only reads on Pin 8. (edit: for the UNO, it is a different pin on each model iirc)

Ok, that's fair enough then.

I am experiencing reading issues - can you be more specific? What happens compared to what you expected to happen? What does your debugging output tell you?

I have a post about analog multiplexers which may be a simple solution compared to the transistors.

I have simulated your circuit and it seems sound enough to me.
It is a little confusing having the transistors there though.  I would prefer to convert the three open drain outputs to logic level outputs (each having its own pullup resistor) then use a digital 3:1 MUX (or discrete logic gates) to select the signal to sample.

Thanks for your answer! And definite thanks for that simulation! I wasn't aware of this tool, definitely bookmarked. As I'm seeing, my method is essentially a MUX, just without using logic gates.  However a discrete MUX chip will definitely be on my consideration list.

Do you have a datasheet that says the A1301UA has an open drain output? The file A1301-2-Datasheet.pdf says the A1301 outputs are  ratiometric, increasing 2.5 mV per Gauss.  Its working voltage is about 5 V, with abs max 8 V.

The A1301 was just being used as a place holder for an actual open drain output.


text:
Serial.println not outputting
I ran the following really simple code on my micro and the monitor is just blank, not displaying any zeroes or anything and the Tx light isn't lighting up. I haven't used analog inputs much so I don't know what could be causing this. Can anyone help? Thanks, here's the code
int sensePin = 0;
void setup() {
    analogReference(DEFAULT);
    Serial.begin(9600);
}

void loop() {
  Serial.println(analogRead(sensePin));
  delay(500);

}

What board are you using? What IDE version? What operating system?

The arduino micro, on windows 8, IDE version 1.0.5

Genuine micro? OR chinese clone?

Its genuine as far as I know

Have you tried programming the Blink sketch to the board?

Might need a "while (!Serial);" after "Serial.begin(9600);" in setup().

Definitely need that.

The answer to no ouput, and suspecting your data source is to replace the data source with a constant value or a string until you get that problem sorted, and then go back to your data source and debug that if necessary.
That said, I don't see any issue with you trying to print the output of an analog read. Obviously you should get something, even if it's just a single zero on each line, twice a second.

Is your monitor the Arduino built-in monitor?
Is it set to 9600 baud, as you've set your output rate in the program?
Is there anything else connected to the Tx pin, Pin-1 (Arduino numbering, not chip numbering)?
There were no error messages from the compiler or loader, right? (The libraries, bless-'em, always get a few warnings; unfortunately we have to ignore those).
You've no reason to believe the Arduino is other than 100% good?


text:
EEPROM not consistent over reboot
I'am using a Wemos D1 mini V3.0.0 (esp 8266 core).
I tried to save a structure in EEPROM memory but all data are lost when i reboot the board.
I am using these basics functions :
int cle_verif = 519; //verification key

struct sauvegarde_data {
  int cle; //verification key
  int mode_ecl; //var
  int r; //var
  int v; //var
  int b; //var
};
sauvegarde_data customVar;

void sauvegardeEEPROM() {
  EEPROM.put(0, customVar);
  EEPROM.commit();
}

void chargeEEPROM() {
  // Lit la mémoire EEPROM
  EEPROM.get(0, customVar);
  Serial.println("");
  Serial.println("cle : "+String(customVar.cle));
  Serial.println("mode eclairage : "+String(customVar.mode_ecl));
  Serial.println("r : "+String(customVar.r));
  Serial.println("v : "+String(customVar.v));
  Serial.println("b : "+String(customVar.b));
  if(customVar.cle != cle_verif){ // check if the key is correct
    initialiserEEPROM();
  }
}

void initialiserEEPROM(){
  // Valeurs par défaut
  customVar.cle=cle_verif;
  customVar.mode_ecl=0;
  customVar.r=15;
  customVar.v=15;
  customVar.b=15;
  sauvegardeEEPROM();
}

and then, i ran the following code to initialize the EEPROM memory with default values :
EEPROM.begin(128);
initialiserEEPROM(); // initialisation
customVar.b=2; // change cached var value
chargeEEPROM(); // read EEPROM memory

the output is customVar.b=15 which is correct and it means it has been saved in EEPROM.
Any idea ?
Have a great day.
PS: i use four libraries which are FastLed, EEPROM, ESP8266WiFi, ESP8266WebServer.
My goal is to save the LEDs color for a more pertinent reboot.

So, what exactly doesn't work? You wrote, 15 has been stored correctly... please also post your setup and loop code (at least those parts that are relevant)

I don't see EEPROM.begin(). https://arduino-esp8266.readthedocs.io/en/latest/libraries.html#eeprom

Hello, my loop code is not really relevant as it is only server.handle. I then get an argument over a webpage which updates eeprom with sauvegardeEEPROM(); function but that is all

EEPROM.begin was in my setup function i'm sorry :-/ I edited the post so you can see it :-)

The part which is not working in when i reboot the card, all the data i saved are lost.

It turns out i'm just really stupid. I spent something like 7 hours to make things work but i just selected the wrong card during the whole time.
Sorry for bothering you guys :-/


text:
Ardiuno DUE board. Sketch uploading Error
I am working on Arduino UDE board in Ubuntu 18.04. I've followed following link tutorial.
https://www.arduino.cc/en/Guide/ArduinoDue#:~:text=Use%20your%20Arduino%20Due%20on%20the%20Arduino%20Desktop%20IDE,the%20Arduino%20Boards%20Manager%20page.
In Ardiuno IDE I am getting as /dev/ttyS4. Also, I've gone with follwing procedure :
sudo usermod -a -G dialout username
sudo chmod a+rw /dev/ttyS4
ls -l /dev/ttyS4

This gave the following outpit
crw-rw-rw- 1 root dialout 4, 68 Jun 17 17:26 /dev/ttyS4

And I am getting following error while uploading sketch though Ardiuno IDE :
Sketch uses 11092 bytes (2%) of program storage space. Maximum is 524288 bytes.
Forcing reset using 1200bps open/close on port /dev/ttyS4
/home/user/.arduino15/packages/arduino/tools/bossac/1.6.1-arduino/bossac -i -d --port=ttyS4 -U false -e -w -v -b /tmp/arduino_build_718911/ardiuno_to_python.ino.bin -R
Send auto-baud
No device found on ttyS4
An error occurred while uploading the sketch
Set binary mode

I've tried following solution of decreasing baudrate to 1200 by following command line mulitple times till I get output as 1200 :
stty -F /dev/ttyS4 speed 1200 cs8 -cstopb -parenb

Still I am facing the error while uploading sketch. I've tried pressing reset and erase buttons few seconds but still not getting anything. Can anyone please help

The problem is solved. The cable came with my Arduino was charge only , I tried data transfer cable and it worked. This is so dumb. sorry for wasting your time.


text:
Esplora: Connecting a 2-Wire Speaker to Arduino Esplora
I am currently trying to make a simple game system with my Arduino Esplora, however I have noticed something. The Arduino Esplora has no pins for a 2-pin speaker that I get from a RadioShack store (Click here for item description). How would I go about connecting the speaker because I am also using the TFT LCD screen, or is there a workaround with the output TinkerKit pins on the top?
Any help is greatly appreciated. Thanks!


text:
Using an Arduino Weight Sensor, it fails to satisfy a while loop and I can't firgure out why
/*

 This example code uses bogde's excellent library: https://github.com/bogde/HX711
 bogde's library is released under a GNU GENERAL PUBLIC LICENSE

 The HX711 does one thing well: read load cells. The breakout board is compatible with any wheat-stone bridge
 based load cell which should allow a user to measure everything from a few grams to tens of tons.
 Arduino pin 2 -> HX711 CLK
 3 -> DAT
 5V -> VCC
 GND -> GND

 The HX711 board can be powered from 2.7V to 5V so the Arduino 5V power should be fine.

*/

#include "HX711.h"
#include <Servo.h>

float calibration_factor = -4050.0;

#define DOUT  3
#define CLK  2
Servo myServo;

HX711 scale(DOUT, CLK);

void setup() {
    Serial.begin(9600);
    Serial.println("Food Test");
    scale.tare(); //Assuming there is no weight on the scale at start up, reset the scale to 0
    Serial.println("Readings:");
    myServo.attach(9);
    long zero_factor = scale.read_average(); //Get a baseline reading
    Serial.print("Zero factor: "); //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
    Serial.println(zero_factor);
}

void loop() {
    scale.set_scale(calibration_factor); //Adjust to this calibration factor

    if ((scale.get_units(), 1) <= 5) {
        Serial.print("whoa that is light, more food needed");
        myServo.write(90); // Open food hatch
        delay(2000);
        myServo.write(0);

        do {
            // Do nothing
            Serial.println("It is working somewhat");
            Serial.println(scale.get_units(), 1);
            delay(1000);
            // When weight exceeds 5 it should break out of this loop and go below
        } while ((scale.get_units(), 1) < 10);

        Serial.print("Closing the Hatch");
        myServo.write(0); // close food hatch
    } else {
        Serial.print("Something Went Wrong");
    }
}

Output:
It is working somewhat
10.6
It is working somewhat
10.9
It is working somewhat
10.5
It is working somewhat
6.9
It is working somewhat
-0.8

I will try to explain the problem as best as I can. I am using a scale library and the scale.get_units(),x returns a value as a float. The whole point is that a servo will open and stay open until a specified weight of 10lbs is reached. As seen in the do, while loop that's what I specify. It jumps into the if loop and then into the do while loop, and it continually prints out values of readings which is what I want. BUT, even when I reach over 10lbs it will not break out of the Do/while loop, essentially it never satisfies the while condition and I have no clue why. It prints out values over 10 but keeps reading values. I know the format isn't the best but any help would be greatly appreciated!!

It looks to me like you have an extra bracket in there that you don't want.
At the moment your structure is:
if {
    do {
    }
} while...

As it stands your sketch won't compile. The unbalanced brackets prevent it.  Remove the excess one so that the while is associated with the do not the if and report back.

Part II
The main cause of your problem is the strange bit of code you have in your ifs and whiles.
if ((scale.get_units(), 1) <= 5) {

....

} while ((scale.get_units(), 1) < 10);

In both of those you have the bit (scale.get_units(), 1) which is completely meaningless.  The comma operator in C calls (or evaluates) both sides, and then returns the right hand side.  So that calls scale.get_units() and then returns 1.  1 has always been, and will always be, less than 10, so the while never ends.
I don't know what you were hoping to achieve by having the , 1 in there, but you should delete it from every place you have it.

Thank you for that fix, but it still wont break out of the do loop if the weight is greater than 10. Example: It is working somewhat
-0.6
It is working somewhat
13.8
It is working somewhat
-1.0
It is working somewhat
-5.4

Can you fix your sketch and replace your completely broken one with one that compiles? Also make sure you sort out your indentations - that would have immediately shown you the bad brackets.

Better. Now check my edit (Part II)

Well it hasn't fixed everything but it definitely helped me a ton, thank you so much for your help and support, I've been at it for hours but now I can actually breathe. Thank you!!!


text:
reading from an array and writing into a servomotor
I have an Arduino Uno.
I am trying to write a code that reads a command and according to that command it saves angles into an array or writes the angles of the array into a servomotor.
I am facing some problems with my code such as executing the instructions of boucle FOR without ending and other strange things.
#include <Servo.h>

Servo s;
int t[6];
int n, r = 2, b = 4 ;
char c;
String ch = "" ;
int i = 0;
int nb, rep = 0;
int cmd = -1;

void setup() {
    Serial.begin(9600);
    pinMode(r, OUTPUT);
    pinMode(b, OUTPUT);
    digitalWrite(r, LOW);
    digitalWrite(b, LOW);
    s.attach(9);
    t[0] = 0;
    t[1] = 90;
    t[2] = 180 ;
}

void loop() {
    while ((cmd == 0) || (cmd == -1)) {
        cmd = lirecmd();
        delay(20);
    }

    if (cmd == 1) {
        digitalWrite(r, HIGH);
        digitalWrite(b, LOW);

        while (i < 3) {
            while (Serial.available() > 0) {
                c = Serial.read();
                ch.concat(c);
            }

            if (ch != "") {
                nb = ch.toInt();
                t[i] = nb;
                i = i + 1;
                ch = "";
            }
        }
    } else if (cmd == 2) {
        int x;
        cmd = -1;
        digitalWrite(b, HIGH);
        digitalWrite(r, LOW);

        for (i = 0; i < 3; i = i + 1) {
            Serial.print(i);
            x = t[i];
            delay(1000);
            s.write(x);
            delay(1000);
            break;
        }
    } else {
        digitalWrite(r, HIGH);
        digitalWrite(b, HIGH);
    }

    i = 0 ;
    cmd = -1;
    rep = 0;
    digitalWrite(r, LOW);
    digitalWrite(b, LOW);
    delay(50);
}

int lirecmd() {
    if (Serial.available() > 0) {
        n = Serial.read() ;
        n = n - 48 ;
    }

    return n ;
}

Please find a style guide. It will make your code easier to read.

You should rearrange your code.
Global variables, like that
int i = 0;
are not a good idea: it makes the code much harder to read and much easier to make mistakes, by using the wrong variables in the wrong places.
Also, try to break down all those nested loops, create functions with a meaningful description.
That too will help making the variables more local: pass parameters and return values.
As empirical rule of thumb, do not nest more than 1 or 2 times and keep the functions 10-15 lines long.
If you cannot do it, there is probably something wrong in your algorithm.

ok,i will try to do that,thx.


text:
How to convert String to byte array
I have the code, it's purpose is to receive the string from a comport like:
Set@1234567890123456@1234567890123456@1234567890123456@1234567890123456
and translate it into four byte arrays byte user1[16], user2[16], pass1[16], pass2[16]. Here's the code:
String inString = ""; // COM port incoming data buffer

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Start");
}

void loop() {
  // put your main code here, to run repeatedly:
  // Receive data from com port
  while (Serial.available() > 0) {
    int inChar = Serial.read();

    if (inChar != '\n') {
      inString += (char)inChar;
    } else {
      // New line
      String Action = inString.substring(0, 3);
      if (Action == "Set") {
        SetCard(inString);
      } else if (Action == "Get") {
        Serial.println("1");
      } else {
        Serial.println(Action);
      }
      inString = "";
    }
  }
}

void SetCard(String Data) {
  Serial.println(Data);
  // Data Set@user1@user2@pass1@pass2
  // Set@1234567890123456@1234567890123456@1234567890123456@1234567890123456
  byte user1[16], user2[16], pass1[16], pass2[16];

  String user1str = inString.substring(4, 20);
  String user2str = inString.substring(21, 37);
  String pass1str = inString.substring(38, 54);
  String pass2str = inString.substring(55, 71);

  Serial.println("Strings");
  Serial.println(user1str);
  Serial.println(user2str);
  Serial.println(pass1str);
  Serial.println(pass2str);

  Serial.println("Arrays");
  user1str.getBytes(user1, 16);
  user2str.getBytes(user2, 16);
  pass1str.getBytes(pass1, 16);
  pass2str.getBytes(pass2, 16);

  writeByteArray(user1, 16);
  writeByteArray(user2, 16);
  writeByteArray(pass1, 16);
  writeByteArray(pass2, 16);
}

void writeByteArray(byte array[], int arrlength)
{
  for (int j = 0 ; j < arrlength ; j++) //print the block contents
  {
    Serial.write (array[j]);//Serial.write() transmits the ASCII numbers as human readable characters to serial monitor
  }
  Serial.println("");
}

When I run this code and send my string through a com port I expect the output:
Start
Set@1234567890123456@1234567890123456@1234567890123456@1234567890123456
Strings
1234567890123456
1234567890123456
1234567890123456
1234567890123456
Arrays
1234567890123456
1234567890123456
1234567890123456
1234567890123456

And yet, I receive
Start
Set@1234567890123456@1234567890123456@1234567890123456@1234567890123456
Strings
1234567890123456
1234567890123456
1234567890123456
1234567890123456
Arrays
123456789012345
123456789012345
123456789012345
123456789012345

Why? And how do I receive desired output?
getBytes docs

Why? And how do I receive desired output? getBytes docs

The String member function getBytes() will null-terminate the string. You must add space for that.
  byte user1[17], user2[17], pass1[17], pass2[17];
  ...
  user1str.getBytes(user1, sizeof(user1));
  ...
  Serial.print((char*) user1);

That should do the trick.

Thank you. It worked. So, how can I truncate user1[17] array to user1[16] after I set it value with getBytes?

Or do I need to create a buffer array[17] and then write the first 16 elements from there to array[16]?

Come to think of it I could just   for (int j = 0 ; j < sizeof(user1) ; j++)    {     user1[j] = user1str.charAt(j);   } and it would work with 16 elements

Using String.getBytes(buffer, len) to get bytes.
"len" is the length to copy, but usually need to add 1 for the end of string '\0'.
For example:
String s = "123";
int count = s.length();  // lenth() is 3
s.getBytes(buffer, count);   // copied "12\0" => HEX(31 32 00)
s.getBytes(buffer, count + 1);   // copied "123\0" => HEX(31 32 33 00)

The official document not mentioned those above, and it's not reasonable for the modern function design.
Misunderstanding in that and waste our life so much.

toCharArray() is documented https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/tochararray

toCharArray(buffer, len) will still keep the last bye for 0x00 ('\0'). So if want to copy the specific length of the content, len should add 1 for '0'. Also, care the buffer length as the last damn byte.

that is what is expected for char-array (C string) (but not expected for getBytes)

If the official document has mentioned the '\0' in details, it's fine for purpose. It's pity for none.

I am heaving difficulties reading your post and comments. How do you declare buffer?


text:
How do I correctly use enum within a class?
I am trying to set the status of an object from a private enum and I'm not sure how to get the private member to the public version in the constructor, and I'm pretty sure I should not be using byte in the constructor when it's an enum.
Also, I'm not sure if I should even have the values of the enum inside the header at all. Here is my code:
.h
class CandleRack
{
  public:

    CandleRack(byte candleRackStatus);
    ~CandleRack();
    void begin();
    void pushButton();
    void selectRandomCandle();
    void turnOnCandle(byte candlePosition);
    void burnCandlesForMs();
    void fadeOutCandle(byte candlePosition);

  private:
    Bounce *_debouncePushButton;
    byte _pushButtonPin;
    enum _candleRackStatus
    {
      inactive = 0,
      candlesOn = 1,
      rewardAnimation = 2,
      tweetArrived = 3,
      partyMode = 4,
    };
    byte _candlePosition;
    byte _candleStatus[NUM_LEDS];
    elapsedMillis _candleTimeElapsed[NUM_LEDS];
    unsigned int _candleOnForMs;
};

.cpp
CandleRack::CandleRack(byte candleRackStatus)
{
  _candleRackStatus = candleRackStatus;
  _debouncePushButton = NULL;
}

in the sketch
CandleRack MyCandleRack(0);

error:
error: expected unqualified-id before '=' token
_candleRackStatus = candleRackStatus;

Thanks!

Might be more of a programming question as an Arduino question. I've heard that ENUM's are specifically useful when dealing with switch-case statements, since you can define a "default" case.

You can define a 'default' case on a switch statement without needing an enum, but for me it will help the code be more usable as you can give each case a name and not just a number.

SHouldn't CandleRack MyCandleRack(0); be CandleRack MyCandleRack(inactive); or maybe CandleRack::inactive. My C++ is a bit rusty (very rusty). Also, in the interests of program readability the enum would be useful outside the class otherwise you're just assigning a bunch of numbers.

The enum gives the object its properties so my logic tells me it should be a part of the class, it's also a private member so it's properties are hidden from all of the other classes I will be adding. You're right about MyCandleRack(inactive); though.

Hmm, you're true on the default thing. But I can vaguely remember my prof being "mad" at me for using defines instead of enums, since your compiler could check if all enums are handled in your switch-case.

I see two separate issues here.
First of all your enum isn't available as a variable.
By declaring it as a private type within your class the enum can't be used outside of that class.
This forces a user of that class to handle unintended calls like (attention, bug):
CandleRack(255);

which can make code harder to read (and debugging more difficult, since it wouldn't be detected by the compiler).
Second of all you try to directly assign a byte value to an enum type. This will be rejected by the compiler and/or cause runtime errors later (depending on compiler settings).
I recommend that you declare the enum type so that it is accessible directly via the header file:
.h
enum CandleRackStatus {
    inactive = 0,
    candlesOn = 1,
    rewardAnimation = 2,
    tweetArrived = 3,
    partyMode = 4,
};

class CandleRack
{
  public:

    CandleRack(CandleRackStatus candleRackStatus);
    ~CandleRack();
    void begin();
    void pushButton();
    void selectRandomCandle();
    void turnOnCandle(byte candlePosition);
    void burnCandlesForMs();
    void fadeOutCandle(byte candlePosition);

  private:
    Bounce *_debouncePushButton;
    CandleRackStatus _candleRackStatus;
    byte _pushButtonPin;
    byte _candlePosition;
    byte _candleStatus[NUM_LEDS];
    elapsedMillis _candleTimeElapsed[NUM_LEDS];
    unsigned int _candleOnForMs;
};

Now you can instantiate your class while using the correct enum type as the parameter.
.ino
CandleRack MyCandleRack(CandleRackStatus::inactive);

Within your implementation you can now directly store the constructor parameter in the private variable, the compiler will make sure it's always of the correct enum type:
.cpp
CandleRack::CandleRack(CandleRackStatus candleRackStatus) {
    _candleRackStatus = candleRackStatus;
    // rest of your initialisiation goes here
}

As an added bonus, there's the possibility to use a couple of C++ language features that will make your implementation easier:

a default parameter value
an initializer (list)

.h
class
{
  public:
    CandleRack(CandleRackStatus candleRackStatus = CandleRackStatus::inactive);
    // [...]
}

.cpp
CandleRack::CandleRack(CandleRackStatus candleRackStatus) : _candleRackStatus(candleRackStatus) {
    // rest of your initializiation goes here
}

One thing I don't understand is why you have Capitalized the name CandleRackStatus. I thought an enum was just a variable and nothing like a class or struct. I think it's confusing to treat it like a class (with naming conventions) ...

last question, when I actually want to change the status of the CandleRack, do I do _candleRackStatus = candlesOn ?

Re: Capitalized, that's a matter of taste and what school of programming you come from. I recommend treating enums like types, because they are. And in most C++ styles types get a capitalized name. See https://google.github.io/styleguide/cppguide.html#Enumerator_Names for reference, also a good read as a whole.

Re: changing the status, the identifier candlesOn is defined within the type declaration of the enum. So in order to access it you would qualify it with the type name: CandleRackStatus::candlesOn. That's called static access and the :: operator works on all type properties that are public and static (see http://stackoverflow.com/questions/10090949/accessing-to-enum-values-by-in-c). So you would change the status using _candleRackStatus = CandleRackStatus::candlesOn.

We've discussed simplification of names before, so if these expressions are too lengthy or confusing, just choose shorter names for types and variables.

How about this refactoring?
class CandleRack
{
  public:
    enum status_t
    {
      inactive = 0,
      candlesOn = 1,
      rewardAnimation = 2,
      tweetArrived = 3,
      partyMode = 4,
    };
    CandleRack(status_t status = inactive);
    ~CandleRack();
    void begin();
    void pushButton();
    void selectRandomCandle();
    void turnOnCandle(byte candlePosition);
    void burnCandlesForMs();
    void fadeOutCandle(byte candlePosition);

  private:
    Bounce *_debouncePushButton;
    byte _pushButtonPin;
    status_t _candleRackStatus;
    byte _candlePosition;
    byte _candleStatus[NUM_LEDS];
    elapsedMillis _candleTimeElapsed[NUM_LEDS];
    unsigned int _candleOnForMs;
};

And in a sketch with either the default setting (inactive)
CandleRack MyCandleRack;

or explicit
CandleRack MyCandleRack(CandleRack::candlesOn);

Cheers!

It seems this answer compiles the gist of my answer into a code-only post (see e.g. http://meta.stackexchange.com/questions/148272/is-there-any-benefit-to-allowing-code-only-answers-while-blocking-code-only-ques)

Yes It does a bit. If you could add some of these suggestions to your post I think that would make it a great answer. Especially as this shows how I could use the enum as a public member and not outside of the class - which in my mind, makes it more understandable.

But also thanks to Mikael for this post too, it also helps my understanding of how to use enums.

In this example where is status coming from? status_t status = inactive

status is an alternative naming to your candleRackStatus. Simpler names can increase readability. Since you only pass one parameter, you don't really need to qualify it in more detail than neccessary, so it's probably a good idea to simplify. :) I've updated my answer to explain the use of the enum type and a default parameter value.

Hmm, I find descriptive names more readable and other elements of my sketch will also have a status (even of this object - music status, animation status etc) so I think it's important for me not to rename. I'm also unsure of where status_t comes from, what is the _t ?


text:
What's wrong with my Arduino board?
When I connect the Arduino to my PC the Led "ON" lights for a second then turns OFF. I wonder if the Arduino has a fault?

Most likely a short between VCC (5 volt) and GROUND. When there is a short the fuse will kick in after a second, and disable the whole board, including the ON-led.
When you disconnect the board, the fuse will reset.
So either the board is faulty of the connection you made to it are.

thx for the explaination,and help.


text:
'Simple' problem. Delay not working?
Servo goes to one end, and immediately travels back without a 2s delay inbetween. After it travels back there is a 2s delay before it loops. Why isn't there a 2s delay before the travel back?
Servo testservo;

void setup() {
    testservo.attach(9);
}

void loop() {
    testservo.writeMicroseconds(700);
    delay(2000);
    testservo.writeMicroseconds(2300);
    delay(2000);
}

Because you have a slow servo that takes two seconds to go from one end to the other?  Try with a longer delay.

If that were true, I don't see why i'd be observing the servo 'stop' for 2s after the second position. I've tried longer delays. The effect is the same.

Your description (“Servo goes to one end, and immediately travels back without a 2s delay... After it travels back there is a 2s delay before it loops”) implies an overall cycle time of 2 seconds, which appears to be inconsistent with the overall 4-second cycle implied by the code shown.
Here are things you can do to debug the problem:

Turn on an LED before one writeMicroseconds() call, and turn it off before the other.  For example, add pinMode(13, OUTPUT); in setup(), and revise loop() as follows:

void loop() {
    testservo.writeMicroseconds(700);
    digitalWrite(13, HIGH);
    delay(2000);
    testservo.writeMicroseconds(2300);
    digitalWrite(13, LOW);
    delay(2000);
}
This may allow you to find out which end the servo is going to.

Besides adding LED signals, try slightly-less extreme times in the writeMicroseconds() calls; eg 1000 and 2000 microseconds rather than 700 and 2300.
See if a neutral servo setting works, eg via code like the following.

enum { LEDpin=13, dtime=2000}
void stest(angletime, tHi, tLo) {
    testservo.writeMicroseconds(angletime);
    digitalWrite(LEDpin, HIGH);
    delay(tHi);
    digitalWrite(LEDpin, LOW);
    delay(tLo);
}
void loop() {
    stest(1000, dtime-50, 50); // Go CCW
    stest(1500, 50, dtime-50); // Middle
    stest(2000, 50, dtime-50); // Go CW
}

When this code runs, the LED should stay on about 2 seconds with the servo fully (or nearly so) counterclockwise.  Then the LED should blip and the servo should move to center position and stay there about 2 seconds.  Then the LED should blip and the servo should stay fully clockwise about 2 seconds.  This three-part cycle should repeat every six seconds.  If it works ok, then try modifying it, eg by changing 1000 us to 700, 2000 to 2300, etc, or by decreasing the dtime value to see how quickly the servo can respond, etc.

Something rather odd's that when i apply resistance to the servo with my fingers in the opposite direction of where it wants to go, the timing and all is fixed and it goes to every position as programmed. I'm clueless. Could the servo have a problem or something?

I just tried using another servo and everything's fine. What's wrong with the other servo? Am I able to fix it? :-(

I just tried powering my board not through my avr pocket programmer... Everything works fine now. Why is this so?

Insufficient power to the servo when powered like it was.


text:
connected between 2 arduino
i want to connect  SPI 2 arduino master and slave through the MUX , to write  and read in external memory , when the master write in memory slave read .
pls help .
code to master
#include <SPI.h>
//-------FM------------------
#define WENB 0x06
#define RDSR 0x05
#define WRSR 0x01
#define PPROGRAM 0x02
#define SERASE 0x20
#define BERASE 0xd8
#define READ 0x03
#define RDSCUR 0x2B
#define CERASE 0x60//or 0xC7

//------------Specify the address-----------
int address = 0x00ff0000;
byte x, Y;
int IN = 5;
int SS1 = 9;
/*char data[]=("don't be afraid ");
char recived[15];*/
//--------------------------
void setup() {
    //------------------------------------------
    // pinMode(EN,OUTPUT);
    pinMode ( SS, OUTPUT ); //ss pin 10
    pinMode ( SS1, OUTPUT );
    digitalWrite ( SS1, HIGH );
    pinMode ( IN, OUTPUT );
    digitalWrite ( IN, LOW ); // MUX connect A
    //digitalWrite(CS,low);
    Serial.begin ( 9600 );
    SPI.begin();//start the SPI connection with the flash memory
    SPI.setClockDivider ( SPI_CLOCK_DIV8 );
    SPI.setBitOrder ( MSBFIRST );
    digitalWrite ( SS, HIGH );
    delay ( 10 );
    //-------erase the sector--//-----------
    digitalWrite ( SS, LOW );
    SPI.transfer ( WENB );
    digitalWrite ( SS, HIGH );
    //-------------------------------------
    digitalWrite ( SS, LOW );
    SPI.transfer ( SERASE );
    SPI.transfer ( ( address >> 32 ) & 0xff );
    SPI.transfer ( ( address >> 16 ) & 0xff );
    SPI.transfer ( ( address >> 8 ) & 0xff );
    SPI.transfer ( address & 0xff );
    digitalWrite ( SS, HIGH );
    delay ( 5000 );
    //------------------------------------------
    //Serial.println("okay fine")
    //-----Program Data Into Memory Array-----.
    //-----------interrupts the slave----------
    /* digitalWrite(SS1,LOW);
     SPI.transfer(0xff);//are you there?
     digitalWrite(SS1,HIGH);
     delay(1000);

     digitalWrite(IN,HIGH);*/
}

void loop()

{
    char c;
    int i = 0;
    char data[] = "Hello!:";
    char recived[7];
    byte x;
    //----------Enable the write in the memory-----.
    digitalWrite ( SS, LOW );
    SPI.transfer ( WENB );
    digitalWrite ( SS, HIGH );
    delay ( 20 );
    //-----Program Data Into Memory Array-----.
    digitalWrite ( SS, LOW );
    SPI.transfer ( PPROGRAM );
    SPI.transfer ( ( address >> 32 ) & 0xff );
    SPI.transfer ( ( address >> 16 ) & 0xff );
    SPI.transfer ( ( address >> 8 ) & 0xff );
    SPI.transfer ( address & 0xff );

    for ( int i = 0; i < sizeof ( data ); i++ ) {
        SPI.transfer ( data[i] );
        // Serial.print(data[i]);
    }

    // disable Slave Select
    digitalWrite ( SS, HIGH );
    //--------------------------------------------
    delay ( 1000 );
    //--------------------------- ----------
    i = 0;
    Serial.print ( "It's okay saved: " );

    while ( data[i] != NULL ) {
        Serial.println ( data[i] );
        i++;
    }

    // delay(100);
    //-----------interrupts the slave----------
    digitalWrite ( SS1, LOW );
    SPI.transfer ( 0xff ); //are you there?
    digitalWrite ( SS1, HIGH );
    delay ( 1000 );
    digitalWrite ( IN, HIGH ); // MUX connect B
}

code to slave
#include <SPI.h>
//-------FM------------------
#define WENB 0x06
#define RDSR 0x05
#define WRSR 0x01
#define PPROGRAM 0x02
#define SERASE 0x20
#define BERASE 0xd8
#define READ 0x03
#define RDSCUR 0x2B
#define CERASE 0x60//or 0xC7

//------------Specify the address-------------
int address = 0x00ff0000;

int SS1 = 9;
char data[] = "Hello!:";
char buff[7];

byte slave;
volatile bool process;
//----------------config slave----------------
void setup() {
    //pinMode(IN,OUTPUT);
    pinMode ( SS, OUTPUT ); //SS pin 10
    pinMode ( MISO, OUTPUT );
    pinMode ( SS1, INPUT );
    pinMode ( MOSI, INPUT );
    //--------------------------------------------------
    Serial.begin ( 9600 );
    ///SPCR |= bit (SPE);
    SPI.begin();//start the SPI connection with the flash memory
    SPI.setClockDivider ( SPI_CLOCK_DIV8 );
    SPI.setBitOrder ( MSBFIRST );
    // digitalWrite(SS,HIGH);
    //-------------master interrupts the slave----------------------------------------------
    // now turn on interrupts
    // SPCR |=bit(SPIE);
    //SPCR |=bit(SPE); //set SPE bit at the SPCR(spi control register) to enable SPI
    SPI.attachInterrupt();
}

ISR ( SPI_STC_vect ) {
    slave = SPDR;

    if ( slave = 0xff ) {
        pinMode ( MISO, INPUT );
        // pinMode(SS1,INPUT);
        pinMode ( MOSI, OUTPUT );
        //digitalWrite(IN,HIGH);
        digitalWrite ( SS, LOW );
        SPI.transfer ( READ );
        SPI.transfer ( ( address >> 32 ) & 0xff );
        SPI.transfer ( ( address >> 16 ) & 0xff );
        SPI.transfer ( ( address >> 8 ) & 0xff );
        SPI.transfer ( address & 0xff );

        for ( int n = 0; n < sizeof ( data ); n++ ) {
            data[n] = SPI.transfer ( 0 );
            Serial.print ( data[n] );
        }

        digitalWrite ( SS, HIGH );
    }
}

You mean you want one Arduino to be able to access the memory of another over SPI? If so, what part are you having problems with? You have told us what you want to do, and you have dumped code on us, but you haven't told us what is actually happening (or not happening) and what you need help with.

I'm afraid you have to clarify your question. Do you mean you want to connect two Arduinos to on external memory? And one Arduino drives a MUX to decide which Arduino is allowed to access the ext. memory? Which MUX do you use? How do you plan to negotiate which Arduino can have access to the memory? Wouldn't it be a better idea to let one Arduino access the memory and the other sends its data to that "master" Arduino?

what my want to do! okay , i have 2 arduino , i program one to be master to control in my project and write in external memory , and anther to be slave and read from external memory , through MUX   to which who can connect with memory , and i control in MUX by  the master. my problem  the slave can't know when exactly read from memory . I used MUX ADG774 and the type of memory MX25L25735E. you can see my code . I hope now be clear

Then you need to have some form of communication between the two Arduinos so that the master can tell the slave when it's allowed to read from the external memory. And in that case you may as well just forget sharing the memory and just use that connection to send data from one Arduino to the other.

The master and slave connected by interrupt  command . what do you think ?

As far as I understand it, SPI library in Arduino supports SPI Master mode only. When you call SPI.begin() in your slave code, it "initializes the SPI bus by setting SCK, MOSI, and SS to outputs, pulling SCK and MOSI low, and SS high". So your pinMode(MOSI, INPUT); is override. Read the source code for better understanding of the library.

Not true - Arduino can be SPI slave also.  Nick Gammon has example here  https://www.gammon.com.au/spi  In this case tho, "slave" only indicate another user of the memory.

May be you right-   ("slave" only indicate another user of the memory ) but here I used MUX to control in slave. okay may be I don't need to MUX if I have 2 arduino . But now I want to use the MUX .another way?

Having a line from Arduino 1 to Arduino 2 to indicate that Arduino 2 should do something is sufficient.
Simple way: a line that is an input on both sides with internal pullups turned on.  Both sides monitor it.
When Arduino 1 wants to write, it checks to make sure the line is high, then it makes its pin an output and pulls it low, and when done releases it by going back to an input (using pinMode() command).
When Arduino 2 see the low, it waits for it to go high, then makes its input and output and pulls it low until it is done reading.
Arduino 1 sees the low and holds off on any writing until it goes back high again.
This is known as arbitration, and is an example of one simple method.

okay-  when or how can arduino 2 know arduino 1 finished write ?

Arduino 1 puts the common pin back to an input, which lets it go High.


text:
Adafruit Feather 32u4 FONA KEY Pin
I received a Adafruit Feather 32u4 FONA as a gift and have read the great, comprehensive document Adafruit put have put together surrounding pinouts, examples etc for the board. I am having issue understanding the section on the KEY pin, I understand that it is used to put the cellular module to sleep, but in order to do this it is mentioned to “cut the trace and wire it to a micro controller pin”. Does this mean that in order to utilize the on/off functionality of the SIM module I have to slightly butcher my new shiny board instead of using the pin directly?

When you have to cut a track there is normally an exposed area between two pads, clearly marked as the bit of track to cut.  You are right with what it means, because doing this saves the manufacturer the few cents adding a jumper would have cost :)

Yes, you will need to physically cut the trace to use the on/off feature. This is common on development boards. It could be done with a jumper but that would add cost and/or require a larger board.
You will see on the back of the board there are 2 large pads connected by a thin trace. You can use an exacto knife to cut the trace. To repair the cut you use a blob of solder to bridge the gap between the pads.


text:
3.3V from 5.0v outlet
I am working with an Adafruit Feather 32u4 FONA board. I want to connect a GPS module I have worked with before (3.3V required) but am not having much luck. I have studied the pinout of the board and have tried the 3.3V pin but it is far too erratic in nature and cannot sufficiently power the module. There is a pin called USB which supplies 5.0V from the pin if a micro USB cable is connected. I have used an LM317 and a potentiometer to make a voltage regulator circuit to convert the 5.0V from the USB pin to the 3.3V I need for the GPS module. This works, as I have measured 3.3V successfully using a multimeter.
The problem is that when I connect the VCC and GND pins of the GPS module to the 3.3V regulated output, the module still doesn't get any power. I measured a significant drop to around 0.89V across GND and VCC after I connect the module. What could be causing this strange behavior?

The bottom left rail is what I am trying to use to power the GPS module, before I connect it I get 3.3V as mentioned earlier, which is the required level.

I don't get what you think that circuit is trying to do. It looks to me like you are just using the LM317 as an expensive diode, and the trimmer pot as a voltage divider. It can never work. If you want to use an LM317 then please, wire it up properly. And never ever ever use a potentiometer to try and drop a voltage for supply.

Ok, well what approach would you yourself take @Majenko ?

I'd probably get a cheap adjustable switching ("Buck") regulator off eBay and use that.

The LM317 also requires some capacitors.

@Majenko, I have one of those, am I able to feed 5V in and trim it to around 3.3V?

I will give it a go

A while has passed since I asked this question but in a bid to resolve it, I used my Buck regulator as suggested and this solved the problem.

According to the datasheet the LM317 has a minimum Vin to Vout of 3v so you'd only be able to get 2v out of it if you put 5v in.  I'd recommend using either an AMS1117 3.3 or one of the cheap modules based on that chip that has an LED and capacitors on board. They definitely deliver 3.3v from 5v in.