text:
Interrupt on button press + debouncing
I want to have an interrupt function executed whenever a button is pressed.
The button is connected to pin 2 and the GND. Therefore, the pin is turned to LOW whenever the button is pressed. In addition to that, proper debouncing should be used
As a proof of concept, the interrupt function should just toggle the BUILTIN_LED whenever the button is pressed.
I have tried many different approaches but i cannot make it work.
This is my last iteration:
bool led_status = LOW; // current state of output pin
int buttonState; // the current reading from the input pin
int lastButtonState = HIGH;  //the previous reading from the input pin

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

int button_switch = 2; // external interrupt pin
bool initialisation_complete = false; // inhibit any interrupts until initialisation is complete

// ISR for handling interrupt triggers arising from associated button switch
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited long enough
// since the last press to ignore any noise:
void button_interrupt_handler()
{
  //static long int elapse_timer;

  if (initialisation_complete == true) //only able to run the ISR when arduino has finished initialization
  {
    // new interrupt so okay start a new button read process -
    // now need to wait for button release plus debounce period to elapse
    // this will be done in the button_read function

    int reading = digitalRead(button_switch);
    if ( reading != lastButtonState) // If the switch changed, due to noise or pressing:
    {
      lastDebounceTime = millis(); // reset the debouncing timer
    }

    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:
    if ( (millis() - lastDebounceTime) > debounceDelay)
    {
      if (reading != buttonState) // if the button state has changed:
      {
        buttonState = reading;
        if (buttonState == HIGH) // only toggle the LED if the new button state is HIGH
        {
          led_status = !led_status;
        }
      }
    }
    digitalWrite(LED_BUILTIN, led_status); //set the LED
    lastButtonState = reading; // save the reading. Next time through the loop, it'll be the lastButtonState:
  }
} // end of button_interrupt_handler

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(button_switch, INPUT_PULLUP); //no res = change to INPUT_PULLUP
  attachInterrupt(digitalPinToInterrupt(button_switch), button_interrupt_handler, FALLING); //no res = change to FALLING
  digitalWrite(LED_BUILTIN, led_status);
  initialisation_complete = true; // open interrupt processing for business
}

void loop()
{
  //do nothing
}

I am not sure what I am doing wrong or why this does not work.
EDIT: When I press the button, nothing happens at all.

I'd probably take a simpler approach. If the ISR is triggered, accept that and toggle the led then set a timer, as you have already done (lastDebounceTime). Use the timer to prevent subsequent calls of the ISR having any effect. When the timer expires (after 50ms) the ISR again behaves normally. An interrupt is, however, not usually the best way for handling a button and simply polling it every X ms is usually enough.

@jsotola Thanks! You are right, I edited the question.

Here is a non-blocking debouncing solution which is suitable also for electrically noisy environments. For example where there are long wires to the buttons which could pick up spurious signals. In this case, you cannot rely on short pulses being the direct result of button activity and must check that the button state has been stable for X ms before accepting it. It also handles potential bounces on the release of the button. It uses a simple finite state machine approach and does not use interrupts.
It can be tried also in a simulator: https://wokwi.com/projects/351021820324872788

const uint8_t ledPin = 13 ;
const uint8_t button_switch = 2;  // the button is wired between this pin and ground (LOW side)
const unsigned long debounceDelay = 100 ;    // the debounce time; increase if the output flickers

enum ButtonState  { PENDING_PRESS, IN_PRESS, PENDING_RELEASE} ;
ButtonState buttonState = ButtonState::PENDING_PRESS ;
uint32_t stateEnteredAtMs = millis() ;

void setup() {
  Serial.begin(115200);
  pinMode( ledPin, OUTPUT) ;
  pinMode( button_switch, INPUT_PULLUP) ;

}

void loop() {
  uint32_t ms = millis() ;
  static uint32_t lastButtonCheckAtMs = 0 ;

  if( ms - lastButtonCheckAtMs > 10 ) {

    switch ( buttonState ) {

     case ButtonState::PENDING_PRESS : {
        if ( digitalRead(button_switch)  == LOW ) {
          buttonState = ButtonState::IN_PRESS ;
          stateEnteredAtMs = ms ;
        }
        break ;
     }

     case ButtonState::IN_PRESS : {
        if ( digitalRead(button_switch) == HIGH )  {
          if ( ms - stateEnteredAtMs < debounceDelay ) {
            stateEnteredAtMs = ms ;
            buttonState = ButtonState::PENDING_PRESS ;
          }
          else {
            stateEnteredAtMs = ms ;
            buttonState = ButtonState::PENDING_RELEASE ;
            digitalWrite( ledPin, ! digitalRead(ledPin)) ;  // toggle led
          }
        }
        break ;
     }

     case ButtonState::PENDING_RELEASE : {
        if ( ms - stateEnteredAtMs > debounceDelay ) {
            stateEnteredAtMs = ms ;
            buttonState = ButtonState::PENDING_PRESS ;
          }
        break ;
     }
    }
    lastButtonCheckAtMs = ms ;
  }
}

Thank you! Does this code work for when the button press leads to LOW (this means no resistance), or when the button press leads to HIGH (this means button and resistor)?

@user1584421 The button is wired between Ground and the arduino pin. This means that when the button is pressed it is seen as LOW by digitalRead(). I added a link to a simulator. There it should also be clear how it is wired. I hope I've made that understandable.

Thank you. I hadn't clicked that link before. There is a weird behaviour when the button is pressed two times simultaneously. It doesn't register as two clicks. There has to be some time passed, until the second click can be registered. Also, can I take the loop() code and just place it in an external interrupt? I would like this to be inside an interrupt function.

@user1584421 That is not weird behaviour, that is filtering out potential bounces, You can adjust the parameter debounceDelay in the sketch. You can't run that sketch in an ISR because you can't hold up an ISR waiting for events like button release etc. However, if you want a ISR based solution, try here in the simulator: https://wokwi.com/projects/351221603927851607

Hmmm.. Thanks, but can you imagine how a can perform a button press inside an ISR? It does not matter if the button is connected to resistor or not (pin HIGH/LOW).

@user1584421 Try the code here https://wokwi.com/projects/351221603927851607 and say in what way it fails to meet your requirements. The button press forces an entry into the ISR. Once inside the ISR it cannot wait for more button activity. However, it  ensures that it is unaffected by bounces by locking out unwanted button pulses for a configurable period of milliseconds following the initial detection of a button press.

Thank you! I tried the code in real hardware, and wherever i press the button, the LED flashed briefly and then it turns off. It does not stay ON/OFF. Actually, the LED was just an experiment, in my practical application i want to build a state machine. Perhaps switch through states of an ENUM. One more observation i have to note has to do with this line last_entryAtMs = millis() ; The variable last_entryAtMs is static. Shouldn't there be an overflow protection in there as well?

Well the overflow point is not valid, since it is initialized at zero at every interrupt call. Unfortunately, i cannot edit the comment now.

@user1584421 The simulator runs slower than real time so some of the timings may have to be increased for usability, for example: debounceDelay = 300 ; . Static variables are initialised once only, NOT on each pass. An unsigned integer simply rolls over on overflow. millis() rolls over every approx. 50 days so there should be no big problem here.

Thank you so much! It worked! However, it is possible that my creation will be up for many many days. Therefore, it is essential that an overflow has to be taken care of. Where or how exactly should that happen?

In almost any run of the ISR it will read the button state as LOW, because the ISR is triggered by the falling edge. The time from the falling edge to the reading is very short, about microseconds, and therefore a level change is improbable.
As others already suggest, you can make the ISR "deaf" for some time after the accepted falling edge. You can do this inside the ISR. The approach is to accept subsequent triggers only if they are long enough after the former one.
Please be aware that some buttons bounce even when released. You might experience a trigger in such cases.
Anyway, do not base a decision on the reading of button state after its falling edge.

The most simple solution to read buttons is a cyclic timer with a period of several milliseconds. Take a sample each 50ms or so, and detect the button change in software. You don't even need to add debouncing code, if the period is longer than the bouncing time of your button.
Since this timer will commonly trigger an ISR, you have already an interrupt as source of the button state for other parts of your software.
If you want an extra interrupt, trigger some unused interrupt in software.

Thanks. If i don't base the reading of a button after its fallig edge, this means i have to use a resistor? Or i can achieve this without one?

No, of course you need defined levels at the input. With a simple SPST button you need a resistor. How else would the digital logic detect the falling edge? However, you can use an internal resistor, if the device provides one.

Take a look at this line in your code - the very first thing that is done in the ISR,
int reading = digitalRead(button_switch);
I think that the reason that your program does not “do anything” is because you are reading the button state inside the ISR and, because you trigger an interrupt on a falling edge, you will ALWAYS see 0 as the button state at that point. It can never change when you read it once at the beginning of the ISR, it will always =0, unless you stay in the ISR and wait for a change, which is a very, very, bad idea.
The rest of your comparisons and detections all fail because within the ISR, the button read is always going to be the same and = 0, because that is how you got to the ISR. As far as your program is concerned, the button has never been pressed or depressed.
It is true, depending on how you configure the button; a single state change will be detected because of initialization, but that is besides the point.
You can test this yourself by moving all of your variables to volatile globals and then in your loop run this:
void loop()
{
Serial.print("lastButtonState ");
Serial.println(lastButtonState);
Serial.print("buttonState ");
Serial.println(buttonState);
Serial.print("reading ");
Serial.println(reading);
}

You may have other problems, but that one stuck out to me.
I would suggest that you take a look at this project and see how he is doing it - https://create.arduino.cc/projecthub/ronbentley1/button-switch-using-an-external-interrupt-7879df
He does read the switch within the interrupt [I don't see why he needs to test the value since in his case it will always be HIGH]. The difference is that he uses the ISR only as a trigger. The rest of the reading of the switch to detect when there are state changes, is all done outside of the ISR.
Additionally, once an interrupt occurs, a triggered status is set and, thereafter the ISR just leaves until the status is changed to "not triggered" and that is done outside of the ISR. The accompanying article explains what he is doing in the code and why.
You are doing, literally nothing [after setup()] outside of the ISR and I think maybe you should re-think that approach.
I tested his program and it works fine. I note that he functionally defines a "press" as pressing and releasing the button (with associated debouncing). So, you don't see the led toggle until you press and release the button. That's not always how I would like it, but it is also besides the point.
Two other points...
Keep your ISR as short as you can. I don't have any hard core evidence, but, right or wrong, yours looks longer than I would be comfortable with.
Finally, I think you would enjoy this excellent thread on millis() inside an ISR. Using millis() and micros() inside an interrupt routine
To be sure, you are NOT using delays inside an ISR and there is nothing wrong with using millis() inside an ISR, but you need to be aware of the behavior.
That's my two cents - hope it helps.


text:
Cannot read LED state
I am running into a problem on a very basic functionality.
I want to read the state of an LED.
I have confirmed that under the specified circumstances, the LED receives 1.9V.
I try to read its state with this code:
#define LED_1  5

void setup()
{
pinMode(LED_1, INPUT);
}

void loop()
{
 int led_state = 0;
 if ( digitalRead(LED_1) ) led_state = 1;
 Serial.println("LED State is: ");
 Serial.println(led_state);
}

However, most of the time, the led_state is 0. Sometimes, it goes to 1, but then quickly goes back to 0.
Is it because the voltage is low?
EDIT: I am hooking power directly to one pin of the LED, and the other pin goes to GND (from the same DC power supply).
Also, the power pin from the LED enters inside Arduino Digital Pin 5.

What LED button do you have? How is it wired? What Arduino are you using?

If it's wired how I think it is the analogRead would be better for it. Or internal analog comparator module (depends on MCU, there might not be library for it) or external OpAmp/comparator

@chrisl Sorry it was not a button. I made a typo in the question, it is corrected now. Just a standard LED. I am using arduino uno.

@KIIV Thanks! Can I do analogRead(), on Arduino Digital Pin 5? I am on Arduino Uno.

No, you'll have to wire it into some analog pin. And then you'll have to compare the value with some threshold (basically making software comparator)

@KIIV Since the voltage is 2V DC in, why can't this be "read" by a digital channel?

Read about 5V CMOS Logic levels for the answer (UNO uses 5V). For example here: https://learn.sparkfun.com/tutorials/logic-levels/all

Can you please provide a diagram of how the LED is wired. It sounds like you don't have a current limiting resistor in series with your LED.

@sa_leinad You are right, I just hooked it up to a DC voltage generator... I found the solution though.

@KIIV I did it with analogRead(). If you want, you can post a proper answer so I can mark it as the selected one. One key point though. The GND of the arduino and the power supply had to be connected, otherwise, the reading was random.

I also have to note that I was able to read the LED state in the past, using DigitalRead. However, the operating voltage of the arduino was 3.3V. Thus, it could read voltages of 1.9V. When the operating voltage of the arduino was 5V, it was unable to measure the 1.9V Voltage with digitalRead.

For the CMOS logic the treshold is usually 1/2 Vcc, therefore you might get lucky with arduino 3.3V Arduinos, but it's still in undefined area. That usual threshold can also change with operating temperature (like 5V WS2812 stopped working in the winter if you were using 3V3 mcu as a driver)
So what are the possible solutions?

route it to the Ax pin and use analogRead + condition (basically software comparator)

if the previous is too slow, you can use AC module on the mega328p (Analog Comparator), but you'll most likely have to dig into the datasheet and use specific pin or pins (compare it against internal 1V1 reference or external one set by potentiometer)

external OpAmp/Comparator (this one can be used with the original pin, note comparator needs pullup, opamp doesn't)

NPN transistor (1k or bigger between base and Anode of the LED, internal pullup or external one between Vcc and Collector, Emmiter to the ground)

I just note, for completion.... If you wire up an LED and you try to read it, make sure the GND is common between the LED and the Arduino.

A digital input on the Arduino Uno is guaranteed to read LOW if the
input voltage is less than 1.5 V. It is guaranteed to read HIGH
if that voltage is above 3.0 V. For any voltage in between, you
have no guarantees.
That being said, the datasheet of the microcontroller shows some
“typical” characteristics. According to those, the input should switch
to HIGH when the input voltage goes above 2.6 V, and switch to
LOW when it goes below 2.1 V. There is an hysteretic range in
between.
Note, however, that there is no guarantee that your input will behave
like in the typical characteristics. The only guarantees are for
voltages below 1.5 V and above 3.0 V.

I made an experiment, providing up to 5V in the LED. I could still see the input oscillate from 0 to 1 back to 1. Why is this happening? I didn't cross over the 5V threshold.

@user1584421: I do not know what is happening in your setup because: 1. You cannot “provide” 5V to an LED without burning something. 2. The code you posted does not even compile. Please, edit your question: add a schematic of your circuit, and a version of the code that can be tested.

Thanks! I updated the question.

@user1584421: You should never power an LED like this, as you may burn the LED, the power supply, or both. Always use a current-limiting resistor. If nothing burned, chances are the PSU itself is limiting the current, and thus not providing 5 V to the LED.

Yes, you were right. The PSU was limiting the current. I managed to solve this problem with analogRead(). And by having a common GND between the PSU and the Arduino. Thank you very much for your highly informative post!

On my understanding, this is what you made

But i think you should do it this way

Here is the code

int value;
float input;
int delaytime=500;

void setup() {
pinMode(value,INPUT);
Serial.begin(9600); //serial bud rate
}

void loop() {

value=analogRead(A2);
input=(value*5.0)/1022.0;
Serial.println(value);
Serial.println("LED state is: ");
Serial.println(input);
delay(delaytime);

}

source: Stack Exchange

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

sort: votes


text:
Simple serial message not consistent (sometimes jumbled up)
I have the following code, it works (most of the time) - yet it's not 100% reliable and now and then will send through a double message on one line or 2 subsequent alpha characters:
const byte interruptPin0 = CONTROLLINO_IN0;
const byte interruptPin1 = CONTROLLINO_IN1;
int counter1 = 0;
int counter2 = 0;
unsigned long previousMillis = 0;
unsigned long interval = 2000;
int a = 60;
char buffer1[256];
char buffer2[256];

void setup()
{
  pinMode(interruptPin0, INPUT_PULLUP);
  pinMode(interruptPin1, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin0), pin1Fired, RISING);
  attachInterrupt(digitalPinToInterrupt(interruptPin1), pin2Fired, RISING);
  Serial.begin(9600);
}

void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    sprintf(buffer1,"A%d",counter1);
    Serial.println(buffer1);
    sprintf(buffer2,"D%d",counter2);
    Serial.println(buffer2);
    counter1 = 0;
    counter2 = 0;
  }
}

void pin1Fired()
{
  counter1 = counter1 + 1;
}

void pin2Fired()
{
  counter2 = counter2 + 1;
}

Result:

This later causes a problem when my code on the other end of the serial comms expects [LETTER][NUMBER].
What have I missed here? I'm relatively new to C for Arduino so quite possibly took a bad approach here?
I've tried to avoid sending serial comms from the interrupt, I read that was risky - hence me tracking the interrupt counts separately.
Can also confirm baud rate matches.
EDIT
To confirm MCU resets I have printed in setup - note: no interrupts firing, still the same issue:

add some printing to setup(). something like Serial.println("START");to see if the MCU doesn't reset for some reason.

Thanks @Juraj - see edit.

which version of Arduino AVR boards package do you use? The newer versions have newer avr-gcc compiler version and it sometimes has strange problems. Try the Arduino AVR boards package 1.6.21. It has the well-tried version of avr-gcc.

Having to use Controllino's own board manager @Juraj

It seems to compile/upload fine with 1.6.21, I'll let this run and see if this has solved it.

This has been running for 2 minutes and hasn't happened even once! If this has worked @Juraj you have saved me a massive headache!

This has happened again unfortunately, very frustrating. You can see from the link here I have to use their board manager: https://www.controllino.biz/knowledge-base/board-library-setup-in-arduino-ide/

Try removing everything related to the interrupt handling (pinMode(), attachInterrupt(), pin*Fired()...) while keeping counter* volatile. Does the problem persist? 2. Could you share the compiled .elf file corresponding to the minimal program that shows the problem? If so, please update the source code in the question to match this minimal program.

Very frustrating time trying to diagnose this.
All credit to Controllino for their support when looking into whether it was a hardware/code issue (it wasn't!).
The problem turned out to be the recipient of these messages. The performance of the PC the Controllino was plugged into was really bad. I noticed what you've seen in the screenshots I've shared every time I'd open a new app or dragged a window.
The serial monitor in the Arduino IDE would lock up for a few seconds and so would miss the serial messages (and have to catch up).

My guess is that an interrupt is occurring during your reading or writing of the counter variables.
Since the variables are bigger than the native size of the registers in the CPU multiple instructions are required to work with them, and an interrupt can occur right in the middle of that work which changes the values it's working on. That can cause a mess (though I wouldn't expect it to make that kind of mess, TBH).
You should wrap all accesses to the counters that aren't in the interrupts inside a critical section. This is a segment of the code where interrupts are not allowed to happen. For obvious reasons you want to keep that code as short as possible.
Also in the code you have given there is no need for your buffers and sprintfs. You can just use multiple Serial.prints to achieve the same result with a much smaller code/memory footprint.
Here's an example:
void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;

    // Copy and reset the counter values in a critical section
    noInterrupts();
    int nowCounter1 = counter1;
    counter1 = 0;
    int nowCounter2 = counter2;
    counter2 = 0;
    interrupts();

    Serial.print("A");
    Serial.println(nowCounter1);
    Serial.print("D");
    Serial.println(nowCounter2);
  }
}

Also your counter variables should be volatile since they are accessed from both the interrupts and the main loop:
volatile int counter1 = 0;
volatile int counter2 = 0;

Thanks for your reply! That makes sense, I do recall seeing 'noInterrupts' and should have known to use it. I've copied the loop example in your answer but it's still happening. Just received A0A0

What board are you using?

Controllino mini

I find it impossible to work out what USB chip they are using in there. It could be a pile of junk for all we know.

This is not an answer, but showing a way to make your code more clean.
Use the critical sections as proposed by Majenko.
You can rewrite
sprintf(buffer1,"A%d",counter1);
Serial.println(buffer1);
sprintf(buffer2,"D%d",counter2);
Serial.println(buffer2);

as
sprintf(buffer, "A%d\r\nD%d", counter1, counter2);
Serial.println(buffer);

Also, an unsigned long int can be maximum around 10 characters (2^32), so including the 'A', 'D', extra new line and \0, a single buffer of around 30 characters will suffice, instead of 2 buffers of 256 bytes (which takes 25% of an Arduino UNO's SRAM).
Also you can rewrite
counter1 = counter1 + 1;

as
counter1++;

which increases a variable with 1.
Also counter1 and counter2 should never be negative so an unsigned type is better.

@EdgarBonet Thanks for that comment, I updated my answer accordingly.

This isn't meant to be a solution; it's more of a workaround.
To avoid repeated letters, you could use code to make sure that each alpha character isn't the same as the one before, and if so, delete the current character before printing.
Then to tackle doubling, if the string has an even number of characters, split the string in half, and if both halves are equal, remove one of them from the string.
This isn't exactly what you wanted but it's more of a worst-case scenario kind of thing.

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


text:
Confused as to how 2 of my interrupts are firing from just 1 pin input?
I have the following code which uses interrupts to set a flag for whether serial IO should happen to update my PC about a particular pin input. So I have interrupts on pins 2 and 3.
I am using the arduino's pin 13 as an output, and every 2 seconds send a pulse. On my arduino, I have 1 wire running from 13 to pin 3. Note: I have nothing at all inserted into pin 2.
Somehow, I get the following input every 2 seconds:
Pin 2
Pin 3
How is my interrupt for pin 2 firing??
boolean serialCommsQueue1 = false;
boolean serialCommsQueue2 = false;

void setup()
{
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  attachInterrupt(digitalPinToInterrupt(2), pin2Fired, RISING);
  attachInterrupt(digitalPinToInterrupt(3), pin3Fired, RISING);
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop()
{
  digitalWrite(13, HIGH); // sets the digital pin 13 on
  delay(1000);            // waits for a second
  digitalWrite(13, LOW);  // sets the digital pin 13 off
  delay(1000);            // waits for a second

  if (serialCommsQueue1)
  {
    serialCommsQueue1 = false;
    Serial.println("Pin 2");
  }

  if (serialCommsQueue2)
  {
    serialCommsQueue2 = false;
    Serial.println("Pin 3");
  }
}

void pin2Fired()
{
  serialCommsQueue1 = true;
}

void pin3Fired()
{
  serialCommsQueue2 = true;
}

EDIT:
If I take the wire out of 3, pin 2 constantly (every 2 seconds) writes to serial. If I put the wire back in pin 3 regularly writes every 2 seconds - which itself is a problem too, since it should only be detecting a 'change'?

You probably have floating inputs.

The interrupt on pin 2 triggers, because the pin is floating. Since nothing is connected to the pin, it reacts to whatever noise is flying by (for example from pin 3). That can lead to the pin changing its state together with pin 3, or to just erratically randomly changing state.
You need to connect a pullup or pulldown resistor (one rather big resistor going from the pin to either Vcc or ground), which sets the pins state, when it is not actively driven otherwise. If you need a pullup or pulldown depends on your wanted behavior.
If a pullup is ok for you, you can activate the Arduinos internal pullup resistor by using
pinMode(2, INPUT_PULLUP);

I don't think you realise how much hassle this has saved me! Thank you very much mate, I will award a bounty as soon as poss.

This is a common issue with CMOS digital inputs. If they are not connected through a resistor (10k is a good choice) to either +5V or ground, they give semi-random 1s and zeros.


text:
Can I speed up the Leonardo bootloader?
Inspired by an example question before beta, can I make the Leonardo bootloader take less that 8 seconds to run? It is very slow and I want to speed it up somehow.

Can you give us more details about your development environment (IDE you use). Did you burn the bootloader yourself, or did the board came with the bootloader already loaded? Do you have a link to the bootloader code on the net? Also, do you know if this delay is normal of all Leonardo boards? Because 8s seems to be an awful lot of time for a dev board to boot.

It's the default IDE (this wouldn't make any difference, but OK), and i used the stock bootloader that came with the board.

What version of the official Arduino IDE? I'm trying to determine the exact bootloader code base. But it won't be helpful because the bootloader you're using didn't come from your IDE. Since it came installed from factory, we may never know which one it is. The only hope is for you to burn the bootloader from your IDE into the board and report the same delay. If you decide to do it, just beware of what you're doing.

Or someone may give it a try and post an answer assuming one given version of a given bootloader out there. It's possible, but not optimal.

Are you talking about the time it takes to flash a new sketch with the bootloader, or a boot-up delay on reset before an already flashed sketched starts running?

@ChrisStratton the boot up delay

Yes, you can shorten the value of TIMEOUT_PERIOD in caterina.c - see  http://www.leonardomiliani.com/2013/accorciamo-i-tempi-del-bootloader-della-leonardomicroesplora/?lang=en But beware that a shorter value may make it harder to recover if you load a sketch that breaks the USB support.

@chris - make that an answer, i will accept it!

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


text:
Serial input parallel output shift registers with arduino
I need a way to rewrite the switch case part in a more efficient way.
int y , x ;
byte dataArray[6];

void setup () {
   pinMode(8,OUTPUT);
   pinMode(11,OUTPUT);
   pinMode(12,OUTPUT);

   Serial.begin(9600);
   dataArray[0] = 0x3 ; //00000011
   dataArray[1] = 0x5 ; //00000101
   dataArray[2] = 0x9 ; //00001001
   dataArray[3] = 0x11; //00010001
   dataArray[4] = 0x21; //00100001
   dataArray[5] = 0x41; //01000001
}

void loop () {
   while (Serial.available()>0) {
     y = Serial.read();
     x = Serial.read();
     switch ( x ) {
     case 1:
        digitalWrite(8,LOW);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,dataArray[y]);
        digitalWrite(8,HIGH);
        delay(10);
        digitalWrite(8,LOW);
     break;

     case 2:
        digitalWrite(8,LOW);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,dataArray[y]);
        shiftOut(11,12,LSBFIRST,0);
        digitalWrite(8,HIGH);
        delay(10);
        digitalWrite(8,LOW);
     break;

     case 3:
        digitalWrite(8,LOW);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,dataArray[y]);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        digitalWrite(8,HIGH);
        delay(10);
        digitalWrite(8,LOW);
     break;

      case 4:
        digitalWrite(8,LOW);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,dataArray[y]);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        digitalWrite(8,HIGH);
        delay(10);
        digitalWrite(8,LOW);
     break;

      case 5:
        digitalWrite(8,LOW);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,dataArray[y]);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        digitalWrite(8,HIGH);
        delay(10);
        digitalWrite(8,LOW);
     break;

      case 6:
        digitalWrite(8,LOW);
        shiftOut(11,12,LSBFIRST,dataArray[y]);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        digitalWrite(8,HIGH);
        delay(10);
        digitalWrite(8,LOW);
     break;

     default:
        digitalWrite(8,LOW);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        shiftOut(11,12,LSBFIRST,0);
        digitalWrite(8,HIGH);
        delay(10);
        digitalWrite(8,LOW);
     break;
     }
   }
 }

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


text:
Unable to read text file from server
I saw the Web client Example  , In the example, the server connection is initialized in setup(). But I want the server to update the text file every time. So, I need the server connection to be in loop().
But, it is not working. Where is the problem in my code.
#include <GSM.h>

#define PINNUMBER ""

// APN data
#define GPRS_APN       "GPRS_APN" // replace your GPRS APN
#define GPRS_LOGIN     "login"    // replace with your GPRS login
#define GPRS_PASSWORD  "password" // replace with your GPRS password

// initialize the library instance
GSMClient client;
GPRS gprs;
GSM gsmAccess;

// URL, path & port (for example: arduino.cc)
char server[] = "yourdomain.com";
char path[] = "/current.txt";

int port = 80; // port 80 is the default for HTTP

void setup() {
// initialize serial communications and wait for port to open:
Serial.begin(9600);
Serial.println("SMS connected");

// connection state
boolean notConnected = true;

// After starting the modem with GSM.begin()
// attach the shield to the GPRS network with the APN, login and password
while(notConnected) {
   if((gsmAccess.begin(PINNUMBER)==GSM_READY) &
    (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY))
    notConnected = false;

else {
     Serial.println("Not connected");
     delay(1000);
    }
   }
Serial.println("GPRS connected...");
Serial.println(" Connecting to Server ");
}

void loop() {
if (client.connect(server, port)) {
  client.print("GET /current.txt");
  Serial.print("GET /current.txt");
  client.println(" HTTP/1.1");
  Serial.println(" HTTP/1.1");
  client.println("Host: www.yourdomain.com");
  Serial.println("Host: www.yourdomain.com");
  client.println("User-Agent: Arduino");
  Serial.println("User-Agent: Arduino");
  client.println("Accept: text/html");
  Serial.println("Accept: text/html");
  client.println("Connection: close");
  Serial.println("Connection: close");
  client.println();
  Serial.println();
  Serial.println("\nCOMPLETE!\n");
  //client.stop();

} else {
  Serial.println("connection failed");
  Serial.println("\n FAILED!\n");
}

if (client.available()) {
  char c = client.read();
  Serial.print(c);

} else {
  Serial.println();
  Serial.println("disconnecting.");
  client.stop();
}
}

What's not working?

The server is connected, but it does not gives the server response for the requested text file.

It looks like your sketch will only ever read the first character from the server. Is that deliberate?

Its working as long as the connection doesn't break or the server doesn't stall. We must wait till the response .
while (client.connected())
{
 while(client.available())
 {
 char ch = client.read();
 Serial.print(ch);
 }
}
 client.stop();


text:
How to emulate an analog potentiometer with PWM
I have a piece of electronic that controls a motor. It takes power from AC power.
Now there is a 10KOhm Potentiometer. The data sheet of this controller says that the control signal is 10Vcc.
Here's the connections diagram (in Italian):

I'd like to emulate the Potentiometer with Arduino. I'm not sure if PWM will do the job.
Any hints?

I'm not sure your question is clear enough. Can you tell us more about what you want to accomplish? What will be receiving input from this emulated pot?

all right.. is it better?

It's better, thanks! But it's still not enough I suppose. Do you have more info on the board you want to modify? Maybe a picture of the board. Or even better, can you share the datasheet you have?

Usually a pot is part of a voltage divider. I'm assuming that 10Vcc is the voltage at one of the far terminals of the pot. The other end is usually grounded and the middle pin goes from 0 to 10Vcc. But there's no way of knowing if that's what's going on. If it is, you would need a DAC (digital to analog converter) to simulate it...

Hi ricardo, the data sheet is in italian sorry. It is here: http://we.tl/Kk89gm2PRL

No problem, I'm sure someone will read it... I'll read it a home as the firewall at work won't let me.

There exist "Digital Potentiometers" that can be controlled by microcontrollers.  Perhaps one of those will work.

Adding to Ricardo's answer:
PWM can do the job, sort of. You need a low pass filter (LPF) to convert the PWM to an analog voltage and an amplifier to take it from 0-5 to 0-10V. Or you can get a dedicated digital-to-analog (DAC) chip but that will obviously be more expensive than a resistor and capacitor for the LPF.
Here's some tutorials on converting your PWM to an analog voltage:
Analog-Output: How-To
Arduino’s AnalogWrite – Converting PWM to a Voltage
Then you need to basically double the voltage. You do that with an operational amplifier. The resistors you pick for the op amp set its "gain", in this case you want it to be 2 so you can go from ~5v (max output) to 10v.
Here's an example of that: My First OP-AMP Circuit

You can avoid the op-amp by using a PNP transistor to switch the 10v, and pulling down to ground with a resistor, and then filtering that, but the op amp way might make more sense.

You can take an analog (PWM) output from the Arduino and turn it into 0 to 10 V DC using something like this:

Amplification
The op-amp shown is hooked up as a non-inverting amplifier, where the gain is given by:
VOut / VIn = 1 + (R2 / R1)
Since R2 and R1 in this case are both 1 k then the output will be the input multiplied by:
1 + (1000/1000) = 2

Thus, if we have 5 V coming from D3 we will have 10 V at the output of the op-amp. We need to supply a bit more than 10 V to the op-amp supply pin (pin 8) because this is not a rail-to-rail op-amp, that is, it cannot output all the way up to its supply voltage.

Low-pass filter
The resistor R3 and the 10 µF capacitor form a low-pass filter that filters the PWM signal from the Arduino into a more-or-less smooth DC voltage.
This shows the difference between the Arduino PWM output, and the output of the op-amp:

You can see from the scope traces that the yellow line (the PWM output) has a 50% duty cycle, and the blue line (the op-amp output) is 5 V and has a slight ripple.
With a 100% duty cycle, the output is 10 V.

Ripple
Switching the scope to AC coupling we can see how much ripple we have in the op-amp output:

The scale for the blue channel has changed in this image, and the cursor shows that we have around 140 mV of ripple.
We can reduce the ripple by using a larger resistor for R3. For example, making it 10 k reduces the ripple to 86 mV.
The larger resistance make the output less responsive to changes at the input (it takes time to charge or discharge the capacitor) but in testing it still seems pretty responsive.

Code
Test code:
void setup ()
  {
  }

void loop ()
  {
  analogWrite (3, analogRead (A0) / 4);
  }

I had a potentiometer connected to A0 and adjusted it to alter the duty cycle of the PWM output on pin D3.

Theory
You might ask "Why 138 mV of ripple? Why not 50 mV? Why not 200 mV?".
Let's look at the theory. First, the image posted above looks a bit noisy, so let's take an average of the input to the op-amp:

Now we can see that the ripple is about 57 mV (the output of the op-amp would be double that). Indeed, the averaged output is 57 * 2 = 114 mV

The general formula for calculating the time taken by a RC network to reach a certain voltage is:
t = -log((V-Vc)/V)R*C

Where "exp" is the natural exponent.
See Ladyada - RC Delay Calculator.
Also Mathematical treatment of charging and discharging a capacitor.
V  = supply voltage   (initial voltage)
Vc = output voltage   (target voltage)
R  = resistance in ohms
C  = capacitance in farads
t  = time in seconds

These figures will be on the RC discharge graph at roughly the point indicated:

See Wikipedia - RC circuit
Introducing our values for the resistor and capacitor (using Lua) we get:
VS = 5.0       -- supply voltage
VMED = VS / 2  -- 50% duty cycle
VL = VMED - 27.2e-3   -- low voltage as measured
VH = VMED + 29.6e-3   -- high voltage as measured
RES = 4700            -- resistance in ohms
CAP = 10e-6           -- capacitance in farads

T1 = -math.log ( (VS - VH) /VS) * RES * CAP
T2 = -math.log ( (VS - VL) /VS) * RES * CAP

print ("T1 =", T1)
print ("T2 =", T2)
print ("diff = ", T1 - T2, "seconds")

Results:
T1 = 0.0331
T2 = 0.0321
diff =  0.0010 seconds

The time difference is 1 ms which agrees with the observations.

Quite right! How come no-one noticed that for a year? I've converted your "answer" to a comment. With a bit more reputation, you will be able to post comments. Thanks for pointing it out. And, welcome to Arduino Stack Exchange. :)

You can use any typical motor control chip like a ULN2003 with PWM and maybe a smoothing capacitor, Google "ULN2003 Arduino" for many examples.
Based on the pinouts from Ricardo's answer, you'd get the 10V from pin 1 and ground from pin 3, and feed the PWM'd output from the ULN2003 back into pin 2.

that ia darlington transistor right? I'm still a student in electronics.. does it means that a darlington transistor can amplify current right? but what for pwm VS analog signal?

@nkint Yes, you're using a Darlington like a fast relay switch, using the Arduino's 5V output to control the device's 10V. The switching speed makes it suitable for use with PWM from the Arduino. You could add a capacitor to help smooth the output to make it more like analog.

I won't be able to answer your question completely, but hopefully I'll be able to make things a bit clearer for someone more knowledgeable to complete the answer.
From what I could understand from the datasheet, inputs 1, 2 and 3 are used to connect a pot that will control the motor speed. It's the POTENZIOMETRO DI COMANDO (control pot) in the figure linked in the question.
The datasheet also specifies (in the figure below) that you can connect terminal 3 to ground and feed terminal 2 with a voltage from 0 to 10Vcc, that will control the motor. That's how you control the motor using a MCU, I suppose.

Here's where my knowledge is getting short. I'm guessing that a PWM signal won't do the trick. You'll need to feed an actual voltage in terminal 2 to control the motor properly. To do that you have a few alternatives:

Use an ADC IC
Use an R2R resistor ladder network using digital outputs and some means to amplify its voltage to 10Vcc.

I hope this helps a bit.

my solution is simple get a servo (pwm input) and connect the shaft of the servo to the pot with a coupler then just use a simple servo control program


text:
Resetting an Arduino with a timer
I want to run an Arduino autonomously - but although I apply a watchdog sometimes the systems hangs and can only be restarted by physically interrupting the power-supply (or hitting reset). So I need an external source to do that either after x hrs or based on a condition.
Instead of using another Arduino with a MOSFET or relay I am asking myself if this couldn't be done smarter with a pure electronic component like a timer or a capacitor. I could set a pin of the Arduino on high while it is active and let this charge a capacitor or something similar - if the time/energy exceeds a certain amount (because it hangs) this would connect the reset-pin of the Arduino to ground.
Any idea how this could be achieved and what component should be used?

You can buy specific watchdog chips that do this job for you.  You could also probably craft something with a 555 timer which you start timing with a pulse from the MCU and each pulse resets its timing.

Best would be to fix the problem that's making the Arduino hang in the first place. Since you didn't post any code nor schematics, I can only guess that this may be a hidden bug in the code. In normal conditions, ATmegas and Arduinos can run for a long time without hanging. I have a ATmega328P based digital clock running for several months without resetting it.

Sorry for not posting the code - i have it on github link. Besides check on memory consumption etc. what makes me believe it's not a code issue is the fact that i have several of these (identical) devices and the error never seems to show a similar pattern, not in timing and not in shape... But of course i can be wrong, am definitely not an experienced programmer.

The following 555 circuit will produce a 170 ms low-going pulse every 24.2 hours.  You can adjust the values of the components using this calculator if you want different timing parameters.

Since the reset line of a microcontroller is configured for open-drain (meaning you can connect several inputs to it, which is a good thing since we are taking advantage of that), we need to drive it with a open-drain output.  That is what the buffer on the bottom of the circuit is for, to convert the push-pull output of the 555 to open-drain.  A typical buffer is one section of a 7407.

Awesome - really works well and exactly what i was looking for! BUT: would like to try another version where the 555 is used rather as a replacement for the "if anything goes wrong reset" watchdog, meaning: if program execution takes longer than 60sec reset (and while sleeping do nothing). My first attempt failed, tried to power the 555 circuit by a Pin of the Arduino and simply switch it off when sleeping. Any idea how this could be implemented as well?

@StephanNoller Good to hear that worked for you.  Re your new requirement, I would ask that as a new question.

Followed your advice - would be so grateful if you could have a look at this 555 question as well...

Here is the circuit I use which depends on a heartbeat from the arduino and resets the arduino if 8 pulses are missed and also enables the arduino code to know that an external watchdog reset occured

and the Arduino code which can be incorporated into your sketch

//Watchdog
#define ResetDetect 8       // watchdog detect pin, HIGH if a watchdog reset has occured
#define heartbeat 9         // heartbeat pin
int pulseState = LOW;       // pulseState used to set the heartbeat pin
long lastbeat = 0;          // will store last time the heartbeat pin was updated
long HeartBeatFreq = 500;   // interval at which to blink (milliseconds)
boolean ResetHappened;      // Set to true if a watchdog reset has occurred

void setup(){
  pinMode(ResetDetect, INPUT);    // set Watchdog Reset sensing pin as input
  digitalWrite(ResetDetect, HIGH);// and turn on pullup
  pinMode(heartbeat, OUTPUT);     // set the heartbeat pin as output:

    // Check if Restarting after Watchdog Reset
    // NB must come before heartbeat resets external counter
    int ResetSet = digitalRead(ResetDetect);
    if (ResetSet == HIGH){
      ResetHappened = true;
    }
    else {
      ResetHappened = false;
    }
}

void loop(){

  // Heartbeat resets external watchdog when pin goes high
  if ((long)( millis() - (lastbeat + HeartBeatFreq)) >= 0) {
    lastbeat = millis();
    // if the LED is off turn it on and vice-versa:
    if (pulseState == LOW)
      pulseState = HIGH;
    else
      pulseState = LOW;
    // set the LED with the ledState of the variable:
    digitalWrite(heartbeat, pulseState);
  }
}

If there are long running sections of code the 'heartbeat' could be put into a function and that function called in the appropriate places to avoid unintended timeouts/resets

Why not use the in-ship watchdog timer ?
I found in the Atmel ATmega328 (used for example in the official Arduino Uno board) official datasheet some references :
http://www.atmel.com/Images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet.pdf

We can find on page #5 two blocks named "Watchdog Timer" and "Watchdog Oscillator" on the upper left corner. No need of additional circuits, soldering or any connections.
These blocks are bad documented on the Arduino official website but usable (I did it).
Some docs with code examples :

http://sysmagazine.com/posts/189744/
https://tushev.org/articles/arduino/item/46-arduino-and-watchdog-timer

Regards

I am indeed using these functions - but unfortunately - after working like intended for days - the device sometimes hangs nevertheless. That's why i am searching for a more safe fallback-solution now.

@StephanNoller What is your Arduino board type ? Mine is legacy Arduino Uno and I've not found any problem.
If you watch the sysmagazine link, the author give some explanation about a watchdog specific program hang ...:
http://sysmagazine.com/posts/189744/


text:
Read RC receiver channels using Interrupt instead of PulseIn
I am designing my own quadcopter control algorithm, whereby I currently read 4 RC receiver channels using PulseIn on each loop in the following manner:
ch1_raw = pulseIn(rcPin1, HIGH, 25000);

In other words, ch1_raw contains the length of a HIGH pulse in microseconds.
I now want to avoid PulseIn in the interest of speed and instead achieve the same using interrupt.
I have looked at http://playground.arduino.cc/Main/PinChangeIntExample and I am aware that other similar questions have been asked (e.g. How to read RC receiver channels without using pulsein() command with arduino and Is PulseIn fast enough for Quadcopter?), but I don't understand how to implement interrupt to give me the correct ch1_raw value on each loop.
Can somebody help me? (I'm new to Arduino, so go easy on me please!) Thanks!

Edit:
So far I have tried to implement the following:
#include <PinChangeInt.h>

unsigned long pulsestart, pulsewidth;

int rcPin1 = A0;

void setup(){

  pinMode(rcPin1, INPUT);

  Serial.begin(9600);

  PCintPort::attachInterrupt(rcPin1, counttime,RISING);
  PCintPort::attachInterrupt(rcPin1, subtracttime,FALLING);

}

void loop(){

  Serial.print("  pulsewidth: ");
  Serial.println(pulsewidth);

}

void counttime()
{
  pulsestart = micros();
}

void subtracttime()
{
  pulsewidth = micros()- pulsestart;
}

Edit 2:
(Somewhat) successful implementation so far, using EnableInterrupt.h instead. It seems that FALLING is being detected, but not RISING.
#include <EnableInterrupt.h>

#define rcPin1 10

volatile uint16_t pulsestart=0;
volatile uint16_t pulsewidth=0;
//volatile unsigned long pulsestart=0;
//volatile unsigned long pulsewidth=0;
volatile uint16_t risingcount=0;
volatile uint16_t fallingcount=0;

void counttime()
{
  pulsestart = micros();
  risingcount++;
}
void subtracttime()
{
  pulsewidth = micros()- pulsestart;
  fallingcount++;
}

void setup() {
  Serial.begin(9600);
  pinMode(rcPin1, INPUT_PULLUP);
  enableInterrupt(rcPin1, counttime, RISING);
  enableInterrupt(rcPin1, subtracttime, FALLING);
}

void loop() {
  //delay(1000);
  Serial.print("risingcount: ");
  Serial.print(risingcount);
  Serial.print(" fallingcount: ");
  Serial.println(fallingcount);
  //Serial.print("pulsewidth: ");
  //Serial.println(pulsewidth);
}

For some reason, this code posted above does not work on the mega 2560 and only works on the uno. Please let me know if you can find out why.

Regarding the question, “Does PinChangeInt only work on digital pins?”, note that PCI's work on all the digital pins of an ATmega328, and on the first six analog pins.  (32-pin '328s have eight analog pins, A0-A7; 28-pin '328s only six, A0-A5.)
Regarding the problem symptom that “pulsewidth just seems to increase continuously”, that could happen if for some reason rising edges aren't processed.  To debug, add a couple more volative byte variables, say nrises and nfalls; increment each of them in the appropriate interrupt handler; and report their values from time to time.
Regarding your #include <PinChangeInt.h> statement, note that PinChangeInt.h is deprecated (as of 3 April 2015).  Consider using EnableInterrupt.h instead.
It's possible you'll resolve your problem while changing libraries.  If so, fine.  If not, or if that library's performance isn't adequate, consider changing over to handling the  pin change interrupts more directly.  The ISR in the following sketch shown below runs several times faster than code that uses PinChangeInt or EnableInterrupt library calls.
[Edit: This edit encloses the ISR in a sketch that compiles.  The code previously shown was missing two array length specifications.  This code was tested with a rotary encoder attached to A2, A3, with A0 and A1 grounded; an output sample (using an Arduino Nano) follows the code.]
/*  rcTiming.ino -- JW, 30 November 2015 --
 * Uses pin-change interrupts on A0-A4 to time RC pulses
 *
 * Ref: http://arduino.stackexchange.com/questions/18183/read-rc-receiver-channels-using-interrupt-instead-of-pulsein
 *
 */
#include <Streaming.h>
static   byte rcOld;        // Prev. states of inputs
volatile unsigned long rcRises[4]; // times of prev. rising edges
volatile unsigned long rcTimes[4]; // recent pulse lengths
volatile unsigned int  rcChange=0; // Change-counter

// Be sure to call setup_rcTiming() from setup()
void setup_rcTiming() {
  rcOld = 0;
  pinMode(A0, INPUT);  // pin 14, A0, PC0, for pin-change interrupt
  pinMode(A1, INPUT);  // pin 15, A1, PC1, for pin-change interrupt
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  PCMSK1 |= 0x0F;       // Four-bit mask for four channels
  PCIFR  |= 0x02;       // clear pin-change interrupts if any
  PCICR  |= 0x02;       // enable pin-change interrupts
}
// Define the service routine for PCI vector 1
ISR(PCINT1_vect) {
  byte rcNew = PINC & 15;   // Get low 4 bits, A0-A3
  byte changes = rcNew^rcOld;   // Notice changed bits
  byte channel = 0;
  unsigned long now = micros(); // micros() is ok in int routine
  while (changes) {
    if ((changes & 1)) {  // Did current channel change?
      if ((rcNew & (1<<channel))) { // Check rising edge
        rcRises[channel] = now;     // Is rising edge
      } else {              // Is falling edge
        rcTimes[channel] = now-rcRises[channel];
      }
    }
    changes >>= 1;      // shift out the done bit
    ++channel;
    ++rcChange;
  }
  rcOld = rcNew;        // Save new state
}

void setup() {
  Serial.begin(115200);
  Serial.println("Starting RC Timing Test");
  setup_rcTiming();
}

void loop() {
  unsigned long rcT[4]; // copy of recent pulse lengths
  unsigned int rcN;
  if (rcChange) {

    // Data is subject to races if interrupted, so off interrupts
    cli();          // Disable interrupts
    rcN = rcChange;
    rcChange = 0;       // Zero the change counter
    rcT[0] = rcTimes[0];
    rcT[1] = rcTimes[1];
    rcT[2] = rcTimes[2];
    rcT[3] = rcTimes[3];
    sei();          // reenable interrupts

    Serial << "t=" << millis() << " " << rcT[0] << " " << rcT[1]
       << " " << rcT[2] << " " << rcT[3] << " " << rcN << endl;
  }
  sei();            // reenable interrupts
}

The code shown above uses Streaming.h, a contributed library that adds some “syntactic sugar” to Arduino C.  That is, at compile time it converts C++-like << Serial stream operators to Serial.print statements, without increasing code size.  If you don't have Streaming.h installed, either install it via Streaming5.zip from arduiniana.org or manually translate the Serial << ... statement to Serial.print statements.
A sample of the sketch's output on serial monitor:
t=35773 0 0 14196 13456 4
t=35775 0 0 14196 13456 3
t=35778 0 0 14196 5748 4
t=35781 0 0 5244 5748 3
t=35783 0 0 5244 5748 4
t=35785 0 0 5244 5748 3
t=35786 0 0 5244 28 12
t=35788 0 0 3024 28 3
t=35789 0 0 3024 28 4
t=35792 0 0 3024 28 3
t=35796 0 0 3024 6396 4
t=35802 0 0 9316 6396 3
t=35809 0 0 9316 6396 4

In the output above, the two 0's are from A0, A1 being grounded and not changing.  The next two numbers are from the DT and CLK lines of a KY-040 rotary encoder, which toggle alternately to encode step-direction.  They should represent on-times in microseconds, and are always multiples of 4 because micros() reports multiples of 4.
The last number is the number of times the ISR's change-checking loop ran since loop()'s previous print.  An A2 change will show a count of 3 or more, and an A3 change 4 or more.  Cases where times are the same may represent contact bounces shorter than the ISR's service time; ie, several falling edges in a row might be detected, or several rising edges.  A storage scope or logic analyzer probably is necessary for finding out exactly what happens.

Many thanks! So I have implemented nrises and nfalls as you suggested; and I have also tried to run the code here: http://playground.arduino.cc/Main/PinChangeIntExample - I have tried both on several different pins. The result is always the same: nrises and nfalls stay on 0, i.e. it seems that indeed the rising/falling edges are not being processed.

I have also tried the code you provide above, which looks great for my application, since speed is of the essence. I am having some trouble implementing it though. Right now, I am getting a compiling error on "rcRises[channel] = now;": "invalid types 'volatile long unsigned int[byte]' for array subscript

I have now been somewhat successful using EnableInterrupt.h instead (see edit 2 above). When attaching a simple switch between the rcPin1 and ground, I have managed to narrow down the problem to FALLING being detected (fallingcount increases each time I press/depress the switch) but not RISING (rising count stays at 0). This also occurs when attaching the RC receiver instead of the switch.

Does anybody know why this would be? and how I can resolve this issue? Thanks!

Add [4] before ; in  declaration of rcTimes, and similarly for rcRises.  See edit.

Brilliant! It works perfectly, and very fast. I am now able to run my complete quadcopter control loop (including inputs from gyro and accelerometer, outputs to ESCs, etc. not shown here) at ~200 Hz, whereas before (using PulseIn) the fastest I could achieve was ~12 Hz. BIG difference! Thanks so much.

Are you aware there is a library that does this? https://github.com/jantje/libraries/tree/master/RCLib

@jantje, I wasn't aware of that library.  Thanks for mentioning it!  Note, the example Maga6ChanelsA8_A13.ino includes PinChangeInt.h which
is deprecated (see EnableInterrupt.h instead). Both of PinChangeInt.h
and EnableInterrupt.h are slow -- they do a bunch of extraneous
processing the code shown above avoids.

Thanks for the feedback.
Note that the library only uses pinchange int if you want to use pins that do not support pin interrupts by hardware.

Interrupts don't obey, or even understand the concept of, the "loop" paradigm.
An interrupt fires when it needs to fire, and if you're reading a PWM signal then that means it's firing hundreds of times a second.
As long as your interrupt is updating a variable that can be read from within the loop, and you ensure that the variable doesn't get updated during your reading of it (Google: Critical Sections) then you will always have the most up to date value at your fingertips whenever you need it.
As for the interrupt itself, that's very straight forward - you just need to recognise if it's a rising or falling edge:

If rising edge: record the timestamp (micros()).
If falling edge: Subtract the recorded timestamp from the current micros() and store in the global variable.

Actually the repetition rate for a channel is traditionally around 50hz, meaning the loop will probably be running faster than the data source.  However the channels are usually time multiplexed, so if downstream of a demux reading individual servo leads, we might say time striped.

50 Hz = 100 edges per second. That counts as hundreds to me ;)

Many thanks! That's a lot more clear already. I have edited my question to show what I have tried to implement so far. However, it is not quite right yet. "pulsewidth" just seems to increase continuously and does not respond to any change in RC transmitter input. Can you see what I have done wrong?

Pin A0 is an analogue pin. Does PinChangeInt only work on digital pins?

Make your interrupt variables volatile.

ok I've done that (simply by putting "volatile" in front of the "unsigned long"). but still the same symptoms

authors: Γιωργος Βεζυρης

authors: Олександр Калашник


text:
Arduino board as USB/serial for a Nano with broken USB
I broke the USB connector on an Arduino Nano and I am trying to use my Uno board as a USB/serial adapter to be able to upload sketches. The broken Nano came with a customized bootloader (avrdude -c arduino compatible), which I do not have a copy of. The content in the HEX files I have is encrypted, it has to go through the bootloader for the plain code to be flashed. This rules out ISP.
I came up with this:

Please note that the ATMega on the Uno board is removed. As I am proxying the Nano through the Uno board, I am wiring RX to RX and TX to TX.
The problem I face is that it seems the Nano board is not receiving data from the PC. Everything else works:

pressing the reset button on either board resets the Nano
TX from the Nano goes back to the PC (the current sketch on the Nano prints some stuff on boot), TX leds blink accordingly on Nano and Uno boards
RX led on the Uno board blinks when PC sends something, but RX led on the Nano board does not blink in that case
connecting the RX/TX Nano pins to a USB/serial cable lets me send and receive data to/from the sketch

I tried with another, non-broken, Nano (standard bootloader) and I have the same issue, so I think the broken Nano is fine. If I upload a sketch that continuously writes to the serial port, the PC receives it. If I upload an "echo" sketch, I do not get anything back (the "echo" works well over direct USB connection).
I am a software guy, my apologies if I am doing something obviously wrong. I read several pages on the topic, I couldn't spot a fix. The boards are not official Arduino products, but I am not sure this is relevant. I wonder if part of the answer is related to the fact that the USB/serial conversion is handled by a Mega16U2 chip rather than something like a CH340, now useless on the broken Nano.
Some links that I checked:

Arduino UNO as USB to serial TTL converter
Arduino Uno as an FTDI RS232 to Serial Adapter
Using an Arduino or Seeeduino for its FTDI chip
Use an Arduino UNO as a USB-to-Serial converter

You probably need to remove the USB interface chip from the broken board, or else cut its connection to the target processor, so that the external interface can drive it instead.  Sometimes there is a 1K or so resistor to permit something else to take over, but your source Arduino is even more likely to have that resistor, so the wrestling match may end in a draw.  If there is such a resistor on the target board, removing it is probably the best solution.

The target's disused USB serial chip is not generating noise, but arguing about the proper signal level, only on the side where it would be transmitting - you can have both serial interfaces receive from the target ATmega without conflict.  Cutting power to disused chips is generally not a sound solution - they may draw power from I/Os instead, both stressing the chip and loading those I/Os to the point where the signal levels are invalid.  You really should remove the resistor on the target, but if you can get the signal upstream of the resistor on the source that might work temporarily.

You may want to connect +5v to +5v not to VIN.

@Majenko I don't think I should do so. As stated in the Arduino documentation (https://www.arduino.cc/en/Main/ArduinoBoardUno) the 5V pin outputs a regulated 5V.

No, that is wrong. Do not believe everything you read on the Arduino website. The 5v pin is connected to the regulated 5v rail. It neither outputs nor inputs. It just is. Since you don't have a high enough voltage going in to vin for the regulator to work properly you don't have a regulated 5v rail on the nano. So link it to the regulated 5v rail of the Uno to make it a regulated 5v rail.

As explained in comments by Chris Stratton, both the Mega16U2 on the Uno and the USB/serial chip on the Nano are competing for the signal level. Removing the resistors on the RX/TX lines between the USB/serial chip and the ATMega on the Nano board will prevent it from interfering with the signals exchanged with the Uno.


text:
Arduino Mega pin conflict
I am building a rather complicated model railroad crossing signal and have moved to using the Mega since I need more pins than the Uno. Upon reading the specs of the Mega on the Arduino.cc website I noticed a potential pin conflict, or not, maybe they serve a dual purpose?

External Interrupts: 2 (interrupt 0), 3 (interrupt 1), 18 (interrupt 5), 19 (interrupt 4), 20 (interrupt 3), and 21 (interrupt 2).
I2C: 20 (SDA) and 21 (SCL).

SDA and Interrupt 3 both function on pin 20? Likewise with Interrupt 2 and SCL?
I assume this is true, how/why do they share the same pin?

Lots of things share pins. It's normal. The "how" is that those pins are connected, internally, to multiple bits of the circuitry.
The "why" is simply because if you had a discrete pin for each possible function you would end up with a chip the size of your desk.
Pretty much every single pin on the chip has multiple functions on it.

Then can you define two things with the same pin? #define INTERRUPT_3 20 and then #define I2C_SDA 20?

You can define anything to anything. You can only use one function at a time though. After all - how would you wire the pin to both the I2C device and the interrupt source and differentiate between them?

So if I plan on using interrupts AND I2C, then effectively I can't use interrupt3?

And interrupt 2. Still, you have pin-change interrupts on every single other pin on the board...

Not on the Mega you don't.

@NickGammon Hence the "pretty much" in my answer. True, I forgot it was a Mega in the comments. I do find it bizarre that Atmel "forgot" to provide PCINT on an entire port...

Maybe they hit some complexity in the internal state machine that the processor uses, that it would take more trouble than it was worth to support it.


text:
Error: "invalid use of incomplete type" and "forward declaration"
I have the following errors trying to use a TFT library function inside my library. My library uses the pointer to an instance of the TFT library in the constructor, as well described there:
Basic C++ programming, how to pass constructor argument into class?
The errors are:
error: invalid use of incomplete type 'class TFT'
_TFTscreen->background(0, 0, 0);

error: forward declaration of 'class TFT'
class TFT;

MESmenu.h:
#ifndef _MESMENU_H_
#define _MESMENU_H_

#include <SPI.h>
#include <SD.h>

class TFT;

class MESmenu{
public:
  MESmenu(TFT* pTFT) : _TFTscreen(pTFT) {};
  void start();
  void execute();
private:
  TFT* _TFTscreen;
};

#endif

MESmenu.cpp:
#include "Arduino.h"
#include "MESmenu.h"

void MESmenu::start(){
  _TFTscreen->background(0, 0, 0);
  _TFTscreen->text("starting menu...", 0, 0);
  //...
}

void MESmenu::execute(){
   //some code...
}

The Arduino sketch is:
#include <SPI.h>
#include <SD.h>
#include <TFT.h>  // Arduino LCD library
#include <MESmenu.h>  // my library

// --------- TFT LCD ---------
// pin definition for the due
#define sd_cs  7
#define lcd_cs 10
#define dc     9
#define rst    8
TFT TFTscreen = TFT(lcd_cs, dc, rst);

// MES menu class
MESmenu *mainMenu = new MESmenu(&TFTscreen);

void setup() {
  // initialize TFT
  TFTscreen.begin();
  TFTscreen.background(0, 0, 0);
  // set the stroke color to white
  TFTscreen.stroke(255,255,255);
  TFTscreen.fill(255,255,255);
  TFTscreen.setTextSize(2);
  TFTscreen.text("TEST", 0, 0);

  // Start menu
  mainMenu->start();
}

void loop () {
  mainMenu->execute();
}

The problem is related to the function:
_TFTscreen->background(0, 0, 0);

inside the MESmenu::start() in the .cpp file.
UPDATE:
As suggested by frarugi87 I've updated the question with the details of .h and .cpp files.
Those file are in the Arduino\libraries\MESmenu folder.
I try to change
class TFT;

with
#include <TFT.h>

and removed the #include  from the main arduino sketch.
This leads to the following errors:
libraries\MESmenu\MESmenu.cpp.o: In function `Adafruit_GFX::image(PImage&, unsigned int, unsigned int)':
D:\Software\arduino-1.6.7\libraries\TFT\src/utility/Adafruit_GFX.h:231: multiple definition of `Adafruit_GFX::image(PImage&, unsigned int, unsigned int)'
sketch\test_MESmenu_lib.ino.cpp.o:D:\Software\arduino-1.6.7\libraries\TFT\src/utility/Adafruit_GFX.h:231: first defined here

libraries\MESmenu\MESmenu.cpp.o: In function `Adafruit_GFX::image(PImage&, unsigned int, unsigned int)':
D:\Software\arduino-1.6.7\libraries\TFT\src/utility/Adafruit_GFX.h:231: multiple definition of `PImage::read16(SDLib::File)'
sketch\test_MESmenu_lib.ino.cpp.o:D:\Software\arduino-1.6.7\libraries\TFT\src/utility/PImage.h:17: first defined here

libraries\MESmenu\MESmenu.cpp.o: In function `Adafruit_GFX::image(PImage&, unsigned int, unsigned int)':
D:\Software\arduino-1.6.7\libraries\TFT\src/utility/Adafruit_GFX.h:231: multiple definition of `PImage::read32(SDLib::File)'
sketch\test_MESmenu_lib.ino.cpp.o:D:\Software\arduino-1.6.7\libraries\TFT\src/utility/PImage.h:17: first defined here

libraries\MESmenu\MESmenu.cpp.o: In function `Adafruit_GFX::image(PImage&, unsigned int, unsigned int)':
D:\Software\arduino-1.6.7\libraries\TFT\src/utility/Adafruit_GFX.h:231: multiple definition of `PImage::loadImage(char const*)'
sketch\test_MESmenu_lib.ino.cpp.o:D:\Software\arduino-1.6.7\libraries\TFT\src/utility/PImage.h:17: first defined here

Please add the actual source code that gives the problem. It looks like you have forgot to include the TFT header file in the menu source file.

The posted code is almoste complete.
I have the MESmenu.cpp file that contais:
#include "Arduino.h"
#include "MESmenu.h"

void MESmenu::execute(){
  _TFTscreen->background(0, 0, 0);
}

And this give me the error.
If I put the code of the function "execute" in the .h file it works.
If the code is in the .cpp file I got the error.
I cannot include the TFT.h library in the .h or .ccp files, becouse it leads to "multiple definition"

Try to change
class TFT;

to
#include <TFT.h>

Then you can remove the #include <TFT.h> from the main arduino sketch.
Moreover you should at least write a piece of code to make the compiler include your library just once; this is the usual way to do it:
#ifndef _MESMENU_H_
#define _MESMENU_H_

#include <SPI.h>

...
the rest of your library
...

  TFT* _TFTscreen;
}

#endif

_MESMENU_H_ is any unique string (usually the filename is used, remembering that you can't put spaces or other punctuation marks except the underscore). And you should put it only in the header file (*.h or .hpp), not in the source (.c or *.cpp or *.ino)
EDIT:
The additional info lead me to analyze the library and.. there are problems with the library. Particularly the file TFT/src/utility/Adafruit_GFX.h has a big problem: it has the code for the functions.
To fix it, you have to modify the library.
Go into the folder TFT/src/utility/ and make a copy of Adafruit_GFX.h, calling it PImage.cpp.
Open Adafruit_GFX.h and delete everything between line 227 and line 370. This means that from
bool useFill;
};

#if defined(__SD_H__)  // Arduino SD library

#define BUFFPIXEL 20

void Adafruit_GFX::image(PImage & img, uint16_t x, uint16_t y) {

...

  return PImage(bmpFile, bmpWidth, bmpHeight, bmpDepth, bmpImageoffset, rowSize, flip);
}

#endif

#endif // _ADAFRUIT_GFX_H

it should become
bool useFill;
};

#endif // _ADAFRUIT_GFX_H

Having done this, open PImage.cpp and delete everything above line 227, then delete the function Adafruit_GFX::image and the last endif and add, at the beginning, #include Adafruit_GFX.h. This means that the file should look like
#include "Adafruit_GFX.h"

#if defined(__SD_H__)  // Arduino SD library

#define BUFFPIXEL 20

// 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 PImage::read16(File f) {

...

  return PImage(bmpFile, bmpWidth, bmpHeight, bmpDepth, bmpImageoffset, rowSize, flip);
}

#endif

Then try to compile again the program
BTW: the source I looked at is at this page.

I try with your suggestion, but now I got "multiple definition" releated to Adafruit_GFX.h that is included in the TFT library. Do you think that the problem could be in the TFT library itself?

@DavideTagliafierro multiple definitions of what?

libraries\MESmenu\MESmenu.cpp.o: In function 'Adafruit_GFX::image(PImage&, unsigned int, unsigned int)':
D:\Software\arduino-1.6.7\libraries\TFT\src/utility/Adafruit_GFX.h:231: multiple definition of 'Adafruit_GFX::image(PImage&, unsigned int, unsigned int)'
sketch\test_MESmenu.ino.cpp.o:D:\Software\arduino-1.6.7\libraries\TFT\src/utility/Adafruit_GFX.h:231: first defined here

Ok, and where is MESmenu.cpp? Can you post the whole modified files in the question? Or at least the ino, mesmenu.h and mesmenu.cpp

Question updated with more details. I try to move all the functions from the .cpp file to the .h file it works (not tested on the board, but it compiles). I still doesn't understand why.

@DavideTagliafierro Modified the answer; it looks like the library is broken ;)

Thanks a lot for the hint. I tried to modify the library following your indications, but I got even more "multiple definition" than before. I think that the TFT library needs more changes... I ended up moving all the functions of my MESmenu library to the .h file and delete the .cpp file.
I was stuck since a long time on that and in one day you help me getting out. Thanks.

@DavideTagliafierro Glad you made it. Anyway you should not include the cpp file too; and the common rule is thaty you should only include h files, and in h files you should never define variables (only declare them - as external, of course) nor implement functions outside class definition; these should be performed in cpp or ino files..


text:
Setting the frequency of a timer interrupt
The concept:
Play a sine wave saved as a character array in PROGMEM through an 8-bit DAC connected to the PORTC pins on the Arduino Mega.
This works:
// File just defines an array and a size

#include "sine440.h"

int i = 0;
void setup() {
  DDRC = B11111111;
}

void loop() {
  PORTC = pgm_read_byte(&sine[i++]);
  if(i >= sine_size){
    i = i - sine_size;
  }

  delayMicroseconds(60);
}

The above code produces a sine wave of about 440 Hz, exactly what I wanted. Now, I'd like to move this into an interrupt routine, as follows:
This doesn't work
#include "sine440.h"

int i = 0;
void setup() {
  DDRC = B11111111;
  TCCR5B = (1 << WGM52) | (1 << CS50 );
  OCR5A =  16000000/16000;
  TIMSK5 = (1 << OCIE5A);
}

ISR(TIMER5_COMPA_vect){
  PORTC = pgm_read_byte(&sine[i++]);
  if(i >= sine_size){
    i = i - sine_size;
  }
}

void loop() {

}

The above code produces a sine wave of 1721 Hz. I know that this means it's iterating through the array too fast, but I don't know how to change it. In order for it to produce 440 Hz, it needs to be preforming 16,000 iterations per second, which is what I believe  OCR5A =  16000000/16000; does. But it doesn't appear that changing the value of OCR5A does anything at all. Giving it the max value of 65,535 still produces a 1721 Hz sine wave...
So what am I doing wrong here? How do I change the speed of this timer interrupt?

Try setting TCCR5A = 0 explicitly, maybe arduino has WGM51 or WGM50 set at startup for some reason.

I second BrettAM's comment. The Arduino IDE sets most of all the timers up for PWM, and I had to comment out a section once to use my own ISR with Timer 3 on a 32u4, because no matter where or how I set it, the CTC interrupt never went. The WGM50 and CS51 are set at the start of the Arduino files basically, so that messes with your settings.
You will need go into the Arduino core files. This is $install_path/arduino-1.x.x/hardware/arduino/avr/cores/arduino/, and under that directory you need to find file wiring.c. This file contains all the setup of the timers for PWM and the millis() or micros() functions.
Go to line 342. Located there is this:
#if defined(TCCR5B) && defined(CS51) && defined(WGM50)

  sbi(TCCR5B, CS51);           //set ter 5 prescale factor to 64
  sbi(TCCR5B, CS50);
  sbi(TCCR5A, WGM50);         // put timer 5 in 8-bit phase correct pwm mode

#endif

Here you can place another #if defined() macro around this, resulting in:
#if !defined(doNotSetTimer5)

  #if defined(TCCR5B) && defined(CS51) && defined(WGM50)

    sbi(TCCR5B, CS51);           //set ter 5 prescale factor to 64
    sbi(TCCR5B, CS50);
    sbi(TCCR5A, WGM50);         // put timer 5 in 8-bit phase correct pwm mode

  #endif

#endif

Now when you want to use your custom settings, you will put the following at the top of your .ino file:
#define doNotSetTimer5
#include <wiring.c>

That does not block the Arduino environment from setting up Timer 5 when compiled with other code, but only when you want to use custom settings (changed because of @Gerben's suggestion). When you change these settings you will lose PWM on 3 pins: 44 45 46. But you will be able to make use of setting your own PWM up or a CTC ISR().
This doesn't mess with anything else and is the easiest way to do it.

Wouldn't it be better to use a !defined(...), as to not break existing code? Something like #if !defined(doNotSetTimer5). That way you need to set the flag only if you want the no-standard settings.

@Gerben         that's a good point, I will change it to that rather then. Will be more compatible with stuff. +1

Hey, thanks. I actually found a thread yesterday before seeing BretAm's comment that addressed this issue with a different timer. So i tried it out and it worked. But this did a great job in explaining WHY it was happening.

@Dave          pleasure, maybe just add that link as a comment here or something to have another way too.


text:
ATtiny85 (Sparfun Clone/Trinket), detect/read operation voltage
I just started with Arduino programming and currently I'm using this Sparkfun clone board:
o http://nl.aliexpress.com/item/Digispark-kickstarter-Micro-development-board-ATTINY85-module-for-Arduino-usb/32584975067.html
It's really nice and like the way to program it and 'burn' it, it's easy to do. For the first project, I came along this instructable, an USB volume knob:
o http://www.instructables.com/id/Digispark-Volume-Control/
I'm using the Sparkfun Arduino programming IDE with added AdaFruit Trinket USB library (Trinket is also ATtiny85), download source, tweak it a bit to my needs and it's working perfectly. Had some programming question though, see also:
o https://stackoverflow.com/questions/37740026/change-override-trinket-attiny85-usb-identification-name-device-name/37743886#37743886
o  https://stackoverflow.com/questions/37769451/arduino-make-a-library-more-optional-by-project?lq=1
o https://stackoverflow.com/questions/37824336/arduino-trinket-attiny85-usb-possible-to-read-the-state-of-all-keys
Anyway, optimized the source code (original not really a beauty), play with it and added also a fade-In/fade-out idle feature to the LED on PIN 1 and it blinks when turning the dial encoder.
I want to add add some more features to this knob, such as pushbuttons to change some internal modes. For example:

Toggle button for knob sensitivity (3-modes: slow (default), normal, fast)
A mute button

I want to that device 'remember' the state of the toggle button but there is no option (flash memory) to save the state. So I came with the idea to use a backup button cell to keep the device 'alive' when disconnected from USB (or computer turned off). A Button cell is 3V and USB is 5V so maybe is possible to 'test' the input voltage. If this is possible you can put the device in sleep mode (low power mode) directly after detecting USB connection lost and this voltage drop.
I have read already an article how to put the device into sleep mode (and awake from it):
o https://bigdanzblog.wordpress.com/2014/08/10/attiny85-wake-from-sleep-on-pin-state-change-code-example/
Question is:
Can I measure somehow the voltage is used to power the device? Any ideas (code example please if it is possible)?

The attiny85 does have a 512B EEPROM.

There are a few solutions.

If you want to save te state of your toggle button you can save it in the eeprom of your attiny85
You can use an ADC pin to check your VCC against the internal 1.1V reference
alternatively you can read the 1.1ref aganist Avcc. https://digistump.com/board/index.php?topic=1104.0


text:
Provide custom AVR dude commands through the Arduino IDE
Besides the standard upload button that burns the code using FTDI, I want to then be able to provide custom AVRDude commands for burning fuses, when the external programmer is used.
Is this possible to do from the IDE? Maybe if I can edit some configuration files?
The idea is to have the IDE supply the upload command when the standard upload option is selected, but when external programmer is selected, i want to have custom behavior.
The custom behavior that I want is to preserve the EEPROM and set the lock bit.
These two actions can be performed with the following AVRDude commands:
avrdude -c usbtiny -p m328p -U hfuse:w:0xd2:m
avrdude -c usbtiny -p m328p -U lock:w:0x00:m

The external programmer i use is Sparkfun's "Pocket AVR Programmer" which is an SPI programmer.
So can I have custom behavior (supported by AVRDude) when I select program using external programmer?
EDIT:
I opened file boards.txt and i found these specifications of interest:
pro.name=Arduino Pro or Pro Mini

pro.upload.tool=avrdude
pro.upload.protocol=arduino

pro.bootloader.tool=avrdude
pro.bootloader.unlock_bits=0x3F
pro.bootloader.lock_bits=0x0F

pro.build.board=AVR_PRO
pro.build.core=arduino
pro.build.variant=eightanaloginputs

and
## Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328P
## ---------------------------------------------------
pro.menu.cpu.8MHzatmega328=ATmega328P (3.3V, 8 MHz)

pro.menu.cpu.8MHzatmega328.upload.maximum_size=30720
pro.menu.cpu.8MHzatmega328.upload.maximum_data_size=2048
pro.menu.cpu.8MHzatmega328.upload.speed=57600

pro.menu.cpu.8MHzatmega328.bootloader.low_fuses=0xFF
pro.menu.cpu.8MHzatmega328.bootloader.high_fuses=0xDA
pro.menu.cpu.8MHzatmega328.bootloader.extended_fuses=0xFD
pro.menu.cpu.8MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex

pro.menu.cpu.8MHzatmega328.build.mcu=atmega328p
pro.menu.cpu.8MHzatmega328.build.f_cpu=8000000L

I am using Arduino Pro Mini.
In the second specification, there is the option for setting the fuse bits I want. However, there is no option for the lock bits.
The option for the lock bits are in the first specification - but there is no option for the fuses.
My new questions are these:

Should I specify the lock bits in the first specs and the fuses in the second? Will this work? I have to ask before trying anything stupid. Will the second specs "inherit" from the first specs?
Will the parameters I insert here only work for the Upload Using Programmer option? I want the regular upload (via bootloader) to work normally.
What happens if I ditch the Arduino platform and use a standalone AVR? If I use the same AVR that the Pro Mini platform had. Will the same settings work?

https://arduino.github.io/arduino-cli/0.27/platform-specification/#burn-bootloader or https://arduino.github.io/arduino-cli/0.27/platform-specification/#upload-using-an-external-programmer ?

Well, what i would like to be able to do is this: Preserve the EEPROM data, upload the program and then write the lock byte. There are three distinct AVRDude commands for performing these actions. I was wondering if i could modify the IDE, so that everytime you hit the upload button, it also preserves the EEPROM data and sets the lock byte.

I can't test it now, but you could add the fuse parameters to the tools.avrdude.program.pattern in platform.txt. Copy them from the tools.avrdude.erase.pattern. note: the fuse values are in boards.txt

So the tools.avrdude.program.pattern is what will happen when i program the arduino? And what are the contents of tools.avrdude.erase.pattern? What will the behaviour be after i copy them? I want three distinct steps (preserve EEPROM, upload, set lock bit). I updated the question with AVRDude commands, of what i am trying to achieve.

@Juraj I think I am getting closer. I edited the question. Could you please take a look at it? I have three sub-questions that are really quickly answered. Thank you very much!

those are not two specs in boards txt. all the pro.* keys values are applied, but some depend on the selection in CPU options in the Tools menu (like the fuses) while some are valid for all CPU options (lock bits)

@Juraj So if i use The Arduino Pro Mini, then it means i have to modify the first set for the lock bits, and the second set for the fuse values? Will this work? Also, does this work ONLY for the external programmer option?

you have to modify the tools.avrdude.program.pattern in platform.txt to add the parameter you want to be applied for "Upload with programmer". tools.avrdude.program.pattern is only for "Upload with programmer".

OK. These are its contents:tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} {program.verify} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i". Where and how exactly do i specify the lock bit and the fuses in there? I cannot find any reference on the internet, and the syntax is not obvious.

how is it not obvious? {cmd.path} is path to avrdude and those are parameters for avrdude, just the keys are not replaced with values. for pro mini it evaluates to avrdude -Cavrdude.conf -v -patmega328p -cusbtiny -Uflash:w:Blink.ino.hex:i

Thanks! Some parts are still not obvious. For example, how do I add a separator in the -U flag? I also want to pass hfuse:w:0xd2:m and lock:w:0x00:m. Finally, I should keep a copy of the original string, just in case I want to revert back to a normal operation. I mean, these are global settings, right?

as I already wrote, you can see the fuses parameters in  tools.avrdude.erase.pattern. you can copy from there

I know the fuse parameters, i have them in the question as well. I just don't know how to put them in the one liner on tools.avrdude.program.pattern. There are three parameters, fuses, lock bit and hex file. How do i separate them? What the correct command should be like?

and I say third time:  see the erase.pattern in platform.txt for the fuse parameters tools.avrdude.erase.pattern="{cmd.path}" "-C{config.path}" {erase.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -e -Ulock:w:{bootloader.unlock_bits}:m -Uefuse:w:{bootloader.extended_fuses}:m -Uhfuse:w:{bootloader.high_fuses}:m -Ulfuse:w:{bootloader.low_fuses}:m

You said:
you have to modify the tools.avrdude.program.pattern in platform.txt to add the parameter you want to be applied for "Upload with programmer".
The parameters i want applied are
-U hfuse:w:0xd2:m -U lock:w:0x00:m
The erase params is what you just posted. You say this string should go to tools.avrdude.pattern.
I searched for example, for bootloader.high_fuses. These are in boards.txt. The values i found were not what i wanted. I want hfuse:w:0xd2. Where do i set this value? This is what i am asking.

so for a test modify boards.txt. what I don't know is if avrdude will apply these fuse parameters

Just did a test. In boards.txt, in the Pro Mini section, I changed pro.bootloader.lock_bits=0x0F to pro.bootloader.lock_bits=0x00 but unfortunately it didn't work, as I was able to read the flash. I guess it is not doable from inside the IDE.

it worked https://forum.arduino.cc/t/arduino-cannot-set-lock-bits-and-fuses-from-ide/1034159

You can add the fuse parameters to the "Upload using programmer" command pattern tools.avrdude.program.pattern in platform.txt. Copy them from the tools.avrdude.erase.pattern. (The fuse values are from boards.txt)
the modified upload command pattern:

tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} {program.verify} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i" -Ulock:w:{bootloader.lock_bits}:m

Is there a way to get the IDE to reload this file? I edit it and it seems like I need to close and reopen the IDE to get my changes to apply...

@ldoogy, yes, it requires to restart the IDE


text:
Code flow execution between loop() and timer interrupts
My platform is the Arduino DUE.
I know that the timer counts up to a certain value, then generates an interrupt.
In the Arduino DUE, you can specify the timer value. In other words, you can specify the frequency of the intterupts. You can do this via the TC_SetRC(tc, channel, rc) function.
My question is how code flows in general.
Obvisouly the arduino runs the setup function first.
After that it jumps to loop.
But when does tghe timer starts counting down? When you first jump to loop?
Can you figure out how many instructions will be executed in the loop function, before a call to a timer interrupt is performed, for the given frequency you have specified?
After the interrupt is fired, all the code in the interrupt is run.
Then code flow jumps back to loop()?
And when the timer starts counting again? At the same time the code jumps to loop?
If you set up the timer interrupt frequnecy too high, do you run the risk of having code in you loop functin not run at all? (If, for example, you have lots of code inside the loop()).
In that case, would it be wise to put code that you would generally put inside the loop(), inside a timer interrupt?

The timers starts when it is enabled. Either explicitly or via one of The calls to timer functionality.
Once the interrupt fires, current execution is preserved and the isr execution starts. Once you exit the isr, the loop execution resumes from where it pauses
Yes, if your use fires too frequently or takes too long to execute your loop may never gets executed.

Thanks! I just saw that the timers never stop counting too! I add this here for reference


text:
Getting data from web form
I am using an EthernetServer and EthernetClient with Arduino in order to make a simple webpage. I have a web form for a user to enter various codes that can reset data stored on the back end. However, once I enter text into the web form once, it seems to be continually being included in the HTTP header after that. I have the URL: http://192.168.1.30, which becomes (and stays at) http://192.168.1.30/?data=5935 once I enter '5935'. My code is:
void loop() {

// Listen for incoming clients
client = server.available();
if (client) {

boolean currentLineIsBlank = true;
while (client.connected()) {
  if (client.available()) {
    char c = client.read();

    if(HTTPHeader.length() < 100) {
      HTTPHeader += c;
    }

    // if you've gotten to the end of the line (received a newline
    // character) and the line is blank, the http request has ended,
    // so you can send a reply
    if (c == '\n' && currentLineIsBlank) {

      // Calcuate weather parameters for serial and web
      calcWeather(); //Go calc all the various sensors

      // Send a standard http response header
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/html");
      client.println("Connection: close");  // the connection will be closed after completion of the response
      client.println("Refresh: 5");  // refresh the page automatically every 5 sec
      client.println();
      client.println("<!DOCTYPE HTML>");
      client.println("");

      client.println("
");
      client.println("");
      client.println("
");
      client.println("Web Server and Radio Receiver ");
      client.println("
");
      client.println("version November 14, 2016");
      client.println("
");
      client.println("");

      client.println("INSIDE");
      client.println("
");
      client.print("Temperature (F) = ");
      client.println(templm34);
      client.println("
");

      client.println("Transmission Errors: ");
      client.print("");
      client.print(numberReceived);
      client.println("
");

      client.println("Transmissions Received : ");
      client.print("");
      client.print(numberOfErrors);
      client.println("
");

      client.println("Transmission Error Rate: ");
      client.print("");
      client.print((numberReceived==0)?(0.0):(numberOfErrors/numberReceived));
      client.println("%
");

      client.println("
");
      client.println("
");
      client.println("
");
      client.println("
");

      // Display the table of illuminance values
      client.println("
");
      client.println("
");
      client.println("Illuminance	");
      client.println("Real World Light Value	");
      client.println("
");
      client.println("
");
      client.println("0	");
      client.println("Absolute Dark	");
      client.println("
");
      client.println("
");
      client.println("10	");
      client.println("Night	");
      client.println("
");
      client.println("
");
      client.println("100	");
      client.println("Dark Day	");
      client.println("
");
      client.println("
");
      client.println("1000	");
      client.println("Overcast	");
      client.println("
");
      client.println("
");
      client.println("
");

      client.println("
");
      client.println("<form action='/' method=get>");
      client.println("<input type=text name=data maxlength=4>");
      client.println("<input type=submit value=Submit>");
      client.println("</form>");

      client.println("");
      client.println("");

      break;

    }
    if (c == '\n') {
      // you're starting a new line
      currentLineIsBlank = true;
    } else if (c != '\r') {
      // you've gotten a character on the current line
      currentLineIsBlank = false;
    }
  }
}
}

// give the web browser time to receive the data
delay(1);
client.stop();
if (HTTPHeader.indexOf("5935") > 0) {
  resetData();
  Serial.print("Found!");
}
HTTPHeader = "";
}

"Found" is printed to the serial every time the page refreshes even though I have not actually pressed the submit button to submit it more than once. I've tried the temporary redirect, but the linux machine I need to use for this project already does a redirect so my redirect doesn't work. Is there a way to do this without a redirect?

(actually a duplicate of the question linked from that question, but the fool never accepted an answer on it so I can't link it as a duplicate - bit of a silly system this sometimes)

Link to linked question: http://arduino.stackexchange.com/questions/28124/webserver-on-arduino-refresh-issues

@Majenko I can't use a redirect because the server I am using already does a redirect and when I do mine I lose the webpage

Then you have a very inferior web server setup - I suggest you use a real one.


text:
Arduino Web Server: Receiving response from web form
I am using an Arduino Mega and I have a basic webpage built using EthernetServer for the connection and EthernetClient to write the HTML to the client. I have a simple web form:
client.println("<form method=get>");
client.println("<input type=text name=data>");
client.println("<input type=submit value=Submit>");
client.println("</form>");

I'd like to receive any input from the form and check it against values in order to do stuff on the back end (e.g. reset certain data). How do I get the data from the web page?

Your form method is set to GET. In this case, when Submit is clicked, the client/browser sends request with values in URI:
GET /index.html?data=user_value&default_name_of_button=Submit HTTP/1.1
...more lines to follow...

These HTTP header lines will be available on your EthernetClient instance, retrieve them line-by-line using connected(), available(), read() methods. Then parse the line, find the user_value.
Please note that browser retrieves your page (to display it) using GET method too, in that case URI will be like:
GET /index.html HTTP/1.1
...more lines to follow...

It is recommended to use POST method to submit form values. Example content section (before content, server must send HTTP header - check Arduino Web Server example)
<form method="POST" action="foo.php">

First Name: <input type="text" name="first_name" />

Last Name: <input type="text" name="last_name" />

<input type="submit" name="action" value="Submit" />

</form>

In this case the values are returned in content section:
POST /foo.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://localhost/test.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 43

first_name=John&last_name=Doe&action=Submit

Tutorial on HTTP headers:
https://code.tutsplus.com/tutorials/http-headers-for-dummies--net-8039