text:
Attiny85 appears to be drawing 0.2mA current but battery running down more quickly
I am trying to get a temperature sensor (tmp36) working with an Attiny and if possible I would like it to run for several weeks. I have tried to power down the Attiny and it appears to be drawing only 0.2mA current when asleep, and around 4mA when awake (using a multimeter). However the CR2032 battery went from 3.24V to 2.9V in about 1.5 days.  If it was really only using 0.2mA I would have thought it would go down much more slowly than this.
I wonder if it's using a lot of current every 8s when it turns on briefly and I'm not seeing this on the multimeter, or drawing a lot of current every hour when it reads the temperature or is there something else that I'm missing.
My circuit is an Attiny85 connected directly to a tmp36 temperature sensor.  I have a capacitor connected across the GND and Vcc of the tmp36.  Since I am using a surface mount tmp36 I also have the shutdown pin on the tmp36 pulled high (connected directly to Vcc). Otherwise there are no other connections, it's a very simple circuit and since the current normally appears to be 0.2mA I'm not sure why the battery voltage reading is going down so fast.
I am new to turning off the attiny(and still pretty new to arduino programming) and I copied most of the code for putting the arduino to sleep from here: https://folk.uio.no/jeanra/Microelectronics/ArduinoWatchdog.html
(and possibly other places).
The code I have is as follows:
#include <stdlib.h>
#include <EEPROM.h>
#include <SoftwareSerial.h>

#include <avr/sleep.h>    // Sleep Modes
#include <avr/power.h>    // Power management
#include <avr/wdt.h>      // Watchdog timer
#include <avr/interrupt.h> // Interrupts handling

// Definitions
#define rxPin 3
#define txPin 4

// 0 1 0 Internal 1.1V Voltage Reference, calling INTERNAL should set the            reference voltage to 1.1

SoftwareSerial mySerial(rxPin, txPin);

int currentTime = 0;
int timeLastSaveFullTemp = 0;

int nbr_remaining;
int sensorPin = 7; // This is the 7th pin on the ATtiny85,

                         // it is an analog input when reading as digital  call it 7? analogpintochannel function
                         // (On the HLT tutorial it is labelled as Pin2:  Analog input 1, SCK )

float temperature = -500.00f;     // Create a new float called temperature and give it the value -500 to start with
float prevTemp = -500.00f;
float tempDiff = -500.00f;

int tempAsInt = 0;
int tempDiffAsInt = 0;  // create int to store temperature difference between samples

signed char tempDiffAsChar; // create char to store temp difference between samples, hopefully this saves as a 1 byte no. between -128 and 127 (will store like this on EEPROM where difference is small enough since only 1 byte) (range around -128 to 128 so can't use for temp diff greater than 10 deg)
signed char warningNextDataIsTwoBytes = 111;

int eepromAddress = 0;       // initialize variable for position in eeprom to store data collected

int decideWhatToSaveFlag = 1;    // Decide what to save,  if this = 0 then save the temp difference as a char (1 byte), otherwise save the entire temperature as an integer.

// interrupt raised by the watchdog firing
// when the watchdog fires during sleep, this function will be executed
// remember that interrupts are disabled in ISR functions
ISR(WDT_vect)
{
        // not hanging, just waiting
        // reset the watchdog
        wdt_reset();
}

// function to configure the watchdog: let it sleep 8 seconds before firing
// when firing, configure it for resuming program execution
void configure_wdt(void)
{

  cli();                           // disable interrupts for changing the registers

  MCUSR = 0;                       // reset status register flags

                               // Put timer in interrupt-only mode:
  WDTCR |= 0b00011000;            // Set WDCE (5th from left) and WDE (4th from left) to enter config mode,
                               // using bitwise OR assignment (leaves other bits unchanged).
  WDTCR =  0b01000000 | 0b100001; // set WDIE: interrupt enabled, 8 seconds
                               // clr WDE: reset disabled
                               // and set delay interval (right side of bar) to 8 seconds

  sei();                           // re-enable interrupts

}

// Put arduino to sleep.
void sleep(int ncycles)
{
 nbr_remaining = ncycles; // defines how many cycles should sleep

  // Set sleep to full power down.  Only external interrupts or
  // the watchdog timer can wake the CPU!
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  // Turn off the ADC while asleep.
  power_adc_disable();

  while (nbr_remaining > 0){ // while some cycles left, sleep!

  // Enable sleep and enter sleep mode.
  sleep_mode();

  // CPU is now asleep and program execution completely halts!
  // Once awake, execution will resume at this point if the
  // watchdog is configured for resume rather than restart

  // When awake, disable sleep mode
  sleep_disable();

  // we have slept one time more
  nbr_remaining = nbr_remaining - 1;

  }

  // put everything on again
  power_all_enable();

 }

// the setup routine runs once when you press reset:
void setup() {
  analogReference(INTERNAL);    // This sets the internal ref to be 1.1V (or close to this), note that this makes 1.1V the highest voltage. The TMP36 gives 1.1V at around 55 or 60 deg so need to not put the chip in temperatures hotter than 55deg
  pinMode(sensorPin, INPUT);    // make pin 7 on the ATTiny an input pin

  delay(1000);

  configure_wdt();              // configure the watchdog

  mySerial.begin(9600);         // begin software serial at rate of 9600

}

// the loop routine runs over and over forever:
void loop() {

  sleep(450);                                                 // sleep for a given number of cycles (here, 450 * 8 seconds = 60mins) in lowest power mode

  currentTime = currentTime + 60;                             // add 60 min to current time

  if((eepromAddress<=510))                                    //  the eeprom still has space
  {

/***********Get temperature from sensor, then calculate difference since previous reading****************/

//Earlier set the reference voltage for the analog to digital converter to 1.1V.  This means a value of 1.1V will be read as the maximum (not sure if 1023 or 1024, but anyway)
//Note that this means an input greater than 1.1V from the temperature sensor (temperature about 55deg) is bad, not sure if it will damage the circuit or give bad readings but avoid.

temperature = analogRead(sensorPin)*1100.0/1024.0;  // read value on pin 7, between 0 and 1023 where 1023 is max, convert result back to a voltage in millivolts.
temperature = (temperature - 500)/ 10;              //Celcius temperature = [(analog voltage in mV) - 500] / 10
tempDiff = temperature - prevTemp;

/******* Change temperature diffence to integer and a signed char if it's between -2 and 2 deg ***********/
tempAsInt = int(round(temperature*10));  // multiply temp. by 10 then round and change to an integer type, this should give temp. as a three digit integer scaled by x10, e.g. 335 = 33.5deg, 120 = 12.0deg etc.
tempDiffAsInt = int (round(tempDiff*10));

// work out whether want to save complete temperature or just temp difference
if ((currentTime - timeLastSaveFullTemp) >=10)           // If the entire temperature hasn't been saved for more than 10 min, then want to save the entire temperature rather than just difference
{
  decideWhatToSaveFlag = 1;                               // Set flag to 1, since want to save entire temperature
  }
else
  decideWhatToSaveFlag = 0;                               // If the entire temperature has already been saved recently then set flag to zero since only want to save the difference.

if ((tempDiffAsInt>-20 and tempDiffAsInt<20)and (decideWhatToSaveFlag == 0))    // if temp change is less than 2 degrees and if the decideWhatToSaveFlag hasn't been previously set to 1 for another reason.
  tempDiffAsChar = (char)(tempDiffAsInt);

else decideWhatToSaveFlag = 1;                                                  // if the temp diff since prev sample is > 2 degrees or less than -2 degrees then set flag to 1 since want to save the entire temp. not just the difference

if (decideWhatToSaveFlag == 0)
  {
  //mySerial.print(" Temp diff");
  EEPROM.put(eepromAddress, tempDiffAsChar);
  eepromAddress = eepromAddress + sizeof(tempDiffAsChar);
  }

else
  {
  EEPROM.put(eepromAddress, warningNextDataIsTwoBytes);
  eepromAddress = eepromAddress + sizeof(warningNextDataIsTwoBytes);
  EEPROM.put(eepromAddress, tempAsInt);
  eepromAddress = eepromAddress + sizeof(tempAsInt);
  timeLastSaveFullTemp = currentTime;                       // Update time entire temperature was last saved to the current time.
  }

prevTemp = temperature; // copy temp to prev temp for next time.

}

}

Please excuse my coding I'm still learning.  I deleted my comments at the start of the program which explain why I'm changing the temp. to char etc. as they weren't really relevant to this question but if anyone wants them let me know.
Here is the circuit, a 3V battery is connected between Vcc and GND.  The capacitor is 0.1uF ceramic.  I am using the SOIC (surfacemount) type package of the tmp36, the (not) shutdown pin in the SOIC version needs to be pulled high so I have connected it to Vcc as specified in the datasheet (this pin doesn't exist in the TO92 through-hole version of the tmp36).

All help is greatly appreciated,
I'm also interested in suggestions for reducing the current further.  (Or for how to store more temperatures in a 512 byte EEPROM but that's less important than the battery)
Thanks very much!!
p.s. I have tested this code and it did save one temperature per hour as expected. (The section of code that saves temperature differences rather than temperature doesn't run when there is a 60 min gap between temperatures so all temperatures were saved to the eeprom as integers).

0.2mA is noise to most DMMs. What are you using to measure it?

I tried one $5 DMM and another slightly better one but brand Jaytech so not really particularly accurate probably, but I would have thought if the current was 1mA or more it would say so.  Unless it's oscillating up and down quickly or something.

Going to try changing the clock speed to 1MHz (from 8MHz) to see if that helps...

I uploaded your code to my Attiny85 (nothing connected to it) and got 0.2 mA current draw at 3V. That actually sounds far too high for sleeping, it should be more like 6µA rather than 200µA.

@IgnacioVazquez-Abrams Measurement error does not seem to apply in this particular case. Possibly other things in the (unposted) circuit are drawing more than expected.

I've just realized that was a silly thing to say, as I got that current draw myself, with nothing connected. So, code problem. :)

Using this calulator http://oregonembedded.com/batterycalc.htm you'd end up with around 42 days of run time. PS power_adc_disable doesn't actually do anything unless you've already disabled the ADC using ADCSRA &= ~_BV(ADEN);, as power_adc_disable only updates the PRR register.

2.9V doesn't sound too bad. See a datasheet for the CR2032 I found:

It looks like slightly more than 2.9V would be the expected voltage for up to 600 hours.
3.2V looks like it is fully charged, and won't stay at that level for long.
Having said that, 200 µA current sounds like a lot. You should be able to get it down to 6 µA. Perhaps post your schematic?

After a bit of experimenting I got the current draw down to the (expected) lower level of 4.25µA running at 3V, and 6.77µA running at 5V.
You had not in fact turned the ADC off. You need to change:
 // Turn off the ADC while asleep.
  power_adc_disable();

To:
  // Turn off the ADC while asleep.
  ADCSRA = 0;            // turn off ADC
  power_all_disable();

I can't comment on what extra draw, if any, your TMP36 will cause, however this should help get the overall current down.

Of course, you need to put the ADC back on afterwards, so this might be better:
  // Turn off the ADC while asleep.
  byte saved_ADCSRA = ADCSRA;
  ADCSRA = 0;            // turn off ADC
  power_all_disable();

  ... sleep here

  power_all_enable();
  ADCSRA = saved_ADCSRA;

oh, thanks!! This looks like the problem,  it looks like I need to test it for more than 1.5 days then.  I did notice it was already 3.14 after an hour or so. I will try testing it for a few days and then accept your answer assuming that was the problem (which it seems like it is).  I hope so :)  I just tried changing the frequency to 1MHz (from 8MHz) which lowered the ON current and sleep current remained about the same.  Will post circuit, I think perhaps I can turn off the tmp36 but haven't tried yet, was a bit worried it might not turn on again or something.

...also it's possible it's not using 0.2mA as I don't have a high accuracy multimeter.

I will set up a few circuits and run them for a week and see how long they last :), then get back to you, thanks again!!  (I need to wait until tomorrow to start, unfortunately all the shops which potentially sell batteries in the small town where I Iive at the moment have already closed for today).

p.s. thanks again, I also read your webpage about how to lower current draw a month or so ago and it really helped a lot, otherwise probably wouldn't have gotten this far even.

In my amended reply I show how to get the current draw down to 4.25µA (excluding whatever the TMP36 takes).

all the shops which potentially sell batteries in the small town where I Iive at the moment have already closed for today - your existing batteries should be fine. After all, you only ran them for 36 hours, and it should last 600 hours at 0.19 mA according to the datasheet.

I just tried changing the frequency to 1MHz (from 8MHz) which lowered the ON current and sleep current remained about the same - yes, well in power-down sleep mode the clock isn't running so it won't make any difference. The bad side-effect of a slower clock is it takes longer while it is awake (8 times as long in your case) which is something you don't want. You don't want it to be awake for longer than necessary.

Hi, thanks very much!! I will try the changes and get back to you, probably early next week or hopefully sooner.  I've found someone with a proper multimeter now and it was actually using about 0.2mA.I should be able to check it again once I've made the changes, hopefully in the next few days if they are at work.  I didn't want to keep using the same battery as I accidentally connected my attiny to the USB power supply on the computer and forgot to turn the switch connecting the battery off, the battery still works but it got very hot and I wouldn't completely trust any capacity results.

p.s. the tmp36 datasheet says 50uA so it should be ok even when turned on, if change the circuit and turn it on and off it should be 5uA.

Hi Nick, thank you very much, after adding your changes to turn the ADC off (and on again) it's now reading 30uA, not sure how accurate my multimeter is but it's certainly less than the 0.25mA it was reading before.  I imagine most of the current is from the temperature sensor so later I will probably try to turn the temperature sensor on and off with the microcontroller.  (Will put the frequency back to 8MHz later too.)

THIS IS NOT AN ANSWER; it's just a very long comment and I was not able to add all the formatting and ideas in the comment I was writing. Please don't consider it as a valid answer.
I leave all the low current topics to Nick, since he's doing a great work as usual. I wanted just to give you some ideas for the temperature acquisition and storing.
First of all, the floats. Forget them. floats are one of the worst things you can do to your poor microcontroller, unless you have an onboard FPU.
I haven't checked your sensor, so I assume that the calculations you performed were correct. (Note: voltages above 1.1V should not damage the board, but will not be detected - the value will cap at 1023)
So when you read number X (from 0 to 1023) you get the temperature by writing
((X * 1100 / 1024) - 500) / 10

You are using floats to do this. I don't like them at all, so let's switch to ints. Moreover you decided to store them with a 0.1°C precision, so that /10 is meaningless. So in the end
<integral type> finalTempInTenthsOfDegree = ((X * 1100 / 1024) - 500);

Now, the types. The value of the final temperature is between +60°C (corresponding to 1.1V) and -50°C (0V - not sure about this, but let's stick with these value). This means an integral value going from +600 to -500; the proper type is therefore int16_t (signed 2-bytes value). During your calculations, the X (which is a uint16_t) is multiplied by 1100; this value can rise up to 1125300 (when X = 1023), which does not fit a 2-bytes variable. You can reduce 1100/1024 to 275/256, but this does not solve the problem.
EDIT: As Edgar Bonet pointed out in the comments, the problem of having a 4 bytes is not solved with this trick, but dividing by 1024 is more "time consuming" than dividing by 256 (because the 10-bit shift involves shifting bits through bytes, while a 8-bit shift is just moving the bytes. His tests (avr-gcc 4.9.2, optimization for size -Os) show that a shift by 10 bits (=division by 10) is converted in a routine to shift one bit through all the four bytes and then this is repeated 10 times. This lead to 72 clock cycles. A 8-bit shift, on the other hand, was converted to a byte movement for three out of four bytes and the zeroing of the uppermost. So 4 clock cycles. So... Yes, this does not solve the problem, but can optimize the code; I'll think of this trick in my future projects. Of course this can be done in a much more optimized way, and the number of cycles required can change according to the way the operation is written and the optimization level, but it is worth remembering that if you shift by a multiple of 8 bits (on an 8-bit machine) it is more optimized than another arbitrary value.
In any case, even with either of the two values, a 4-bytes int is required. In order to reduce unnecessary overhead, let's switch it back to a 2-bytes whenever possible. Something like
int16_t finalTemp = ((int16_t)((((uint32_t)X) * 1100U) / 1024) - 500;

So the operation order is

Take the X value
Promote it to a unsigned 32 bit variable
Multiplicate by 1100 (values from 1125300 to 0)
Divide it by 1024 (values from 1098 to 0)
Cast it back to a signed 16 bit value
subtract 500 (values from 598 to -500)

Now, the storage. If you store the values as they are, you will get 256 measurements, which at one measurement per hour mean something like 10 days.
One easy way to increase this space is noticing that you are using only 11 bytes out of 16. So you can compact it and get 372 measurements (around 15 days)
The trick you used (ten measurements with just the difference) is ok only if you guarantee that in ten hours the value will not drift by more than +/- 12°C.  This is not guaranteed and probably also not optimal. I'd prefer another approach, which is based on the fact that you are using only 11 bytes out of 16. You can have two different data stored in the EEPROM, which are differences (1 byte) or whole temperatures (2 bytes). You will distinguish them with the first bits: a 0 denotes a difference, a 1 a whole temperature (followed by 0 is the low byte, by a 1 is a high byte). This means that for the difference you have seven bits, so it can range from +63 to -64. Whenever you reach a difference from the previous temperature within 6 degrees you don't save anymore the whole temperature. The code to do this is for instance the following one:
// int16_t finalTemp calculated before
// int16_t prevTemp initialised, at beginning, for instance to -32000, so the difference is greater and you force a full writing at the first round

int16_t tempDiff = finalTemp - prevTemp;
prevTemp = finalTemp; // update the temperature

if ((tempDiff <= -63) || (tempDiff >= 63)
{
    // In this case we want to save the whole integer
    EEPROM.update(eepromAddress++, (((uint8_t)finalTemp) & 0x3F) | 0x80); // Write the lowest 6 bits, and set the first two to 0b10
    EEPROM.update(eepromAddress++, (((uint8_t)(finalTemp >> 6)) & 0x3F)| 0xC0); // Write the highest 6 bits, and set the first two to 0b11
}
else
{
    // In this case we save only the difference
    EEPROM.update(eepromAddress++, ((uint8_t)tempDiff) & 0x7F); // Just remove the highest bit, and store it
}

In this case, provided that the temperature does not vary a lot, you will get 511 measurements, which is like 21 days. For each variation greater than 6°C/h you will lose one hour of measurement, down to 256 measurements. Please note that I wrote EEPROM.update instead of write, even if this is not necessary (just one of the things I do every time).
The last possibility is to switch to a 0.5°C resolution. If you use this resolution, you can map your values on a range 120/-100, thus being able to use only one byte for each measurement. Since the accuracy is +/- 2°C, you can also choose this without problems.
Apart from the storage, if you record only 256 bytes of information how do you know which are the correct values and which are the previous ones? My suggestion is to reserve one value (for instance if you have used my code you can get an impossible value such as 0x40 - which if I'm not wrong maps to DIFFERENCE -64, which is impossible since the difference is stored only when greater than -63) and fill the memory before starting to insert the values. beware that if you do it then turning on the board will reset the memory...
One last suggestion: you have a sensor which stores the data internally, but.. How do you get them out of it? My personal suggestion is to have a dedicated pin (for instance PB3) tied to a jumper. If it is open then you will proceed with the normal program, otherwise you wait for a download request. (don't do the opposite since the jumper inserted drains the battery). Consequently the code can be something like this:
const uint8_t invalidEepromValue = 0x40;
const int16_t maxAddress = 510; // Not equal to 512 to avoid a last reading of 2 bytes

void dumpMemory()
{
    int16_t prevTemp = 0;
    for (int16_t i = 0; i < maxAddress; i++)
    {
        int16_t value = EEPROM.read(i);
        if (value == invalidEepromValue)
            break; // Finished the reading

        if (value & 0x80)
        { // WholeData
            int16_t value2 = EEPROM.read(i+1);
            if (((((uint8_t)value) & 0xC0) != 0x80) || ((((uint8_t)value2) & 0xC0) != 0xC0))
            {
                mySerial.print("Error with memory cell ");
                mySerial.println(i);
                continue;
            }

            prevTemp = (value & 0x3F) | ((value2 & 0x3F) << 6);
            if (value2 & 0x40) prevTemp |= 0xF000; // Extend the sign

            mySerial.println(prevTemp);
            i++; // skip the next value (already analysed)
        }
        else
        { // Difference
            if (value & 0x40) value |= 0xFF80; // Extend the sign

            prevTemp += value;
            mySerial.println(prevTemp);
        }
    }
}

void setup() {
    pinMode(modePin, INPUT_PULLUP);
    mySerial.begin(9600);         // begin software serial at rate of 9600

    delay(1);
    if (digitalRead(modePin) == LOW)
    { // Enter read mode
        while (1) // loop forever
        {
            while (mySerial.available() == 0); // Wait for some chars

            dumpMemory();

            while (mySerial.available() > 0)
                mySerial.read(); // Flush receiving buffer
        }
    }

    // Clear the memory
    for (int16_t i = 0; i <= maxAddress; i++) // Equal to cover the last reading of 2 bytes
        EEPROM.update(i, invalidEepromValue); // Here update is almost mandatory

    // Go on with the initialization you already implemented
    ...
}

I hope that the software serial works even without the main structure (so in a while(1) in the setup).
Please keep in mind that all the code written here has NOT been tested, so it may require some corrections

You wrote: “You can reduce 1100/1024 to 275/256, but this does not solve the problem.” It may not solve the problem, but it can be used as an optimization. Dividing an unsigned number by 256 is almost free, as it only involves moving bytes. Dividing by 1024, on the other hand, requires extra shift instructions.

Thank you very much, I really appreciate the time taken to help.  I will have a look at the current first and once that's working have a look at this.  Actually my problem is a bit bigger than 1 point per hour. I plan to measure skin temperature of bats and ideally it would be good to have one temperature per 10 minutes for 10 days or longer.  Since with 512 bytes I'm not sure if that's possible I'm thinking what would be best, I really only need to know if the bats lower their body temperature (use torpor) so perhaps I will do one point per hour and then....

increase the frequency to 10 minutes if the temperature changes.  Though of course any time I change the frequency I also need to record the time so I can work out at what time each temperature was recorded.  Overall therefore a better option might be to put up with a lower sample rate such as one point per half hour. It could be enough, I will have to test it and see which one is best for the information I'm trying to record.

Anyway, thank you very much, I will definitely look at this properly and probably use it, have upvoted it.  Sure it will also be useful to anyone else doing similar things. Thanks also about the float comments, good point, I don't really need them at all!

@EdgarBonet Seems reasonable; did you ever test if the compiler is this smart? I cannot test it these days, but it would be useful to check the actual generated code. In any case thank you for your contribution :)

I just gave it a try with avr-gcc 4.9.2 at -Os. The division by 1024 compiles to a loop of 10 iterations, each shifting the 4 bytes of the number one by one. With the loop overhead, the total execution time is 72 CPU cycles. The division by 256 compiles to an instruction that clears one byte, and three register moves. Total execution time is 4 CPU cycles. Both codes are sub-optimal. By reassigning registers, the division by 1024 could be done in 6 cycles and the division by 256 in 0 cycles.

@EdgarBonet Impressive as usual! Thank you. If you agree, I'll add these info in the answer not to lose them

Yes, sure, I'll be glad if you do so!

@EdgarBonet Done. Thank you for your idea and tests :)


text:
How to externally power HC-05 module with Arduino Pro Mini?
guys, I am new to arduino. I am trying to power my HC-05 (5v with regulator to 3.3v) from Arduino Pro Mini 3.3v but I can't get it to power on.
There is a problem: The site I bought HC-05 from says that it needs 3.3-6 volts to power on but the back of HC-05 shows only 5v pin. To confirm that it runs only on 5v I need to connect it to external 5v supply.
But how do I make the connection? What do I connect to negative of the battery if I choose to externally power it?
Second Problem: If my HC-05 turns out to need only 3.3v input voltage, how many coins cells do I connect in series to power both pro mini and HC-05 module.
I am using a coin cell (3.3v) for powering the pro mini.
Thanks...

If you can't figure out the battery connection (it goes to ground) then I doubt that you connected the module correctly in the first place. Have a look at this question ( https://electronics.stackexchange.com/questions/280500/why-do-you-have-to-use-a-voltage-divider-with-hc-05-bluetooth-module-arduino ) to make sure you got the wiring correctly. And as far as I know a coin cell usually is 3.3 V, so if you don't specify what cells you have it's hard to tell. edit: if 5 V is printed on it I would trust that over the vendor specs. I found images of HC-05 modules that have 3.6 - 6 printed.

5V is within the valid range of 3.3V to 6V. What makes you assume that it only works on 5V?

@sa_leinad Who do you mean? I meant that I found modules that have 3.6 to 6 V printed on them. If his module has 5 V printed on it I would suspect it needs 5 V and not the range, since they could have printed 3.3 V to  6 V then.. I don't know these modules so I don't know if all work with 3.3V, but I also mentioned that wiring needs checking. If it works with 3.3 V and OP did everything correctly it should have worked when powering with 3.3 V.

@idkfa I have a regulator in my HC - 05 which levels it to 3.3v. Should I still use a voltage divider?                                                                                You are probably right about that I should trust what is printed on the board and consider my HC-05 to be 5v input and a regulator to 3.3v (which is mentioned as level 3.3v on the board).                                                    If I don't require a voltage divider? Where do I connect the negative of the power supply?

As I mentioned I don't know the module. I'm sure if you read the link / do some further research you can find out if you need a voltage divider or not. I would have to read that myself, too. As I already wrote: it goes to ground. @chrisl wrote in his answer "In this case be sure to connect the grounds of both power supplies, so that they have a common ground."

@idkfa I was actually speaking to Hardik Sharma with my comment. Sorry for the confusion.

The HC-05 (the PCB that is mounted on the PCB of the module) itself runs on 3.3V. Many microcontrollers run on 5V, so people are selling the HC-05 mounted on a PCB with extra components, for example a voltage regulator from 5V to 3.3V.
Voltage regulators have a minimum input voltage for which they can hold the output voltage at the specified value. Refer to this question for more information about this. So supplying the module with 3.3V instead of 5V will result in a supply voltage for the HC-05, that is significantly lower than 3.3V, so it most likely won't work correctly.
If you want to use the HC-05 module as it is, you have to provide 5V supply voltage from another source. In this case be sure to connect the grounds of both power supplies, so that they have a common ground.
If you don't want to use an extra power supply, than you may bridge the voltage regulator on your modules PCB and provide the 3.3V as supply voltage, that are used by the Arduino. Doing so would not be an easy task for a beginner, since you would have to solder small SMD components. Also the outlay of the modules PCBs are very different (depending on manufacturer). Note that in this case you should never ever put 5V on the Vcc pin of the module again, since it is then directly passed on to the HC-05 chip, which would be destroyed from the 5V supply.

I don't want to use a divider so I should connect the negative of the battery to GND on the pro mini. RIGHT?

Yes, negative battery pin to ground of HC-05 and to ground oft arduino. Positive battery pin only to HC-05. This way the current for HC-05 only comes from the battery, but the HC-05 can also evaluate digital signal Form arduino, since they have a common ground

source: Stack Exchange

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

sort: votes


text:
How to install several IDE version on my PC
How can i install old version of IDE, without uninstalling the other version?(How can i install several IDE version in same laptop).

Avoid asking multiple questions, https://arduino.stackexchange.com/help/how-to-ask and what research have you done?

Arduino.cc have a guide :
https://www.arduino.cc/en/Guide/PortableIDE
The gist is:

Download the desired version in ZIP format
Unpack the content in the zip file to a folder
Start the arduino.exe in that folder.

Remember that you have to place all libraries, board definitions in that folder.
The folder can be copied to another computer or a USB stick....

Note that it's not required to run in portable mode. If you want each IDE installation to be isolated then that's the thing to do but if you want them to share preferences and hardware packages installed via Boards Manager then you should not use portable mode.

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


text:
Semantics of local PROGMEM
I want to create a class to better use strings in flash. At its core is the following
template<size_t N>
struct progstr
{
    constexpr progstr(const char (&str)[N])
        : progstr(str, make_index_sequence<N> {}) {}

    template<size_t... Is>
    constexpr progstr(const char (&str)[N], index_sequence<Is...>)
        : _str{str[Is]...} {}

    constexpr operator const char*() const {
        return _str;
    }

    const char _str[N] PROGMEM;
};

Where make_index_sequence and index_sequence are the same as those from <utility>.
The problem arises when I try to emulate PSTR
template<size_t N>
constexpr const char* pstr(const char (&str)[N])
{
    return progstr<N>{str};  // huh?
}

It even compiles. However

The returned pointer is "dangling", but it is pointing into flash memory. Will this work?
A constexpr function may be called with an array with runtime values, and that cannot possibly create the string in flash can it?

the operator keyword is missing in () operator

I tested with 100 chars string
const char*
Sketch uses 1566 bytes
Global variables use 288 bytes

with F macro
Sketch uses 1594 bytes
Global variables use 188 bytes

progstr <101> ps(...
Sketch uses 1618 bytes
Global variables use 288 bytes

const char* ps = pstr("...
Sketch uses 1502 bytes
Global variables use 188 bytes

the pstr version string has errors at the end, when printed.
sorry, the pstr function works only if previous sketch version put the string into flash memory. it is not in hex file.


text:
Follow redirect of a captive portal with NodeMCU 0.9
What am I doing?
Trying to connect to a free wifi with a Nodemcu 0.9.
What I have already done?
Connecting and loading a test page in order to be redirected to the login page
Connection code:
 const char* ssid = "polimi";

  Serial.println("Attempting to connect");
  WiFi.begin(ssid);
  //Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

Detection of captive portal
  String host = "clients3.google.com";
  String site = "/generate_204";

  Serial.print("Connecting to ");
  Serial.println(host);

  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  // We now create a URI for the request
  Serial.print("Requesting URL: ");
  Serial.println(site);

  client.print(String("GET ") + site + " HTTP/1.1\r\n" +
    "Host: " + host + "\r\n" +
    "Connection: close\r\n\r\n");
  delay(500);

  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  Serial.println("");

  Serial.println("###Connection closed###");

What am I obtaining?
Nothing, but I wanted to obtain the html strings of the captive portal
What I'd Like
Find a way to follow the redirect and finally send a POST with my credential.

nothing? it connects to wifi? it connects to server? maybe it takes longer then 500 ms until the response arrives

@Juraj For sure it connects to the wifi then print the "requesting url..." and "###connection close ###". Absolutely no redirect. Client. Readstring does nothing

your way of waiting for the response with delay is wrong. see some WiFiClient example

@Juraj Can you show me where to find interesting example? This is what I've found on internet. I suppose I'm waiting using: while(client.available()). If I am writing here is because I don't understand where's the error

now I see that the esp8266 library has not so good example. try to adopt AVR WiFi Shield library example or this example https://github.com/jandrassy/UnoWiFiDevEdSerial1/blob/master/examples/WiFiLinkWebClient/WiFiLinkWebClient.ino

use the httpclient instead of the low-level stuff to make it easier on yourself.

@dandavis Is there any working httpclient?

So far I was able to import RestClient.h that allows me to send a POST request, now it will be quite hard to read a possible redirect

there's a few built-in "ESP8266HttpClient" example, which use a high-level interface.


text:
bluetooth module and pic
I am currently working on a project that requires bluetooth module and pic. I need to get the ID or address of the connected device.Any idea how can i do it. I only know that this is done using AT commands.

Which bluetooth module are you using? Can you show us the sketch you used to try and get the address?

i am using HC-05 module.I am connecting this module with my phone and want to access my phone's ID or address.

Please edit your question and show us the sketch you are using.


text:
How to set the sampling frequency in Arduino without using a delay
I am reading an ECG signal using a single lead heart rate monitor. What I know is that when I use delay(15) it means that I am getting 66.67 readings in a second which corresponds to the sampling frequency. I want to set the sampling frequency to 250. This can be done by introducing delay(4).
What I really need is to set the sampling frequency to 250 Hz without introducing a delay in the code because I am acquiring ECG data in real time. Also, I am sending the data to python for processing and the delay will affect the sampling frequency in the time domain analysis.
any detailed solution or code ??
PS. I am using Arduino UNO
Code:
#define SERIAL_BUFFER_SIZE 8192
#include <SoftwareSerial.h>
unsigned long Time;
void setup() {

  // initialize the serial communication:

  pinMode(10, INPUT); // Setup for leads off detection LO +
  pinMode(11, INPUT); // Setup for leads off detection LO -
  Serial.println("CLEARDATA"); //clears up

  Serial.println("RESETTIMER"); //resets timer to 0

  Serial.begin(115200);

}

void loop() {
  if((digitalRead(10) == 1)||(digitalRead(11) == 1)){
   Serial.println('!');
  //  continue;
  }
  else{
   /*
     // send the value of analog input 0:
     int idata = analogRead(A0);
  //  float data = (idata*3.3)/1023;
      Serial.println(idata);
*/
  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (3.3/1023.0);
  Serial.println(voltage);
  }
  //Wait for a bit
    delay(4);
}

You could also use a hardware timer to do this. E.g. use Timer1 to interrupt your code 250 times per second and take ADC measurement there. Also be aware of the ADCs conversion time, which can take about 100 us to execute. (Code see e.g. https://github.com/PaulStoffregen/TimerOne/blob/master/examples/Interrupt/Interrupt.pde)

There are many options, which have varying degrees of accuracy and complexity. The right one for you depends on how much timing accuracy you require. See Getting a fixed sampling rate, which your question is almost a duplicate of.

Use the concept of blink without delay.
Instead of using delay() to set the timeout you use a timestamp and check micros() against that to see whether your interval has passed:
const unsigned long READ_PERIOD = 4000;  // 4000 us: 250 Hz

void loop() {
    static unsigned long lastRead;
    if (micros() - lastRead >= READ_PERIOD) {
        lastRead += READ_PERIOD;
        if (digitalRead(10) == 1 || digitalRead(11) == 1)
            Serial.println('!');
        else
            Serial.println(analogRead(A0) * (3.3/1024));
    }
}

I took the liberty to do a few edits: use micros() instead of millis(), as the latter has 1 ms of jitter; write lastRead += READ_PERIOD instead of lastRead = now to prevent creeping drift; a few simplifications.

Thanks for your answer. I have tried the code, however, it gave sampling frequency 125 Hz. I tried playing with the READ_PERIOD and I found that 2000 gave sampling frequency of 250 Hz. What does this number stand for and what concept or equation is being used ?   Many thanks !!

(1000000 / 4000) == 250  If 2000 works your timing is off.

@dandavis  can you please specify the units of the baud rate and the reading period. it is  (bps / us  = hz) ??    Thanks


text:
Arduino UNO SPI Serial Clock (Pin 13 SCK) gives no output, but Blink Example (Pin 13 LED) works
I was attempting to use an SPI library and DAC device (Library AD57X4) for the first time, when I realized that the Arduino UNO Pin 13 was not outputting a clock signal (something I expected it to do).
Using a serial analyzer I can sample at 16MHz, yet nothing comes out of UNO Pin 13 except maybe a very occasional noise blip.  After no luck with the AD57X4 library, I wrote this simple program to try to get SPI clock signal on UNO Pin 13.  Setting UNO Pin 13 to OUTPUT makes no difference.
#include <SPI.h>

void setup() {
  //pinMode(13, OUTPUT);
  SPI.begin();

}

void loop() {
  SPI.transfer(0x00);
}

I do get a signal on UNO Pin 11 (MOSI), frequency 381 kHz.  This signal is due to SPI.transfer(0x00); , as it disappears when the line is removed.  Although likely irrelevant to the question, I noticed some periodic 6us gaps every ~1ms on this UNO Pin 11 (MOSI) signal.

The Blink Example Works:
    // the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

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

I tried monitoring UNO ICSP header pin 3 (SCK), however there is no signal for either the SPI or Blink programs.

UPDATE:
I switched over to an Arduino NANO that I had around and was able to get this output.  I expected the clock to be high frequency and continuous for SPI.  The MOSI output is the same 381 kHz that I observed earlier.

#include <SPI.h>

void setup() {
  pinMode(13, OUTPUT);
  SPI.begin();

}

void loop() {
  SPI.transfer(0x00);
}

EDIT:
Here is a schematic of my circuit.  I am using an EVAL-AD5754R Evaluation Board from Analog Devices.  Here is a link to the AD5754 chip data sheet.  I'm providing 5V power through the J7 terminal (via the UNO), and supplying the SPI connections through the J8 header. The EVAL-AD5754R board works perfectly via USB and their software, but now I am transitioning to controlling it through Arduino/SPI.  As you can see I'm temporarily using a 12V battery for the analog voltage supply - this is until I build a regulated circuit.  J8 DGND pins are shown unconnected on the schematic below, but I've tried connecting one of them to the UNO's GND to no effect.

This is the configuration of the linkers which act to configure the eval board:

This is an annotated table describing J8 header connections (UNO <-> EVAL-AD5754R):

Can you post your schematic? And the exact part number (and preferably a link to the datasheet) of your DAC device.

@NickGammon I am using EVAL-AD5754R from Analog Devices.  I edited the question to include a schematic of the UNO and the configuration of the DAC board.

set pin 10 as output in test sketch, to prevent uno to fall into slave role with the SPI library

I can't reproduce that. Using your first test code:
#include <SPI.h>

void setup() {
  //pinMode(13, OUTPUT);
  SPI.begin();

}

void loop() {
  SPI.transfer(0x00);
}

I get this on the logic analyzer:

Also on my scope on pin 13:

As expected, a 4 MHz signal with gaps between the bytes.

I expected the clock to be high frequency and continuous for SPI.

No, you get the clock when data is being transmitted and not at other times.

Although likely irrelevant to the question, I noticed some periodic 6us gaps every ~1ms on this UNO Pin 10 (MOSI) signal.

That would be the Timer 0 interrupt kicking in (roughly every 1 ms) and thus interrupting your looping code for a few microseconds.

Possible solution
Try enabling slave select (write LOW to pin 10). I think some versions of the logic analyzer ignore incoming data if the slave isn't selected.
In fact, pin 10 should be an output, otherwise the SPI hardware goes into slave mode. Some versions of the library might not set it to output.

I'm going to try this tomorrow. I was able to draw a schematic of my circuit above.

I was able to get the clock signals now as expected. Library still not working for me (a separate question), but at least I can now see the signals on the SPI!  Thanks


text:
Control/Interacting with Android OS using Arduino board
I am new to arduino, and based on my search, it is possible to connect Android devices and Arduino board thru bluetooth module. But most solutions i found are either for controlling Arduino board using an Android app, or controlling Android app using Arduino board.
My question is, is there a way to control/interact with the Android OS on the phone using Arduino, thru whatever connection?
I am asking this because I am thinking of building a portable keyboard or touchscreen device for Android devices, and want to see if Arduino is a good platform for prototype.

What do you mean "thru whatever connection"?

Whatever = TCP/IP?

@gre_gor so can be bluetooth, usb, wifi, wifi direct, etc.

@MatsK that can work, but i guess it is part of wifi or cellular connection?

There is wifi and cellular add-ons to Arduino that can have a TCP/IP stack and thereby you can have a program that is agnostic to what coimmunication layer you have.

What you've seen is most usually a bluetooth module which has a "virtual COM port" service -- you connect to the bluetooth module and you can then send a data stream up and down through this COM port, just like you are able to do with a normal Serial port.
If you want a bluetooth keyboard:
What you want for seamless integration is a bluetooth module which natively exposes a "HID" (Human Interface Device) profile. Keyboard, mice and gamepads are examples of an HID.
There is a multitude of projects which use Arduino + Bluetooth HID module:

http://www.kobakant.at/DIY/?p=3310 uses an Arduino Pro Mini and and BlueSMiRF HID (from Sparkfun)
Evan Kale's video: https://www.youtube.com/watch?v=BBqsVKMYz1I (uses HC05 bluetooth module with altered firmware)
https://mitxela.com/projects/bluetooth_hid_gamepad
Bluefruit EZ-Key: https://www.adafruit.com/product/1535

When you are a beginner you should buy the more expensive modules which don't require you to do any firmware hacking. Adafruit's product might work for you. As the description page says, you can connect a microcontroller's UART TX to the modules RX pin to send arbitrary keystrokes. You can then add a keyboard matrix, or lots of buttons, or whatever you desire to that microcontroller to make it trigger the keypresses you want.
This should get you started on your own research.

super detailed thanks! what about touchscreen device, is that considered as HID too?

I have never seen remote touchscreens or displays on Android. I am not sure if it is possible to connect a new screen to an Android wirelessly.


text:
Need assistance with serial data between PC and Arduino Mega 2560
With help from a friend I have written a sketch for my Mega2560 that talks to a PC application via serial at 9600 baud.  The PC application send an S which instructs the mega to send variable values without any delimiters.  The PC application then creates a string from the data which is split to fill text boxes.  Some elements of these text boxes can then be changed and clicking a button makes the PC application build a string, prefixed by R# and using <> as delimiters.  It then tags an S on the end.  This string is then sent to the Mega, which as it detects the R and # reads the delimited data into a 43 element array. Once it reads the S it then runs the send function again to confirm the changes.
As a stand alone program this works -
I then added in functions for reading four Ds18B20's, four DHT11's an RTC and displaying this on a TFT.  These routines were added as separate contained voids and called in order from the main loop.  When testing the serial it nolonger works.  I either have to click on the get data button multiple times for it to read and display the info.  Sending updated information back gets lost in transit (I've used a com port sniffer and it shows data passing out to the mega).  Lastly, it's no longer accepting the updates when it does work - and having sent data back a second time it still reads the same as before the values were changed.  When the coms fails the mega seems to have locked up, so it's stuck in the comms section, presumably as one of the IF/Then conditions hasn't been met because it's run out of data.  But the routine wasn't changed from the standalone code which worked fine.
Hopefully this is as concise as you need but still has enough information to help diagnose the possible issue.  I've tried extending delays in the PC application to see if it was that which was the cause, but even setting them to 5 seconds it still errors as described
Thanks
Malcolm
Main loop from working standalone code
void loop ()
 {

loopcount = 0;

// Serial.println ("in main loop ");   // to show then program is looping the main code
// delay(3000);

 // your other 5seconds of code etc

 if(Serial.available()){             // test is S or R on comms

 int tbyte = Serial.read();

 if (tbyte == 'S'){
//  Serial.println ("send data");      // S received so Send data
  transmit ();
//   sendarray ();
   }

  if (tbyte == 'R'){                 // R received  so readstream of data
//    Serial.println ("recive data");
   readstream ();
    }
  }
 // sendarray ();
 }

 // end of main loop

Subroutines from the standalone code
// Subroutines --------------------------------------------------

 void readstream ()  {

  while (loopcount < 2000){
    if(Serial.available() > 0){

if  (serialFlag == 0) {

   inByte = Serial.read();

  if (inByte == 0X23 ){
    serialFlag = 1;
//    Serial.println ("# receieved so delimited data follows  ");
  }
}

  if  (serialFlag == 1) {
   processInput ();
    }
   }
  }
 }

// ProcessNumber-----------------

void processNumber (const long n)
 {
// Serial.println (n);

 dataIn[i]  = n;

 //Serial.println (i);
// Serial.print (dataIn[i]);

 i++;

// Serial.println (i);

 if ( i >= 43) {
//  Serial.println (" end of data....... return to main loop");
  serialFlag = 0;     // set flag back to zero
  i = 0;

 loopcount = 2222;   // stops the Serial While Loop, though better replaced by a timer
 }
 sendarray ();
 }

 // End of ProcessNumber-----------

 // ProcessInput--------------------

void processInput ()
 {
 static long receivedNumber = 0;
 static boolean negative = false;

 byte c = Serial.read ();

 switch (c)
   {

   case endOfNumberDelimiter:
     if (negative)
       processNumber (- receivedNumber);
     else
       processNumber (receivedNumber);

   // fall through to start a new number
   case startOfNumberDelimiter:
     receivedNumber = 0;
     negative = false;
     break;

   case '0' ... '9':
     receivedNumber *= 10;
     receivedNumber += c - '0';
     break;

   case '-':
     negative = true;
     break;

   } // end of switch
 }

 // End of ProcessInput------------------

And the input to array
void sendarray ()
{
daytemp1 = (dataIn[0]);
daytemp1=daytemp1/10;
daytemp2 = (dataIn[1]);
daytemp2=daytemp2/10;
daytemp3 = (dataIn[2]);
daytemp3=daytemp3/10;
daytemp4 = (dataIn[3]);
daytemp4=daytemp4/10;

<snip>

reduce the code to minimum required to demonstrate the error that you are getting .... remove all the useless fluff in the code and reduce it to receiving and recognizing the Q and S ... once recognized, have the code indicate which of the two was recognized .... do not do anything else until that part works

When you contacted me elsewhere you gave the impression your problem was simply how to convert incoming serial data into a variable rather than printing it. Please confine your question to this. In particular you need a Minimal, Complete, and Verifiable Example (MCVE).

But if I copy and paste the code into my code it keeps failing. Most often it fails to compile with error messages that might as well be in Klingon - maybe, but we can understand error messages. Please post them.

Please read How do I ask a good question?.

@MalcC - Is it possible to expand on what the timing issue was with the PC a bit more, if you think its something others might benefit from in the future.  (I think you should post an answer to this if you can)

@CodeGorilla not a problem.  My friend informed me that the code on the mega was taking around 4-5 seconds to complete the loop, so I added a 500ms delay between sending the R and the # in the PC application, and then added a 5 second delay after the string had been sent to the mega before the PC application sent the request to the Mega to receive data to confirm the values had been updated.  This prevents the PC application reading the buffer mid loop when the mega hadn't sent data to the com port

Prior I had used a PIC18F4620 running at 40 Mhz and didn't need such delays - maybe PICs handle communications differently, because on both projects the com port speed is set to 9600 baud, so data transmission is the same.

I'm sorry, I know you are new, but this is not a very easy to understand question, please keep reading though, I am trying to help.  Your description of what you want your code to do is like trying to eat a dinner plate.  Remember no one reading this has the knowledge of the problem that you do and a diagram or three speak a million words.
If it is failing to compile you need to post the source code and the compilation error.  Without that information there is no point posting the question.  The information on what is wrong is there, unfortunately you haven't used Google's Klingon to English translator.  Seriously paste the compile errors into Google and you will get a stack of results, some of which will tell you what you have done wrong.
Your friend's code is not great.  If that really is the code (rather than a space enforced edit), then I suspect it won't compile either, because its not valid C++.  Also there are logic errors in it, you can make a number negative, but once you have you can't go positive.
So, what can you do about it?
Rule 1: You have to learn how to walk before running around the globe.  Part of your requirement is to read Q or S from the serial line.  So write a program of YOU OWN that does just that (I mean don't copy one of a web site/friend).

Write a program that reads the serial line.
When you press Q it prints "You pressed Q!"
When you press S it prints "You pressed S!"
When you press any other key it prints "You pressed something else"
What happens when you press s or q?

Then build up step by step, keep back ups of everything, because you will break it at some point.
Other rules, which will contradict rule 1, will be available once you have mastered number one :)
Good luck and if you get stuck again, please post here again
 (small example code + error messages + output + expectations) = good post

How do I reply to a reply... other than hit the answer button, I have an update, but still have an issue - sorry for posting loads of info in previous post - Can't win as most forums ask for the full code and detailed explanation rather than just the bit where an error occurs

You can edit your question to clarify it. We don't want snippets of code, however your private email to me said I'm looking for a means of taking the numbers between the two delimiters and placing them into variables.. That sounds simple enough. Your posted question far exceeds that problem.

OK - I'll edit the original post

Problem resolved  by increasing delay in the PC application - please close / delete this post

@MalcC - I would keep open, because it makes a good point that  the Arduino isn't quite as quick as a PC and sometimes you can encounter issues because you forget that the Arduinos are running at <1% of the PCs speed.  (Well I never considered speed might be an issue anyway)

@CodeGorilla - that's a fair point.  If Nick or the other admin team feel the same then by all means leave it open.  As explained above when using a PIC at 40Mhz, the main loop is probably shorter and processing subroutines are quicker, which might have thrown me whilst porting it to the mega.  Anyway, I hope that it helps others who are writing PC applications to send and receive data from an arduino device.


text:
ESP8266 MQTT client error
#include <PubSubClient.h>
#include <ESP8266WiFi.h>

//EDIT THESE LINES TO MATCH YOUR SETUP
#define MQTT_SERVER "YOUR.MQTT.SERVER.IP"
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";

//LED on ESP8266 GPIO2
const int lightPin = 2;

char* lightTopic = "/test/light1";

WiFiClient wifiClient;
PubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);

void setup() {
    //initialize the light as an output and set to LOW (off)
    pinMode(lightPin, OUTPUT);
    digitalWrite(lightPin, LOW);

    //start the serial line for debugging
    Serial.begin(115200);
    delay(100);

    //start wifi subsystem
    WiFi.begin(ssid, password);
    //attempt to connect to the WIFI network and then connect to the MQTT server
    reconnect();

    //wait a bit before starting the main loop
        delay(2000);
}

void loop(){

    //reconnect if connection is lost
    if (!client.connected() && WiFi.status() == 3) {reconnect();}

    //maintain MQTT connection
    client.loop();

    //MUST delay to allow ESP8266 WIFI functions to run
    delay(10);
}

void callback(char* topic, byte* payload, unsigned int length) {

    //convert topic to string to make it easier to work with
    String topicStr = topic;

    //Print out some debugging info
    Serial.println("Callback update.");
    Serial.print("Topic: ");
    Serial.println(topicStr);

    //turn the light on if the payload is '1' and publish to the MQTT server a confirmation message
    if(payload[0] == '1'){
        digitalWrite(lightPin, HIGH);
        client.publish("/test/confirm", "Light On");

    }

    //turn the light off if the payload is '0' and publish to the MQTT server a confirmation message
    else if (payload[0] == '0'){
        digitalWrite(lightPin, LOW);
        client.publish("/test/confirm", "Light Off");
    }

}

void reconnect() {

    //attempt to connect to the wifi if connection is lost
    if(WiFi.status() != WL_CONNECTED){
        //debug printing
        Serial.print("Connecting to ");
        Serial.println(ssid);

        //loop while we wait for connection
        while (WiFi.status() != WL_CONNECTED) {
            delay(500);
            Serial.print(".");
        }

        //print out some more debug once connected
        Serial.println("");
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());
    }

    //make sure we are connected to WIFI before attemping to reconnect to MQTT
    if(WiFi.status() == WL_CONNECTED){
    // Loop until we're reconnected to the MQTT server
        while (!client.connected()) {
            Serial.print("Attempting MQTT connection...");

            // Generate client name based on MAC address and last 8 bits of microsecond counter
            String clientName;
            clientName += "esp8266-";
            uint8_t mac[6];
            WiFi.macAddress(mac);
            clientName += macToStr(mac);

            //if connected, subscribe to the topic(s) we want to be notified about
            if (client.connect((char*) clientName.c_str())) {
                Serial.print("\tMTQQ Connected");
                client.subscribe(lightTopic);
            }

            //otherwise print failed for debugging
            else{Serial.println("\tFailed."); abort();}
        }
    }
}

//generate unique name from MAC addr
String macToStr(const uint8_t* mac){

  String result;

  for (int i = 0; i < 6; ++i) {
    result += String(mac[i], 16);

    if (i < 5){
      result += ':';
    }
  }

  return result;
}

The error is 'callback' was not declared in this scope

it is a know bug in Arduino toolchain. copy the callback function before the first use. before client declaration.

@Juraj I've changed it, but I found the same error

update the code in the question

have you tried adding void callback(char* topic, byte* payload, unsigned int length); (exactly that one line with ; at the end) before PubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);

@Juraj - that's not a bug, that's how C++ rolls - you can't "reference" a function in code before you "declare" it - also, moving callback will mean the callback function will try to "reference" client before it is declared, so, similar (but not exactly the same) error will occur - declaring the function callback before client will fix the issue

@JaromandaX, but this is Arduino .ino and the arduino tool generates the declarations

No, it doesn't. If it did there'd be no error

@JaromandaX in .ino functions can be used before definition without previous declaration. only functions used before setup() are not found. it is a bug of ino to c++ conversion

I apologise for my misinformation in that case - I've always treated .ino as c++ :p

In C++, you can't use or reference a function before it is declared, that's not Arduino specific, it's how C++ "works"
Moving the callback function above the client declaration won't help, because the callback function references client
The only solution is to declare the callback function before it is referenced in client initialisation, but have the definition of callback after
i.e. add one line
WiFiClient wifiClient;
void callback(char* topic, byte* payload, unsigned int length); // add this in your code
PubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);

Nothing else needs to be changed
Please excuse some terminology mistakes above - it's been a long time since I learned C/C++, while I know how to use it, I don't always know how to describe it :p

apprently there's some bug in the toolchain - see the comments in the question. However, this is still a valid solution, I guess it works around the bug

The difference is "declaration" vs "definition". Readers should take note of the differences, though they appear somewhat similar. Declaration must occur before (nearer to the start of a source file) use.


text:
Can you make it so, when your phone connects to the Hc-05 on a Arduino, a variable changes?
So whenever my phone gets close, and it connects to the Hc-05, the Arduino changes a variable? I want to avoid the use of apps, where the user has to do anything after first time connecting. The project is an automatic door opener, wherein the user for whatever reason can't use their hands, like if they have groceries in their hands.
Thank you for your time

Detecting successful connection with HC-05
The HC-05 can be configured to do what you are after.
Search for "POLAR" in the AT set documentation.
AT+POLAR=0,1

should be what you need as per their examples.
Hook up PI09 to your arduino and wait for it to go HIGH.
You may even want to wake up your arduino with an hardware interrupt using that signal.
Depending on your package, this may require soldering to the HC-05 module.
The datasheet features a pinout in that case. Be sure to checkout the manual of your breakout board first.


text:
Difference between Ciao REST server and Ciao REST connector and when to use each or the other
I'm reading the Ciao library and can't make out the difference between Ciao REST server and Ciao REST connector.
When is the connector suitable and at what point do I need the server?
This is a graphic of what im thinking to do:

The yun tag was the only i coul set. I would like to set library-ciao.

I don't know about "Ciao" but generally a rest server answers requests from a client that is connecting via a rest connector.
You client will use POST, GET, PUT, etc. to ask the server to provide a service.  This could be as simple as "GET .\index.htm" or more likely posting information to be stored in a database.
The server will sit waiting for these requests and will have handling routines for each specific request and might supply a response.

yes, im fully aware of REST as api but my queston is about the confusing thing that Ciao is used on a microprocessor board that has another cpu processor beside it. It hosts a LininoOS that is a full server. Now im connecting to a Raspberry Pi Server as well and i down't understand the different servers meaning.
Thats why im asking so high level about the difference of the two libraries.

added a graphic to make it more clea what thee types of systems i mean.


text:
Can someone help me with my arduino and relay and switch?
This is my code. What i want to do is activate the relay when switchInNcPin is activate. I am using a switch (micro switch). It has COM NC and NO pins. Can you tell me what is wrong with my code?
PROBLEM:
The relay keeps clicking ON and OFF even though it is meant to wait 5000ms, activate, wait 3000ms, deactivate only once. Can you look at my code and help me?

connect the switch like a button https://www.arduino.cc/en/Tutorial/InputPullupSerial

please don't post pictures of code, copy the code into your question and use the proper format. This way people can copy all or part of your code, make changes and use that in their answer.

Maybe it's not the only problem, but at least:
int val = ...

and
if (val == "FLUSH")

do not match.
I assume you mean a digit here (0 or 9 to flush)?
Also, you should put your circuit in your question. A reason because of the 'flipping' is that your switch is not pulled down, and it results in undefined behavior.
Another thing you could add is debouncing, when a switch is clicked, it results in multiple 0/1 and 1/0 transitions (although your delay might help too).


text:
GSM library_ all examples ar working except GPRS?
i am using arduino uno and sim808. i connected the sim808 to pins 2,3 on arduino uno and used GSM library. i tested all examples: make and receive a call or messages. the part of GPRS initialization is not working after many tries in changing APN and pin number.
i want to use the arduino as a webserver exactly as the example includded in the library.
any one can help?
thanks,
https://www.arduino.cc/en/Reference/GSM

I had the same problem I solved it by moving the jumper wires on the shield(if you are using one) to SW serial. if that doesn't work try testing it with AT commands


text:
Problems encountered when trying to program Arduino UNO via esp8266 with ESP-Link
Basically my project requires to program Arduino Board wirelessly and I have found ESP-link which seems to match my purpose.
I tried to follow the instructions in documentations on the github page https://github.com/jeelabs/esp-link I am using Arduino UNO and ESP8266-01 by the way.
Flashing ESP-link into ESP8266 was successful. I followed the configuration page and successfully connect the ESP8266 to an MQTT Server. I connect my Arduino UNO to computer via USB Serial. Connected UNO to ESP8266 using the default settings (TX - TX, RX - RX, GPIO0 - RST). When I checked the Microcontroller Console page, I could send and received messages to/from UNO as well as resetting the UNO (I programmed blink sketch into my UNO, so I can see every time I reset it, it works)
However, the next step is not that successful. I tried to program UNO via ESP8266 but it does not work out quite well. There are several methods posted on the documentation https://github.com/jeelabs/esp-link/blob/master/UC-FLASHING.md and I have tried them to some extent.
1.Use Avrdude to program. Basically I copied the command when Arduino IDE programmed UNO using avrdude, and change the port to net:{localIP_of_ESP8266}:23
By the way I tested the code by set the port to local Serial port and it works
I get the error and below is what cmd shows:
avrdude.exe: Version 6.3, compiled on Feb 17 2016 at 09:25:53
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "C:\Users\ktz001\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino9/etc/avrdude.conf"

             Using Port                    : net:192.168.10.97:23
             Using Programmer              : arduino
             Overriding Baud Rate          : 115200
avrdude.exe: ser_drain(): read error: The parameter is incorrect

avrdude.exe: ser_drain(): read error: The parameter is incorrect

avrdude.exe: ser_drain(): read error: The parameter is incorrect

avrdude.exe: stk500_recv(): programmer is not responding
avrdude.exe: stk500_getsync() attempt 1 of 10: not in sync: resp=0xa4
avrdude.exe: stk500_recv(): programmer is not responding
avrdude.exe: stk500_getsync() attempt 2 of 10: not in sync: resp=0xa4
avrdude.exe: stk500_recv(): programmer is not responding
avrdude.exe: stk500_getsync() attempt 3 of 10: not in sync: resp=0xa4
avrdude.exe: stk500_recv(): programmer is not responding
avrdude.exe: stk500_getsync() attempt 4 of 10: not in sync: resp=0xa4
avrdude.exe: stk500_recv(): programmer is not responding
avrdude.exe: stk500_getsync() attempt 5 of 10: not in sync: resp=0xa4
avrdude.exe: stk500_recv(): programmer is not responding
avrdude.exe: stk500_getsync() attempt 6 of 10: not in sync: resp=0xa4
avrdude.exe: stk500_recv(): programmer is not responding
avrdude.exe: stk500_getsync() attempt 7 of 10: not in sync: resp=0xa4
avrdude.exe: stk500_recv(): programmer is not responding
avrdude.exe: stk500_getsync() attempt 8 of 10: not in sync: resp=0xa4
avrdude.exe: stk500_recv(): programmer is not responding
avrdude.exe: stk500_getsync() attempt 9 of 10: not in sync: resp=0xa4
avrdude.exe: stk500_recv(): programmer is not responding
avrdude.exe: stk500_getsync() attempt 10 of 10: not in sync: resp=0xa4
avrdude.exe: ser_drain(): read error: The parameter is incorrect

avrdude.exe done.  Thank you.

Then I tried the post http method. Basically I sent a post request to http://{IP_of_ESP8266}/pgm/sync     in my case:

POST http://192.168.10.97/pgm/sync
I get 204 OK as response
Then I tried:
GET http://192.168.10.97/pgm/sync
It returns "sync abandoned after 8 attempts"
So I am stuck again

I tried also a small tool called avr-link https://gitlab.com/bc547-playground/avr-link
Someone used it to program a pro mini via esp8266-01 which I think is close enough to my situation. I ran it on the powershell (I am using Windos 10 btw)
The result is

PS C:\> .\avr-link.exe flash --esp 192.168.10.97 --file C:/Blink.ino.hex
AVR reset initiated...waiting for SYNC status
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
FATAL ERROR: Unexpected response:
00000000  73 79 6e 63 20 61 62 61  6e 64 6f 6e 65 64 20 61  |sync abandoned a|
00000010  66 74 65 72 20 38 20 61  74 74 65 6d 70 74 73     |fter 8 attempts|

using avrflash script. I am not sure how to run it in Windows OS so I did not use the script. If anyone could tell me about this, I appreciate it as well.

So to conclude, the problem seems to happen in getting sync after resetting the UNO (Although I am not 100% sure what does it mean - I am not familiar with the hardware process when flashing a UNO)
There is a paragraph actually in documentation suggesting the problem. Here is the quote:

If you are having trouble with the built-in programmer and see something like this:
./avrflash 192.168.3.104 blink.hex Error checking sync: FAILED to SYNC: abandoned after timeout, got:
  :\xF/\x00\xCj\xCz\xCJ\xCZ\xC\xAÜ\xC\xAä\xC\xAÜ\xC\xAä\xC\xBì\xC\xBô\xC\xBì\xC\xBô\xC\xAÜ\xC\xAä\xC
the most likely cause is a baud rate mismatch and/or a bad connection
  from the esp8266 to the AVRs reset line. The baud rate used by
  esp-link is set on the uC Console web page and, as mentioned above, it
  will automatically try 9600, 57600, and 115200 as well. The above
  garbage characters are most likely due to optiboot timing out and
  starting the sketch and then the sketch sending data at a different
  baud rate than configured into esp-link. Note that sketches don't
  necessarily use the same baud rate as optiboot, so you may have the
  correct baud rate configured but reset isn't functioning, or reset may
  be functioning but the baud rate may be incorrect.

I tried to change the baud rate (both in command and microController Console page) but it still does not work. And in Arduino IDE it programs the board in 115200 so I should be okay with this baud rate imo, but anyway it did not work even when I change it.
As for the reset connection, I could reset the UNO by pressing reset in the Microcrontroller Console page so It shouldn't be the problem (and I don't know how to change it anyway).
Thank you for your patience reading through all this crap..
So what do you think the problem is? Any suggestion would help :D

I have found out the problem: I connected TX and RX wrong way around. It should be TX - RX and RX -TX. ------ However, I still cannot access ESP-Link by host name, but I think the reason is : 1.I don't have mDNS service on my computer (or more precisely a properly functioned one) 2. The mDNS service on ESP-Link is not stable. The other computer can access esp-link server some time but cannot some other time.

@JnJ, In the answer I write about the esp-link mdns bug

I tested it some weeks ago again after a year. The default upload from IDE should work, but mDNS in esp-link has now a bug and propagates the service only in AP mode so in STA mode the IDE doesn't show the network port.
from command line you can upload OTA with arduinoOTA tool used by IDE
example:

/home/duro/.arduino15/packages/arduino/tools/arduinoOTA/1.1.1/bin/arduinoOTA
  -address 192.168.1.104 -port 80 -sketch /tmp/arduino_build_89762/Blink.ino.hex -upload /pgm/upload -sync
  /pgm/sync -reset /log/reset -sync_exp 204:SYNC

If the mdns bug was fixed, for upload from IDE some settings must be added to board.txt
uno.upload.network.endpoint_upload=/pgm/upload
uno.upload.network.endpoint_sync=/pgm/sync
uno.upload.network.sync_return=204:SYNC
uno.upload.network.endpoint_reset=/log/reset
uno.upload.network.port=80

Uno WiFi uses an old version of esp-link so the settings and tutorial apply

Thank you for replying.. I succeeded last week but forgot to update the question. It was the connection between ESP and Arduino board. Should be TX - RX and RX - TX while I connected them wrong way around.

I didn't test the avrdude network upload with esp-link. I used it with esp8266 AVRISP library. I configured the Arduino toolchain for network upload in platform.txt.

tools.avrdude.upload.network_pattern="{cmd.path}" "-C{config.path}"
  -p{build.mcu} -c{upload.protocol} "-Pnet:{serial.port}:328" "-Uflash:w:{build.path}/{build.project_name}.hex:i"

Warning: the use case in my other answer uses the original setting of tools.avrdude.upload.network_pattern


text:
Connecting RCA audio cables to Arduino
I'm working on a project which needs better audio quality than just a piezo buzzer, so I went out and bought a pair of used cheap speakers for $3. It turns out that they have RCA audio inputs rather than 3.5mm inputs. There is a separated left and right speaker, with a left and right RCA audio wire coming out of each.
I've looked around on the internet about connecting speakers to Arduino, but I've only found ways to connect 3.5mm/TRRS to Arduino, or the RCA video jack to Arduino, but not the RCA audio.
How should I go about wiring the RCA audio wires to my Arduino Uno so that I can play basic melodies off it? Are any amplifier circuits, voltage dividers, etc. needed?
I am okay with splicing the cables.
Thanks

lookup "rca to headphone pinout" and pretend you have headphones. they are the same once you cut the connector off anyway (given one extra common with RCA)

I am trying to connect male RCA cables (which come on the speaker) to the Arduino, not the headphone jack

ahh. if it's on the speaker itself, you need some type of amplifier circuit; the arduino can only pump out a few dozen millwatts. get an amp that has RCA speaker-level outputs.

Can you elaborate? Can I build this amp or do I have to buy one? How would I connect the RCA cable to the amplifier (what are the individual wires inside the RCA cable)?


text:
How do I turn lights on & off manually along with home automation?
Need some help regarding HomeAutomation
I was doing my room automate via Arduino with the help of relay , but a little problem I am facing,that when I switched on the light via relay then I cannot turn it off via switch board manually ,the switch is now useless & I have tried two way switch but it's not a better solution.
So please can anyone tell me how to solve this problem so that I can turn lights on manually & automatic too
Thanks

This question is better suited to https://electronics.stackexchange.com/ because your question's root has nothing to do with Arduino, but everything to do with wiring and switches.

A relay with both NO and NC contacts could function as one of the two switches in a conventional two-way switch setup, but you need to be very careful when wiring mains circuits - there are real hazards there.  Likely that subject matter belongs on Home Improvement SE, not on Electronics Stack Exchange.

you can use super caps to record manual offs, keeping the system in sync. if you set it to turn on when powered-on, a flip of the switch (or two) can result in your desired state.

Thank you so much , I will also add this question to https://electronics.stackexchange.com/

You would need to create something like in the picture, one switch will be the relay.

The switch already in place is probably not a three way switch, however it could be switched out for one.

He said he already tried a two way switch.

how would the arduino detect the state of the light?

Yes sir, already did that but any possible way to detect switch is turned on/off ? This will help me to turn the relay state

the state does not matter in this case, the relay can be either in on or off possition to set the light on, depending on the state of the lightswitch.
You could determine if the light is on or off by measuring current just before the lamp.


text:
Does the StringObject.reserve() function prevent memory fragmentation/leaks?
I'm currently writing and testing a professional Arduino application, I'm aware of the dangers of using the String class, so I began to implement C-style strings in some places, but it's just way harder using them to receive data from a Software Serial port that's variable in size and needs some manipulation.
I've upgraded from an Arduino Uno to a Leonardo so my current minimum SRAM usage is 1325 bytes (51%)
Here's the relevant part of my code:
String serialContents;
char emailChar[SIZEOF_ARRAY][SIZEOF_CHAR];

void setup(){
  serialContents.reserve(70);
  SerialOne.begin(9600);
}

void loop{

  if (SerialOne.available() > 0) //something is there to be read
  {
    serialContents = SerialOne.readStringUntil('\n'); //make a string of the characters coming on serial
  }

  if (serialContents.length() >= 60)
  {
   serialContents = ""; //ignore serial data
  }
 else{
  serialContents = cutString(serialContents); //some String manipulation, no adding only cutting
  serialContents.replace("@", "%40");
  serialContents.toCharArray(emailChar[count], 31);
  serialContents = ""; //String reset
}

So my question is, does something like this make my code unstable? Does the
reserve() function help at all?
Edit: Here's the cutString() function
String cutString(String request) {

  int points = request.indexOf(':');

  if (request.substring(0, points) == "CHECKOUT")
  {
    modoPedido[count] = 'o'; //char array
  }
  else if (request.substring(0, points) == "CHECKIN")
  {
    modoPedido[count] = 'i';
  }

  request = request.substring(points + 1);

  return request;
}

there is readBytesUntil if you want a convenient function for c-string

Reserving space will help reduce memory fragmentation, but much of what else you are doing is swamping that small improvement you have made.
The biggest area of concern is your cutString function, which you have omitted from your code above.  Passing a String as a parameter, modifying it, and then returning it again, ends up in new String objects being created and destroyed multiple times, which will make a mess of your heap.
Instead you should pass a String object by reference, and modify that object in-place. No need to return anything.
void cutString(String &theString) {
    // Modify theString here.
}

Of course, what you do in cutString could cause more problems - you should include that function in your code above so we can check it out.

Thanks!
I've updated the first post. Damn, I think I'm creating at least three more String objects with the substring() function. I guess I'll use other way to see if the string contains checkin or checkout like indexOf(), and use the reference method instead of returning the String object.


text:
Wemos mini pro switch power from servo with mosfet bs170
I got a servo connected to a wemos/arduino with a capacitor(470uf). Before I didn`t use a cap.
Now with the cap the device use to much power while sleeping(capacitor on the servo). I want to switch off the power to the servo with a MOSFET. I tried this with a BS170 N channel MOSFET. There is a youtube movie with the same settings except for the mainboard. They use an Arduino uno instead a wemos.
When I test the circuit with a led everything is working. When I use a servo instead a led, nothing happen. There is a little sound from the servo(I think not enough voltage).
When I check the voltage without anything hooked on the drain of the mosfet the output is perfect(5V). If I connect a led or a servo the voltage will drop to 3v.
Wemos mini pro has 3.3v output on the gpio pins.
Can someone explain me what I doing wrong? I saw and read some articles about Mosfet. I think it`s not clear enough for me.

Please show your schematic.

Schematic looks OK.  However, I'd choose a MOSFET with a lower R(DSON) and a lower V(GS) threshold.

My supposition:
The MOSFET's R(DSON) is too high and causing a large voltage drop.
A servo uses more current than a little LED.  That current passing through the MOSFET, with an R(DSON) of potentially up to 5Ω, reduces the voltage available to the servo, causing it to not work. Further more, ground for the servo is raised up above the real ground level adding an offset into the logic levels that could cause communication issues.
Suggestion: Pick a MOSFET with a lower R(DSON) (ideally measured in the milli-ohms), and a lower V(GS) threshold (something around 1-2V max would be good).


text:
Why do we need a transistor with a dc motor while we don't need one with a servo motor?
I was wondering why do we need to attach a transistor as we don't need one while we connect the Arduino with the servo motors. I am using mini servos.

A servo typically has 3 wires: Power, Ground, and Signal
Inside the servo are a bit of electronics that read the input signal duty cycle, the absolute position of the horn, and power the motor in forward or reverse accordingly. There are transistors inside the servo housing to handle the high current of the motor.
A standalone motor doesn't have any other control electronics that separate power from control inputs.
EDIT:
Just to clarify: the signal wire for the Servo doesn't carry any significant power. The IO pins on the Arduino should not be asked to provide more than 40mA of current, and the PWM signal to the servo falls under that current limit.
But to operate a motor, or other device which draws significant operating power, it (the motor) asks for much more than 40mA of current, which can burn out the IO pin and damage it forever. This is why a transistor or other "switch" is necessary: the device which switches the high-current on and off can itself be operated by a very low current.

Because a servo contains a driver circuit that controls the motor portion, whereas a motor doesn't. The transistor is the (simplistic) driver circuit for the motor.


text:
trouble running i2c and spi at the same time
I know this question has been asked before but I am having trouble running I2c and SPI at the same time. I am attaching my code below. The problem when I run the code is that the LED's don't blink until the OLED function has been complete, can I fix this with hardware? do I need to fix this in the code? (please note I am using a teensy 3.2)
My end goal is to be able to initially turn on the teensy, choose a pattern on the OLED for what led's turn on, and then just have the leds run.
code :
#include <SPI.h>
SPISettings settingsA(2000000, MSBFIRST, SPI_MODE1);
#include <SFE_MicroOLED.h>  // Include the SFE_MicroOLED library
#include <Wire.h>  // Include Wire if you're using I2C

int time_interval_for_chip = 1;
int blinking_interval = 500;
unsigned long current_time = 0;
#define PIN_RESET 9  // Connect RST to pin 9

#define DC_JUMPER 0

MicroOLED oled(PIN_RESET, DC_JUMPER);    // I2C declaration

void setup() {
  // put your setup code here, to run once:
  pinMode(10, OUTPUT);
  pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);
  Serial.begin(9600);
  SPI.begin();
  SPI.beginTransaction(settingsA);

  oled.begin();    // Initialize the OLED
  oled.clear(ALL); // Clear the display's internal memory
  oled.display();  // Display what's in the buffer (splashscreen)
  delay(1000);     // Delay 1000 ms
  oled.clear(PAGE); // Clear the buffer.

  randomSeed(analogRead(A0) + analogRead(A1));

  //SPISettings object is used to configure the SPI port for your SPI device. All 3 parameters are combined to a single SPISettings object, which is given to SPI.beginTransaction().
  //sending in bits by MSB first and using SPI_MODE1 which is output edge rising data capture falling
  // can be set to either 4000000 or 2000000
}

void loop() {

  //Blinks output 4 and 8 on and off with teensy without spi.endtrasaction()
  //delaying with delay void function made
  unsigned int result = 0;
  unsigned int result2 = 0;
  byte inbyte = 0;
  byte inbyte2 = 0;

  digitalWrite(10, LOW);
  result2 = SPI.transfer16(0b0100000100000100);
  Serial.print("result= ");
  Serial.println(result2, BIN);
  digitalWrite(10, HIGH);

  //getting the time
  current_time = millis();
  delaying(current_time, 1);

  digitalWrite(10, LOW);
  result = SPI.transfer16(0b0000010000010000);
  Serial.print("result2= ");
  Serial.println(result, BIN);
  digitalWrite(10, HIGH);

  //getting the time
  current_time = millis();
  delaying(current_time, 300);

  digitalWrite(10, LOW);
  result2 = SPI.transfer16(0b0100000000000100);
  Serial.print("result1= ");
  Serial.println(result2, BIN);
  digitalWrite(10, HIGH);

  //getting the time
  current_time = millis();
  delaying(current_time, 1);

  digitalWrite(10, LOW);
  result = SPI.transfer16(0b0000000000010000);
  Serial.print("result2= ");
  Serial.println(result, BIN);
  digitalWrite(10, HIGH);

  //getting the time
  current_time = millis();
  delaying(current_time, 100);
  lineExample();  // Run the pixel example function

}

void lineExample()
{
  int middleX = oled.getLCDWidth() / 2;
  int middleY = oled.getLCDHeight() / 2;
  int xEnd, yEnd;
  int lineWidth = min(middleX, middleY);

  printTitle("Lines!", 1);

  for (int i=0; i<3; i++)
  {
    for (int deg=0; deg<360; deg+=15)
    {
      xEnd = lineWidth * cos(deg * PI / 180.0);
      yEnd = lineWidth * sin(deg * PI / 180.0);

      oled.line(middleX, middleY, middleX + xEnd, middleY + yEnd);
      oled.display();
      delay(10);
    }
    for (int deg=0; deg<360; deg+=15)
    {
      xEnd = lineWidth * cos(deg * PI / 180.0);
      yEnd = lineWidth * sin(deg * PI / 180.0);

      oled.line(middleX, middleY, middleX + xEnd, middleY + yEnd, BLACK, NORM);
      oled.display();
       current_time = millis();
  delaying(current_time, 10);
    }
  }
}

void printTitle(String title, int font)
{
  int middleX = oled.getLCDWidth() / 2;
  int middleY = oled.getLCDHeight() / 2;

  oled.clear(PAGE);
  oled.setFontType(font);
  // Try to set the cursor in the middle of the screen
  oled.setCursor(middleX - (oled.getFontWidth() * (title.length() / 2)),
                 middleY - (oled.getFontWidth() / 2));
  // Print the title:
  oled.print(title);
  oled.display();

  //getting the time
  current_time = millis();
  delaying(current_time, 1500);
  oled.clear(PAGE);
}

void delaying(unsigned long current_time, int period) {

  while (millis() < current_time + period) {
    //wait approx. [period] ms
  }
}

Can you replace the use of millis with normal delay and test again? The usage of millis is wrong, your sketch could delay by 50 days sometimes. You say the the blinking on the leds is delayed. How much slower is it? The i2c bus is slow, and all those delays and millis make the sketch even slower. Why do you have so many delays and complain about the delays? I count 1.4 seconds delay in the function lineExample alone.

can you explain how I am using millis() wrong? that would be constructive

See the blink without delay example: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay As soon as you compare a value to the return value of millis(), that's wrong. You can use the blink without delay twice to do multiple things at once. Update the SPI at a fast rate and the oled at a slow rate.

ok I see what you mean for 1 but I don't see how this is wrong. I followed this link https://www.norwegiancreations.com/2017/09/arduino-tutorial-using-millis-instead-of-delay/

what my code is doing is it won't run the OLED and the led's at the same time, the OLED function needs to be complete before the leds run but I want to run the two at the same time.

I quickly removed the problem when the parameter is just 1 from my comment. I was not thinking that through. The blink-without-delay shows how to use millis. Do not follow what is written in that norwegian link, it is totally wrong. The blink-without-delay shows how to use millis. Can you try to use the blink-without-delay and have two leds blinking at different rates, completely independent of each other?

I will change it, but I don't see how what that person did was wrong, it makes sense.

No, not at all, it is really a bad example. That code is also here: https://dzone.com/articles/tackling-the-new-world-of-iot-management and there are comments there saying it is bad and harmful. You had bad luck finding that. The function millis() will rollover after 50 days, it is simple to avoid problems with the rollover by using it in the way the blink-without-delay shows.

I genuinely think if I change it to the other it won't make a difference. I use to use the while loop at Johns Hopkins University in their labs, so that doesn't make sense to me that this will (make or break it)

Use the blink-without-delay, do not compare the millis value directly to an other value. Everyone who knows about millis can tell you that.

An interupt could come in and be handled between when you record millis and when you wait for it. It might not be accurate.    However if the function is taking a long time to come back you cant do anything else since its blocking.  Unless you rewrite the function to be shorter, or use interrupts to drive your leds

can I drive the led's with the interrupt? I thought an interrupt was suppose to be for a quit time.  Just to clarify my exact goals, I want to do some things initially on the OLED to control how the LED's behave, like pick a pattern on my OLED and then the LED's do that. maybe there is a better way to do what I want?

I think you don't need interrupts for this. You just have to write your OLED and LED code non-blocking. The point of the BlinkWithoutDelay example is to not do busy waiting (what you are doing with your delaying function (doing a delay with your own function using millis() doesn't make sense eiter)), but to only do a short check in every loop cycle, if it is time to do something, and else going further in the code.


text:
Using digital pins 0/1 on Arduino Due when writing/reading over serialUSB port
I am aware that you cannot use pins 0 and 1 as digital pinouts when communicating over serial via serial.print(), but what if you are using the native port on the due with serialUSB.write()?
Thanks

Yes, you can use 0/1 while using the native USB. The two are completely separate.


text:
Does millis() work inside a function?
So I know that millis() doesn't work how it's suppose to if you use it in an interrupt but lets say we have a code that looks like below, will millis() work properly or how it behaves in an interrupt? Do I need to use the delay() instead of millis() when I'm outside of void loop() ?
To clarify, I understand how millis() behaves in an interrupt and why delay() doesn't work in an interrupt.
const int ledPin =  LED_BUILTIN;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1000;

void setup() {
 pinMode(ledPin, OUTPUT);
}
void loop(){
blink();
}
void blink(){
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

That is good code. You can use many more of those functions with different leds and different intervals, but each should have its own previousMillis variable. The interval can be an int or a long, but you can also make it an unsigned long, then the compiler does not have to convert it to unsigned long. Using millis in an interrupt can be used to remember the time, for example as a timestamp to decode a certain timing protocol. But don't use delay in a interrupt and don't use millis to create a delay in a interrupt.

So the millis() will work fine in the void blink() ? it's not like an interrupt where the millis() is the last millis() used in the regular void loop() ?

It will work fine. I don't understand your second question. The way you use millis in the sketch is checking if enough time has passed since the previousMillis, that is how to use millis. There is no waiting, no delay, the led is changed when it is time to do so.

I think I'm confused with the term interrupt vs function, like void blink() isn't considered an interrupt is it? is an interrupt only when I actually declare it?

Your blink function is a normal function. Everything that is called from the loop function is a normal function. An interrupt function is for example with the function attachInterrupt https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

Just as a terminology item: loop is a  function it is not a void. void is the return type. To say something like "the void blink" is confusing. You mean: "the function (named) blink".

Just to reaffirm. The way you  are using millis is absolutely fine. Excellent example of not using delay to blink an led.

Millis is driven by an interrupt. The reason it doesn't "work" from inside an interrupt is that you can't have two interrupts running at the same time. So when your interrupt is running the interrupt that makes millis count can't run.
Millis does work in an interrupt as long as all you want is to record a single point in time. If you do anything that relies on millis changing within the lifetime of the interrupt it will break. That is why delay is bad in interrupts.
So from that you can see that it's only when in an interrupt that things can go awry. Everywhere else, as long as interrupts are enabled, both millis and delay work fine.
After all, loop is just a function called by main, and main is just a function called by _startup... Etc...

Although that is a nice explanation of an interrupt my question isn't about what an interrupt does. To clarify is void blink() behaving as an interrupt or does something only behave as an interrupt when you declare it?

Something only behaves like an interrupt when it is called by an interrupt. Blink is just a function. Like loop. Like millis. Like delay. Like setup. They are all just functions. Only interrupts are interrupts.

so it's only considered a interrupt only when i use attachInterrupt() right? so then in the void blink() function about millis() works fine, it doesn't behave like the way it would in an interrupt correct?

An interrupt is a context not a function. A separate thread of execution if you like.

Only if you called blink from an interrupt would it behave like an interrupt.

ok I think my confusion was Jot said that my delay function written on this thread https://arduino.stackexchange.com/questions/51049/trouble-running-i2c-and-spi-at-the-same-time?noredirect=1#comment104925_51049 was wrong and I just didn't understand how it's wrong, especially because it worked correctly.

It's not your usage of millis that is wrong but your method of calculation. You run into problems when the millis count rolls over. Your calculation, with integer wraparound, goes awry.