text:
None of the pins work as inputs
I’m using an Arduino-uno
I'm trying to read an PWM signal being output by pin 6.
I'm attempting to read it with pin A0.
5 volts are being supplied from pin 6 to a 300 ohm resister in series with one led.
This circuit returns to the analog input pin A0.
It'll admit it's a strange set up and I was told to use a pass through filter to read the signal.
At this point I'm not concerned with whether the program reads the right values,
so despite the code involving the serial monitor I'm just trying to figure out why the led won't turn on anymore.
As I stated in the sketch, this exact set up was working fine yesterday. The led was on and (accurate or not) there were consistent values being printed to the serial monitor.
I'm trying to figure out now what changed after I unplugged it last to create a now open circuit.

```

void setup() {

  Serial.begin(9600);
  pinMode(6, OUTPUT);
  // I  also tried setting the A0 pin as an input even though I thought you didn't have to and it didn't change anything.

}

void loop() {

  analogWrite(6, 255); // This pin is working as an output, I tested it to ground and led lights.

  int value = analogRead(A0); // I realize inputs are typically used for things like potentiometers
                              // But just as an example the LED should still turn on when connected here, correct?
                              //And it did the first few times I did it... maybe that was the problem?

  Serial.println(value);  // This was  all working previously. It just randomly stopped.
                          // Now this just prints random numbers and the circuit remains incomplete.
                          // Even if the input pins are not supposed to be used with 5 volts, Why was it working before then...
                          // ALSO it does not matter which pins you use for what...
                          // No current is running through the digital inputs with digital output set to HIGH.
                          // And No current runs through the analogInput pins when analogWrite is set to 255.
                          // Once again, I apologize if my terminology is off.

}
```

This is what I did to trouble shoot:
With the same sketch running on the board...
I connected a jumper from pin A0 to ground and the serial monitor switched from a bunch of random values to a solid 0. So it recognizes input still... in a sense.
Then I modified the sketch...
void setup() {

Serial.begin(9600);
pinMode(6, OUTPUT);
pinMode(8, INPUT);

}

void loop() {

// now I'm attempting to read a digital signal with the same circuit...
// Pin 6 is connected to a 300 ohm resistor in series with an led which returns to pin 8.

digitalWrite(6, HIGH);

int value = digitalRead(8);

Serial.println(value);

}

This gave the same result. The led wont turn on anymore unless the circuit ends are connected from a voltage source to ground.
Previously, any pins configured as INPUT would not only read consistent values but also complete the circuit, turning the led on.
Now the pins only recognize zero volts and do not complete any circuits. You can't even use a simple potentiometer if you wanted.
Each pin that can be configured as an INPUT acts the same way.
The only thing I did between the times when it was working and wasn't was unplug and plug in the board...

Please edit your post and show your sketch. Your terminology of "don’t even complete a circuit as inputs" is confusing. For example, a microphone is an input. How would expect that to complete a circuit?

However, when connecting the circuit to any pins configured as input, the light won’t even turn on... but it works fine connected to ground. - why do you expect an input to light an LED? That's like saying that when you connect your microphone to a computer it doesn't play sound.

Sorry for the confusion. I did not expect an input to light an LED, you're right that would be absurd. I figured some assumption could be made. My bad, The post is updated.

Re “I did not expect an input to light an LED”: You are contradicting yourself here. You previously wrote “when connecting the circuit to any pins configured as input, the light won’t even turn on... but it works fine connected to ground”. So you did expect the light to turn on.

Yes, connecting the end of the circuit. The other end is hooked up to a pwm source. Besides, right after that I state, "it doesn't work when connected to ground either". So your assumption would also imply that I thought a circuit with absolutely no power source should be able to turn on an led.

Sorry, "it does work when connected to ground". See, the original post IS confusing. That is why I updated it. Either way my point stands. It should not be hard for a person like your self to make the right educated assumption to that statement. Instead you assume people's ignorance's, pick out the all the discrepancies, and remain unhelpful. This is why forums are not as popular anymore. If you are genuinely confused and need anymore clarification I can do that, otherwise don't bother posting. It's a waste of time.

Re “It should not be hard for a person like your self to make the right educated assumption to that statement”: Sorry, I am not intelligent enough to read your mind: I am genuinely confused. Pointing out the discrepancies is a way to help you clarify your question. And that would be no luxury: my reading of your question is exactly the same as towe's and Nick Gammon's. Thus, if you think towe did not provide an appropriate answer, that means that you have at least three people confused as to what you really mean. Now, given the unfriendliness of your reaction, I will not try to help.

I'm still confused by your post. Maybe you can make a list of each scenario with a wiring diagram, a description and for each state, what you expected and what actually happened. Currently it is unclear to me, what is connected to what, when you expect the LED to light up

I don't mean to argue, but I too can not read your mind. What you said already was mentioned by yes, three people and cleared up. And the way you said it would give anyone a reason to assume "unfriendliness" on your end as well. You say you can not read my mind yet you literally state what you believe I am thinking. I was not assuming intelligence, I was assuming tone. Which I still think to be in your words "unfriendly". I respect that you do not want to help. However, respectfully, I do hope you realize the hypocrisy in your respons and just remember that there really was no point in this.

Chris, I can do that. I'll update it again in a little bit thanks.

Ok, now its a bit clearer. Tomorrow I will write an answer and discuss the situations, that you describe there. Now its time to sleep, where I live

So, finally, here's the problem. Your present circuit as described by you is connected as PIN6--> LED--> RESISTOR--> PIN8. Instead of connecting the resistor to PIN8 you need to connect it to ground. With the same code, to test input, connect a jumper wire from 5V to PIN8, you should see all 1's in the serial monitor. By connecting PIN8 to GND and you should see all 0s.

Please try to include some schematics and clearly state what you try to achieve and what actually happens. I’m confused by your description of the “problem” as it seems the circuit you describe behaves exactly like expected. Inputs behave like very high resistances. You can’t light an LED by connecting one of its legs just to an input, unless you connect a current/voltage source to that same leg/input as well.

Sounds like there's a basic misunderstanding here.
Setting a pin as "output" mean it'll either supply +5V ("HIGH") or 0V ("LOW"). Both those states are considered "outputs", and the pin can source or sink current in those states. When driven "LOW", the circuit does "input" current to the chip, but that's not what "input" usually means.
"Input" means you can use the pin to read the voltage applied to the pin. When connected to a PWM source, this might manifest as the pin quickly switching between "1" / "HIGH" / "+5V" and "0" / "LOW" / "0V".
Normally, you would use the "input" mode to read things like switches, or potentiometers on the analog input pins.
Your desired use of "current input" pins will require you to configure the pin as "output", and then set it to "LOW", which will make it able to sink current.

This seems very much to me to be the correct answer. An input pin does not "suck in current". It measures if it is there or not. As an analogy, a thermometer does not make things hot or cold, it measures if they are hot or cold.

Sorry for the confusion, I updated the post. I was attempting to use the analog input pins (either A0 - A5) to read the voltage from the circuit which I powered with a pwm source. So where I'd normally connect the end of the circuit to ground, I connected it to an analog input pin configured to "read" the voltage. It was working previously, can this not be done?

@User-2746 Does that mean you are trying read a PWM sicnal with analogRead()? That will not work as long as you don't use something like a low pass filter.

Yes, thank you. I will try this. I'm still slightly confused because previously using the same exact set up the led was on. Whether or not the PWM signal was being read properly due to no filter, I'm not sure, but the led it's self was working. It's like something changed from when I unplugged everything to when I tried it again the next day. Because now, with the same set up, the circuit is incomplete when connected from a PWM on pin 6 to the analogRead on pin A0... Which once again is the opposite to what it did originally.

I also updated it one more time for much needed clarification. It's a strange problem and I didn't explain it well enough.

The LED would glow only when the pin is configured as an OUTPUT or it would be very dim in INPUT mode. This is because INPUT mode sets the pin to a high impedance state, suitable for reading voltages and not for driving circuits requiring current.
Setting a digital pin to INPUT mode, allows you to only read voltages as 0 or 1  which correspond to 0V and 5V respectively. For example, upload the code below to your Arduino and open the serial monitor. Now, by connecting Pin 11 to GND the serial monitor should display 0, and by connecting it to 5V, it should display 1. If this doesn't work something may be wrong with the Arduino.
const int TESTPIN=11; //connect pin 11 to 5V and GND for testing

void setup() {

  pinMode(TESTPIN, INPUT);
  Serial.begin(9600);
}

void loop() {
  Serial.println(digitalRead(TESTPIN));
  delay(500);
}

However, I would recommend that you share your code and diagram before concluding a fault in the Arduino.

Thanks for the input. I tried what you said and it helped explain the problem a little better. The monitor displayed "0" when connected to ground but the values are all random when supplied with voltage. I think your right, somethings wrong with the board. I updated my post adding this in. It's very strange that it just failed so randomly. It was working at first, then I unplugged it, plugged it back in the next day and now it doesn't.

Just to confirm, I hope you connected PIN11 directly to 5V using a jumper with nothing in between?

In your second update you described the following circuit:

simulate this circuit – Schematic created using CircuitLab
Then in code you are doing digitalWrite(6, HIGH);, which sets pin 6 to HIGH/1/true/5V. Pin 6 is configured as output, pin 8 as input. In this situation the LED will not light up. A pin, that is configured as input, will not draw or source current (except a very very small amount). The input pin behaves somewhat like a little capacitor to ground (so in principle nearly no current can flow). Thus no current is flowing through the circuit. No current also means, that the LED does not light up (it needs current for lighting up) and no voltage drop will happen on the circuit. The circuit will not be "completed", as you phrased it. Thus your input pin will also get HIGH/1/true/5V, which is what you then read on in the code.
When you instead change pin 8 to output (pinMode(8, OUTPUT);) and set it to LOW (digitalWrite(8, LOW);), the LED will light up, as now the voltage difference is the full 5V (from HIGH at pin 6 to LOW/ground at pin 8). If you now read the pin with digitalRead(8) you will just read, what you have written to it, meaning LOW/0/false/ground.
You might also have tried to use digitalWrite() with a pin, which is configured as INPUT. That does not really output anything. Instead it activates or deactivates the internal pullup resistor of the pin. As I remember, this pullup resistor is between 20 and 50 kΩ, so again you cannot get enough current to light an LED through that pin. The internal pullup resistor is then like an additional 20 to 50 kΩ resistor from the corresponding input pin to Vcc (5V in your case). If nothing else pulls on the pins value, the pullup resistor will pull the value of the input pin to HIGH/1/true/5V, so that you don't have a floating pin (see below for an explanation of that term).

The next scenario: Using analogRead()
Here you first tried to read an analog pin (A0), which was not connected to anything. That is called a floating pin. There is nothing, that gives this pin a definite value, thus it catches whatever electrical noise comes around, from the microcontroller, from other pins, from the circuit or from outside. A floating pin can change it's value rapidly and randomly, depending on the noise, which comes around. Thus you will get very different and varying values here.
Then you connected A0 to ground. That gives the pin a definite value (LOW/0/false/ground). Thus you now only read zero as value.
If you are doing the analogRead() with a circuit similar to the first case (with the LED between two pins) you will get a similar result as with digitalRead(). An analog input will also not source or draw any current (besides a very very small current). Thus you cannot "complete" a circuit to light an LED on the path.

I'm trying to read an PWM signal being output by pin 6. I'm attempting to read it with pin A0.

A PWM signal is nothing else than changing rapidly between Vcc (5V in your case) and ground. The value, that you give the PWM signal via analogWrite(), defines the duty cycle of the signal, meaning the ratio between the HIGH and LOW portions in the signal. The function name analogWrite() is unfortunately very misleading, as you don't really output an analog voltage. Most Arduinos don't have the hardware to do that, so analogWrite() uses PWM to output a pseudo analog voltage. Devices like motors are not fast enough to react to the fast voltage change, so you can change the speed with PWM. LEDs are fast enough, but the human eye cannot see the individual on-off cycles, so you see the LED being dimmed with lower values.
But the analogRead() function (which uses the ADC hardware internally) is fast enough, thus you would only read a series of changes between 5V and ground, when reading a PWM signal. You could build a low pass filter, which will filter out the PWM frequency and give you a real analog voltage, which you can then read via analogRead(). Though keep in mind, that this makes it slower, so you cannot read fast changes with that. A low pass filter looks like this:

simulate this circuit
The values come from the come from the comment of Edgar Bonet (thanks):

The PWM frequencies of the Uno are 977 and 490 Hz, below the cut-off of the filter you drew. Per the ADC's specification, you can safely increase R1 up to 10 kΩ, which should put the cutoff low enough to attenuate the PWM frequencies by at least 30 dB.

Though you might also want to read up the formula for the cut-off frequency. You can google terms like "RC low pass filter".
If you don't want to use extra hardware, but still want to read the PWM signal, you need to read the pulse length. For this there are multiple ways, depending on the requirements. You can use pulseIn(), you can use interrupts and take timestamps, you can use the capture mode of a hardware Timer.

As I stated in the sketch, this exact set up was working fine yesterday. The led was on and (accurate or not) there were consistent values being printed to the serial monitor.

Unfortunately this is not possible. The pins must behave like I described above. As electronics not break and then just magically unbreak, you must have done something different. An input pin (digital or analog) will not source or draw enough current to light an LED.

Now the pins only recognize zero volts and do not complete any circuits. You can't even use a simple potentiometer if you wanted.

You may have damaged something, though I cannot really say, if that is really the case or if you are just doing something wrong there. A potentiometer has to be connected like the following: The outer pins to ground and 5V respectively, the middle pin directly to the analog input. Nothing else. You might check, if that is, what you did.

Besides all that, you didn't really state, what you are trying to achieve. As you already acknowledged in your question, the described circuit is not typical and a strange setup. To light an LED, you would just connect it to the output pin (via the resistor) and on the other side to ground.

Nice answer! Just two comments: 1. The pullup is specified to be between 20 and 50 kΩ (not MΩ), with 30 kΩ being typical. 2. The PWM frequencies of the Uno are 977 and 490 Hz, below the cut-off of the filter you drew. Per the ADC's specification, you can safely increase R1 up to 10 kΩ, which should put the cutoff low enough to attenuate the PWM frequencies by at least 30 dB.

@EdgarBonet Ups, thanks for correcting. Thinking back, 50MOhm should have made me suspicious of my claim XD. I have included the 10kOhm value into the schematics and mentioned/cited you in the answer.

I got here with a similar problem to the OP, I see they didn't answer your question about what they wanted to achieve, I can't figure it out but I can explain what I was trying to do.  I have a toggle swtich on-none-on, and I want to have 2 leds, to indicate which one is on (yes I know I could just look at the switch :) ).
What I wanted to do was have the LEDs in-line with the input to the Arduino so that instead of using 2 pins for inputs from the switch and 2 pins as outputs for the LED's I could get away with just using the 2 input pins.


text:
Send data from GSM module to cloud server like firebase
I am trying to search for anything to send my sensor data from Arduino + GSM SIM900A to a cloud server, preferably firebase. Does anyone know how can I achieve this operation to firebase or any other cloud database?

source: Stack Exchange

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

sort: votes


text:
Multiple Push buttons to one input
So I am trying to use one input to control an LCD display. The goal being that once one of the buttons is pressed it delivers a message. I have watched quite a few tutorials and can get the program to work sometimes. Yet, it is still pretty buggy and I am wondering why that is. To get this make this project work somewhat used this code.
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int buttonPin = A0;     //Button and LED pin numbers
    void setup()
{
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  //lcd.print("hello, world!");
  Serial.begin(9600);           //Serial monitor used to determine limit values

 }

void loop()
{
  int temp = analogRead(buttonPin);   //Read the analogue input
  Serial.println(temp);               //Display the read value in the Serial monitor
  if (temp = 340)                     //Lower limit for first button - if below this limit then no button is pushed and LEDs are turned off
  {
  lcd.print("No Button Pushed \n");
  }
  else if (temp = 867)                //First button limit - if below this limit but above previous limit then the first button is pressed
  {
    lcd.print("Button 1 Pushed");
  }
  else if (temp = 156 )                //Second button limit
  {
    lcd.print("Button 2 Pushed");
  }

  else                                //If none of the previous buttons are pressed, then the third button must be pressed
  {
    lcd.print("Button 3 Pushed");
  }
  delay(100);                         //Delay for stability
}

The output sometimes is correct other times it is off. I think it has something to do with the circuit. Yet, I am scratching my head to find out what.

Michel Keijzers pointed out the issues you have in your code. But then
there is also an issue with your circuit: if you press any of the push
buttons, the analog input pin gets connected to one of the nodes of the
resistor ladder, and you get a well defined voltage reading. Good.
However, if none of the buttons is pressed, the input is not connected
to anything: it is floating. In this case the reading you get is
unpredictable, as it depends on parasitic influences of stray
capacitances, environmental noise, etc. You should modify your circuit
to make sure that the input voltage is well defined even when no button
is pressed.
Then, regarding the program, I recommend you remove everything after
Serial.println(temp);. Just make it work like this, and take note of
the readings you get in each case. Make sure they are consistent. Once
you know the values you expect, you can decide on the threshold to
apply, which should be about halfway between the typical readings. E.g.
if the two lowest values you get are 0 and 240, you would set a
threshold at 120.

Ok so if I wanted to get a well-defined voltage reading then I would tie the rightmost button to 5v Correct?

Good point, I stopped looking after I saw the problem in the code. Guess a combination of your and my solution is needed (doing your solution first).

So I am going to add in another picture which is the reason for my confusion

I understand now if I tie it low then I can get nice increasing values. Thanks for the help it really helped a bunch

You made a few mistakes with the three lines, first one being:
if (temp = 340)

First, the single '=' is an assignment operator instead of a comparing operator.  You want to use '=='.
However, you need to check if it is within a range, so you need to use <= (to see if it is smaller or equal). Also you need to put them in the correct order, so you get something like:
if (temp <= 156)
{
   // Process value if temp is smaller or equal than 156
}
else if (temp <= 340)
{
   // Process value if temp is smaller or equal than 340 (and higher than 156)
}
else if (temp <= 860)
{
   // Process value if temp is smaller or equal than 860(and higher than 340)
}
else
{
   // Process value if temp is higher than 860
}

Ok so that fixes some issues but the buttons are not giving nice values like that. When no buttons are pushed A0 is reading in 340 and the first button gives a value of 860. This makes me question the circuit itself.

Yes,  you first need to fix the problem that is solved by Edgar, then using my solution once you know the correct value ranges.

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


text:
Change delay function to millis function to play music
I'd like to write a code by changing the delay function in the music playing code to the millis function, do you know how?
#include "pitches.h"

// notes in the melody:
int melody[] = {
  NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
  4, 8, 8, 4, 4, 4, 4, 4
};

void setup() {
  // iterate over the notes of the melody:
  for (int thisNote = 0; thisNote < 8; thisNote++) {

    // to calculate the note duration, take one second divided by the note type.
    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = 1000 / noteDurations[thisNote];
    tone(8, melody[thisNote], noteDuration);

    // to distinguish the notes, set a minimum time between them.
    // the note's duration + 30% seems to work well:
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    // stop the tone playing:
    noTone(8);
  }
}

void loop() {
  // no need to repeat the melody.
}

Have you looked and understood the BlinkWithoutDelay example, that comes with the Arduino IDE? Have you tried some of the many tutorials about millis(), that are available on the web? If yes, what exactly are your problems in changing the code accordingly?

Does this answer your question? Playing Melody with Tone() without using delay()

Why do you want to get rid of the delay()? Your tone() call delays (blocks while playing) as well...

@DataFiddler, it is one of the basic examples in IDE, not a code by OP

I still consider my question "why?" valid. If you use blocking tone() calls, creating the "pizzicato" effect via a small delay() is straightforward.
The call noTone(8);is wrong (=unnecessary) here, BTW.
@chrisl's hint regarding BlinkWithoutDelay is good, if you change to non-blocking tone() creation as well. And if you need other things faster than a tone duration.

@DataFiddler, yes, there is an answer in the duplicate question


text:
Arduino Voltage Reading Problem
I was trying made a gear indicator for my bike, with manually sensing the gear shift.  But failed, cause my bike has no separate "neutral" wire, instead there is gear sensor in-built...!! But not gear-position indicator...!!
The in-built sensor gives different output voltage at every gear.
It sounds good that all I need is just an Pro-mini & OLED.
But, facing problem with the voltage reading on Pro-mini.
When I checking with normal multimeter, the output voltage is very stable.
I tried with the simple voltage reading code.
And added the voltages ranges as shows on multimeter.
Later Checked with Uno, Reading is quite stable (+- 0.02V).

But, Pro-mini voltage reading is too sensitive.
Sometimes, in same gear position getting high voltage difference.
So, in result I doesn't getting a stable voltage reading or gear display.

Need suggestion to make changes, so the pro-mini also read like the multimeter / Uno reads.
(Is this because of Pro-Mini doesn't have the Op-Amp in-built?)

And, also, Why the serial output is around 1.5V, while no input in A0...?

PS: I didn't use voltage divider, because, gear sensor output voltage is below 5V.

That shouldn't happen. I assume it's a 5V 16Mhz Pro mini. Make sure power doesn't go through the voltage regulator on the Pro Mini. Try a different Pro Mini. Try a different analog pin on the Pro Mini. Try out the UNO again, to make sure the sensors signal still stable. You could try averaging the results to get a more stable value, but that's more something you'd do if the signal isn't very stable.

Okay, now that's very quick... After searching & trying over weeks... Just changing the Analog pin works perfectly. (-_-) Feeling Dumb... Anyway, thank you very much...!!!

Another Question, The output gives around 1.5V without any input... Should I use 10K pull-down... or subtract that in programming?

as long as you get discrete values for each gear, i wouldn't try to rebalance the equation.

Ok. It stable, for no input at analog pin... But when I add the sensor output to A1, its again unstable. I connected multimeter & arduino together, no issue with multimeter, but the Pro-mini reading is messed up...!!!!!!

It's all OK now... I was using different grounds... After attaching it fully on bike power, it's working like charm... Thank you guys...


text:
Arduino Coding Issue
I'm running a water pump based on ultra sonic readings. Once the Ultra Sonic Sensor reads > 10 cm , I want the water pump to start until sensor reads < 5 cm. Would you please help me adjust the following code to meet my requirements.
void loop(){
 digitalWrite(trigPin,LOW);
 delayMicroseconds(2);
 digitalWrite(trigPin,HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin,LOW);
 duration=pulseIn(echoPin,HIGH);
 distance=(duration*0.034/2);
 if(distance>5){
   digitalWrite(motor,HIGH);
   delay(30000);
   digitalWrite(motor,LOW);
 } else {
   digitalWrite(motor,LOW);
 }
}

So what you're asking is:

If distance is greater than 10:

Turn on

If distance is less than 5:

Turn off

That's not hard to code, since you already have an "if" there that compares the distance.
 if(distance>5){
   digitalWrite(motor,HIGH);
   delay(30000);
   digitalWrite(motor,LOW);
 } else {
   digitalWrite(motor,LOW);
 }

becomes:
if (distance > 10) {
    digitalWrite(motor, HIGH);
}

if (distance < 5) {
    digitalWrite(motor, LOW);
}

See how there's a direct 1:1 correlation between the English I wrote at the top and the code below it? That's often a good way to understand code: write it out in plain English step by step what you want and what decisions you need to make - then there's usually a simple conversion from English to code.
The hardest part of learning to program is understanding the logic. Do that in English first and the writing of the code itself becomes so much easier.

Thanks. Two points, using the code above, if distance < 10, motor won't work.  I tried adding digitalWrite(motor, HIGH); before if statement but I didn't test it yet. Second, The motor keeps running on repetitive cycles I believe every time code loops. is that healthy?

If distance < 10 then the motor shouldn't work. You haven't specified that it should. You want it on for distance > 10 not < 10. If it's cycling on and off then distance is changing from greater than 10 to less than 5 repeatedly.

With Majenko's code, the motor won't turn on until the distance is > 10. Then it will stay on until the distance drops to < 5. That's what you wanted.

You might want to add a maximum time value as well, so that if your ultrasonic sensor fails with the pump on, it has an upper limit on how long the pump will run. That would require recording the millis() value at the moment you turn the pump on, and turning it off if the motor is on and the current value of millis() is far enough in the past.

@motionchannel: For reference, the behavior described by your prose and implemented in Majenko's code is called hysteretic control. Within the hysteresis band (5 – 10 cm) the pump is supposed to stay in whatever state is was previously set. Hysteresis is a very sensible way of avoiding the motor rapidly switching on and off. See for example Wikipedia: Hysteresis in engineering.


text:
ESP8266 with RTC DS1307 shield - WS2818B shield won't blink - I2C issue?
Dear Ladies and Gentlemen,
I'd like to let a LED blink base on the time of the day. So I took Wemos D1 mini and a WS2818B shield and a RTC DS107 Shield for the before mentioned ESP8266 model.
Based on my observation, I can let the LED blink on its own without starting the initialization of the RTC. As soon as I initialize the communication with the DS1307 shield, the LED shield won't translate any commands toward the desired behavior (e.g. the LED won't blink anymore).
What am I doing wrong?
I'm using the Ardunio IDE to program the D1 mini.
I stacked the shields and kept an eye on the pins to be sure I did wire everything the right way.
Libraries in use:
RTC: https://github.com/Makuna/Rtc
LED: Adafruit NeoPixel
Code:
// WIFI
#include <ESP8266WiFi.h>

// RTC
#include <RtcDateTime.h>
#include <RtcUtility.h>
#include <Wire.h> // must be included here so that Arduino library object file references work
#include <RtcDS1307.h>
RtcDS1307<TwoWire> Rtc(Wire);

// LED
#include <Adafruit_NeoPixel.h>
#define PIN        D2
#define NUMPIXELS 1
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ400);

int DELAYVAL = 1000; // Time (in milliseconds) to pause between pixels

void setup() {

  Serial.begin(57600);
  Serial.println();
  Serial.flush();

  setupLed();

  setupWifiConnection();

  setupRtc();

}

void loop() {

  pixels.clear(); // Set all pixel colors to 'off'
  pixels.show();   // Send the updated pixel colors to the hardware.
  delay(DELAYVAL); // Pause before next pass through loop

  pixels.setPixelColor(0, pixels.Color(0, 150, 0));
  pixels.show();   // Send the updated pixel colors to the hardware.
  delay(DELAYVAL); // Pause before next pass

}

void setupRtc () {

  Rtc.Begin();

  RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
  Serial.println();

  if (!Rtc.IsDateTimeValid())
  {
      if (Rtc.LastError() != 0)
      {
          // we have a communications error
          // see https://www.arduino.cc/en/Reference/WireEndTransmission for
          // what the number means
          Serial.print("RTC communications error = ");
          Serial.println(Rtc.LastError());
      }
      else
      {
          // Common Causes:
          //    1) first time you ran and the device wasn't running yet
          //    2) the battery on the device is low or even missing

          Serial.println("RTC lost confidence in the DateTime!");
          // following line sets the RTC to the date & time this sketch was compiled
          // it will also reset the valid flag internally unless the Rtc device is
          // having an issue

          Rtc.SetDateTime(compiled);
      }
  }

  if (!Rtc.GetIsRunning())
  {
      Serial.println("RTC was not actively running, starting now");
      Rtc.SetIsRunning(true);
  }

  RtcDateTime now = Rtc.GetDateTime();
  if (now < compiled)
  {
      Serial.println("RTC is older than compile time!  (Updating DateTime)");
      Rtc.SetDateTime(compiled);
  }
  else if (now > compiled)
  {
      Serial.println("RTC is newer than compile time. (this is expected)");
  }
  else if (now == compiled)
  {
      Serial.println("RTC is the same as compile time! (not expected but all is fine)");
  }

  // never assume the Rtc was last configured by you, so
  // just clear them to your needed state
  Rtc.SetSquareWavePin(DS1307SquareWaveOut_Low);
}

void setupLed () {

  pixels.begin();

  pixels.clear();
  pixels.show();
}

void setupWifiConnection () {

  WiFi.begin("some ap", "some password");

  Serial.print("Connecting");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
}

Can you check, if and where the code gets stuck? You can do this by inserting serial prints at several positions to track down the exact problem location

please describe what you observe ... add the description to your post, not to comments ... it looks like setupRtc should be generating some output to the serial monitor

According to your code, you’ve connected the Neopixel to D2. The RTC is an I2C device, so it’s also connected to D2. How is that supposed to work? The Neopixel isn’t an I2C device.
Move the Neopixel to a different pin that’s not used by anything else - so not D1. Try D3. Update your code to use D3. There may be other issues but at least you won’t be trying to use the same pin to talk to two very different devices.

Absolutely correct. What I oversaw was the fact the Neopixel LED shield is no I2C device. As suggested I wired the pin to D3 and it worked right away. Thank you @romkey.


text:
My two slave SPI setup on arduino not working correctly
I am trying to connect a DPS310 and an ADXL345 to my Arduino using 4 wire SPI. When the individually tested (i.e. each has its own script), the output is correct, however when the scripts are combined the ADXL output is garbage, but the DPS functions.
What we expect to see:
Temperature = 24.14 *C
Pressure = 857.88 hPa
X: -4  Y: 4  Z: 29

What we actually see:
Temperature = 24.14 *C
Pressure = 857.88 hPa
X: 0  Y: 0  Z: 0    // and does not change when tilted

When the DPS310 line is commented out, the ADXL works fine (this line is indicated in script)
The whole script (with the faulty line indicated):
#include <SparkFun_ADXL345.h>
#include <Adafruit_DPS310.h>

// ADXL obj
#define ADXL345_CS   9 // SPI pin
ADXL345 ADXL = ADXL345_CS; // Instantiate obj with CS pin
int x = 0, y = 0, z = 0;

// DPS obj
#define DPS310_CS   10 // SPI pin
Adafruit_DPS310 dps; // Instantiate obj (pin is set in setup)
sensors_event_t temp_event, pressure_event;

void setup() {
   Serial.begin(115200);
   while (!Serial) delay(10);

   // ADXL SETUP
   digitalWrite(ADXL345_CS, LOW); // START COMM
   Serial.print("ADXL345: ");
   ADXL.powerOn();
   delay(50);
   ADXL.setRangeSetting(16);
   ADXL.setSpiBit(0);
   ADXL.set_bw(ADXL345_BW_12_5);
   ADXL.setInterrupt(0x84, true);
   ADXL.setAxisOffset(0, 0, 5);
   ADXL.readAccel(&x, &y, &z);
   if(x != -1 && y != -1 && z != -1) {
     Serial.println("[PASSED]");
   } else {
     Serial.println("[FAILED]");
   }
   digitalWrite(ADXL345_CS, HIGH); // END COMM

   // DPS SETUP
   digitalWrite(DPS310_CS, LOW); // START COMM
   Serial.print("DPS310: ");
   if (! dps.begin_SPI(DPS310_CS)) { /////////////////PROBLEM LIES HERE//////////////////
      Serial.println(" [FAILED]");
   }
   Serial.println(" [PASSED]");

   dps.configurePressure(DPS310_64HZ, DPS310_64SAMPLES);
   dps.configureTemperature(DPS310_64HZ, DPS310_64SAMPLES);
   digitalWrite(DPS310_CS, HIGH); // END COMM
}

void loop() {
    digitalWrite(ADXL345_CS, LOW);
    ADXL.readAccel(&x, &y, &z);
    digitalWrite(ADXL345_CS, HIGH);

    digitalWrite(DPS310_CS, LOW);
    dps.getEvents(&temp_event, &pressure_event);
    digitalWrite(DPS310_CS, HIGH);

    Serial.print("Temperature = ");
    Serial.print(temp_event.temperature);
    Serial.println(" *C");
    Serial.print("Pressure = ");
    Serial.print(pressure_event.pressure);
    Serial.println(" hPa");

    Serial.print("X: ");
    Serial.print(x);
    Serial.print("  Y: ");
    Serial.print(y);
    Serial.print("  Z: ");
    Serial.println(z);

    delay(50);
}

I think the fault might lie in the classes written for these devices, for instance maybe they were written for single SPI device or have different frequencies/modes? (I'm probably wrong though XD). I have not yet tried to setup the SPI for each device manually (programming commandment: do no reinvent the wheel), so any help would be greatly appreciated.

set CS pin of the second device HIGH before initializing the first device

@Juraj I just tried that and it failed. Even tried to put both HIGH as well as delay for 2s before initializing anything

The ADXL345 uses SPI_MODE3 and DPS310 the SPI_MODE0. The libraries for these devices don't use SPI transactions, but set the settings only in begin(), so they can't be used together.
Your options to solve this is either to put one sensor on software SPI or to put one or both sensors on I2C.
The ADXL345 can be used as I2C device. Its library supports I2C with the constructor when no parameters are provided. Does your module have an option to wire it to I2C?
The Adafruit library for DPS310 has built-in software SPI, so you can use it with any set of pins. And it too supports I2C.

I was afraid of that, any idea how I can modify the libraries to operate with each other? I tried to write a basic SPI script to do the transactions by following what the libraries did, however the libraries are far to complicated for me and so it was to no avail. Or should I rather try to implement my own independent SPI script (keeping in mind I'm very new to this)?

@newt, I enhanced the answer

Thanks, switched the ADXL to I2C and kept DPS in SPI mode and it worked!


text:
Can't Upload Sketches to Arduino Nano Every
first-time builder here.  I just got my Arduino Nano Every in the mail from Mouser, and I'm trying to upload a modified version of the blink example to my new brand-new board.  However, every time I try to upload a sketch, the IDE just spins its wheels for around 5 minutes before giving up.  I've been trying to look through similar questions and haven't found anything that has solved my issue.  My OS is Windows 10.
Here's a snippet of the log (I've turned on verbose reporting for compilation and upload):
Arduino: 1.8.13 (Windows 10), Board: "Arduino Nano Every, None (ATMEGA4809)"
…
Forcing reset using 1200bps open/close on port COM1
…
         Using Port                    : COM1
         Using Programmer              : jtag2updi
         Overriding Baud Rate          : 115200
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
An error occurred while uploading the sketch

Here are the settings I'm currently using:

Board is set to Arduino Nano Every, using Arduino MegaAVR Boards
1.8.6
Registers emulation:  none (ATMEGA4809)
Port:  COM1 (there are no other options that appear for me, and no
other port pops up in the device manager when I plug the board in)
Programmer:  Onboard Atmel    mEDBG (UNO WiFi Rev2)

Here's what I've tried so far:

Disabled antivirus
Uninstalled and reinstalled Arduino IDE
Turning on registers emulation
Restarting computer
Resetting board
Using different USB cables
Using different USB ports (3.0 and 2.0)
Manually installing Arduino drivers to Windows (Windows said the most
up-to-date drivers were already installed after I specified the
directory to search in)
Nothing is connected to the board.
The pin-13 LED blinks, so there's a bootloader on the board.
I've reset the board before uploading.

Any help would be very much appreciated.  I'm about to give up and just return the board and swap it for a different one.

see in Device Manager the USB devices and the COM ports if the descriptions match. did you try a different USB cable?

@Juraj I'm not sure what you mean by whether the USB devices and COM ports match; their names, descriptions under "details" tab, and location are all different.  I've tried two different cables, yes.

so if you disconnect the Every, the COM1 disappears and if you connect the Every the COM1 is back?

No, COM1 is listed in the device manager regardless of whether the Every is plugged in or not.

A new usb port should pop up when you plug in the Arduino board.  If it doesn't then there is a hardware issue (port or cable or device).  Also, i don't think that jtag is the proper programmer selection.  AVRISP mkII is default programmer I believe.

that programmer selection is ignored for Serial upload. the upload output in Question is right for Every. COM1 is no the Every. look in Device Manager for unknown USB devices

I've just tried with another different cable on another different port on my PC.  The same issue persists, so I suspect that the fault is not with the cable or USB port.  There is no unknown USB device listed under device manager.

try to reistall the megaavr boards package

I've already done that.  When I uninstalled the arduino IDE I uninstalled all associated files, including board packages.

uninstalling the IDE doesn't uninstall the boards packages

I'm aware of that.  I manually deleted all Arduino files everywhere I found them on my computer; original installation, documents library, and appdata.

Here is a trick I use on some boards but first be the baud rate is the same in the terminal as in the sketch (Serial.begin(115200). If so then remove everything then put a jumper between ground and reset. Then put a jumper between TX and RX (pin o and pin 1 on uno). launch the IDE and what you type in the console should be echoed back to you. If this works the hardware is connected fine.

I was getting the same error when I got my brand new Nano Every.
I had Registers emulation: ATMEGA328
I changed it to None (ATMEGA4809) and it uploaded without problems.
I'm on ubuntu 18.04, and this is after the IDE prompted me to install the megaAVR boards library (1.8.7) of course.

the emulation selection has nothing to do with the upload. it was something else.

Perhaps. Nevertheless I was having trouble uploading my sketch to my arduino nano every. I googled the error and landed on this question. After reading the question and answers, I realized emulation could be my problem, which it was. This answer was an attempt to aid others with my same problem.


text:
Simple ModBus Master function 15
I have a simple setup with arduino Nano as slave and a arduino Mega as master
Can anyone explain how the function 15
FORCE_MULTIPLE_COILS
Works
i have been running some test on this
and cant figure out how to use the
local_start_address
is this the data to read from
or
is it a pointer to another File
modbus_construct(&packets[PACKET1], 1, 15, 1, 8, 1021);
dec 8 = (no_of_registers = packet->data)  // number of coils
so frame 6 = 1 (frame[6] = no_of_bytes;) // number of bytes more
dec 1021 = (packet->local_start_address)
the dec 1021 and 65565 seams to work ????
but makes no sense to me in binary format ?
Here is
part of CPP file:
enter code here

unsigned char construct_F15()
{
   // function 15 coil information is packed LSB first until the first 16 bits are completed
  // It is received the same way..
  unsigned char no_of_registers = packet->data / 16;
  unsigned char no_of_bytes = no_of_registers * 2;

  // if the number of points dont fit in even 2byte amounts (one register) then use another register and pad
  if (packet->data % 16 > 0)
  {
    no_of_registers++;
    no_of_bytes++;
  }

  frame[6] = no_of_bytes;
  unsigned char bytes_processed = 0;
  unsigned char index = 7; // user data starts at index 7
   unsigned int temp;

  for (unsigned char i = 0; i < no_of_registers; i++)
  {
    temp = register_array[packet->local_start_address + i]; // get the data

frame[index] = temp & 0xFF;

    bytes_processed++;

    if (bytes_processed < no_of_bytes)
    {
      frame[index + 1] = temp >> 8;
      bytes_processed++;
      index += 2;
    }
  }
   unsigned char frameSize = (9 + no_of_bytes); // first 7 bytes of the array + 2 bytes CRC + noOfBytes
   return frameSize;
}

this question appears to be unrelated to the Arduino

i found it
it is the
temp = register_array[packet->local_start_address + i]; // get the data
in the ccp file
register_array[packet->local_start_address + i]
its pointing to the wrong location... register_array??
supersized no one has noticed this as long as the simple modbus master for adruino
has been used ?
or i have a bad CPP file ?
i have temp corrected this by replacing with
unsigned char construct_F15()
{
    // function 15 coil information is packed LSB first until the first 8 bits are completed
    unsigned char frameSize = 10;
    unsigned char temp;
    frame[6] = 1;
    frame[7] = packet->local_start_address ^ 0XFFFF;
    return frameSize;
}

works (0 = off / 255 = on)
modbus_construct(&packets[PACKET1], 1, 15, 1, 8, 0); // 1 thru 8 = off
modbus_construct(&packets[PACKET2], 1, 15, 1, 8, 255); // 1 thru 8 = on


text:
which kind of data are store If i terminate the call in sim800?
I'm working in SIM800 for DTMF based project.
I want to know which kind of data are stored in the buffer during termination of call in SIM800.
How to find if call was disconnected in SIM800?
Also please suggest some AT-COMMAND tester software and DTMF codes for my reference.


text:
Arduino Wont Run Program at 4 Mhz
I want my Arduino Nano to consume as little power as possible, so I have been lowering the clock frequency with CLKPR from the default 16 MhZ speed. I successfully ran the program at 8 Mhz by setting CLKPR=0x01, but am unable to see any output in the serial monitor or any sign of the program running successfully at 4 Mhz (CLKPR=0x02). My project involves transmitting data between Arduino and an Android via Bluetooth, and I can see the receive LED blink on the Nano at 4 Mhz. However, for some reason it does not step through the code, and Serial monitor wont print statements. My Nano is a cheap knockoff so it's possible the chip is not designed to run at 4 Mhz. I've also tried the same test on a knockoff Uno and got the same results. Please let me know if you have any suggestions. I've included the code I'm trying to run:
int state = 0;
int stateData = 0;
int ultraPin = 10;
int trigPin = 11;    // Trigger
int echoPin = 12;    // Echo
long duration, cm;
unsigned char inches;
unsigned long timer;

void setup() {
  CLKPR = 0x80;
  CLKPR = 0x02; // 4 Mhz
  pinMode(ultraPin, OUTPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  digitalWrite(ultraPin, LOW);
  Serial.begin(9600*4); // multiply baud rate by inverse of clock frequency factor
}

void loop() {
  if(Serial.available() > 0){ // Checks whether data is comming from the serial port
    stateData = Serial.read();
    if (stateData == 48){ // ON signal from phone
      Serial.write(50); // confirm signal received
      timer = millis();
      digitalWrite(ultraPin, HIGH);
      while (true){
          digitalWrite(trigPin, LOW);
          delayMicroseconds(2/4);
          digitalWrite(trigPin, HIGH);
          delayMicroseconds(10/4);
          digitalWrite(trigPin, LOW);
          pinMode(echoPin, INPUT);
          duration = pulseIn(echoPin, HIGH);
          cm = (duration / 2) / 29.1;   // Divide by 29.1 or multiply by 0.0343
          inches = (duration / 2) / 74; // Divide by 74 or multiply by 0.0135
          Serial.write(inches);
          delay(50/4);
          stateData = Serial.read();
          if (stateData != 49){
            // receipt from android
            unsigned long timeElapse = millis() - timer;
            if (timeElapse > 5000/4) {
              break;
            }
          }
          else {
              // reset the timer
              timer = millis();
            }
      }
    }
 }
 delay(200/4);
}

delayMicroseconds(2/4); is just as calling delayMicroseconds(0); Not sure if this is a valid argument for this function.

How are you programming the Nano? How do you set the correct fuses for 4MHz? Are you using an external crystal or the internal oscillator?

I am using the internal oscillator. I don't know where the fuses are and didn't think I needed to touch hardware

A Nano is normally clocked at 16 MHz off a ceramic resonator. If you want to use the internal oscillator (which runs at roughly 8 MHz), you have to use an ISP programmer to change the fuses. CLKPR allows you to change the prescaler at run time, but not the clock source.

Not sure if changing the prescaler modifies power consumption.

@EdgarBonet But I could change prescaler to 8 Mhz at run time. Or was it still clocked at 16 Mhz?

As I said before: at run time you can change the prescaler (e.g. to divide the frequency by 4), but not the clock source (you cannot switch from the 16 MHz ceramic resonator to 8 MHz internal RC oscillator).

ok, so i guess what you are saying is changing the prescaler doesnt do anything without changing the clock source.

I think what I am looking for is sleep mode with some interrupt when serial message is received. Thanks for the help, my problem is resolved: https://www.megunolink.com/articles/wake-on-serial-message/#:~:text=Almost%20every%20digital%20pin%20on,interrupt%20to%20wake%20the%20device.


text:
Arduino + Codeblocks C++
I'm writing the code for my Arduino board using Code::Blocks editor. When I create a new project, there is AVR Project and Arduino Project under Projects category. Which one do I select?

@chrisl - This looks like an answer. Please make it an answer. Comments on questions are for clarifying the question. To "answer" like this make the SE software think no-one has answered.

You can select, what you want. If you want to build an Arduino Project, you should choose "Arduino Project". If you don't want to use the Arduino Framework, you can choose "AVR Project".

how do I set the path to arduino.h and other headers?

Under project build options, Arduino UNO (which is the version I have) I can see my path is set to $(ARDUINO_DIR)\libraries but isnt compiling


text:
why is "if" slow?
I am new to the Arduino world and I hope I can find a solution here. The code below functionally works ok. The problem I have is, at line 45 I've inserted an if statement to change dac_value. It is very slow while serial and all that is outside if works fast/fine... What would be a solution to make it fast? Tried if - else if and also while... result is the same. Hope someone can help. Thank you.
{
#include <Arduino.h>
#include <Wire.h>
// #include <LiquidCrystal_I2C.h>
#define MCP4725 0x61
#define MCP4725B 0x60
unsigned int val;
byte buffer[3];
byte buff[3];

int ClockPinV = PB1;
int ClockPinA = PA6;
const int currsensPin = PA3;
const int voltsensPin = PA2;

void setup()
{
  Serial.begin(115200);
  pinMode(currsensPin , INPUT_ANALOG);
  pinMode(voltsensPin , INPUT_ANALOG);
  pinMode(ClockPinV , INPUT);
  pinMode(ClockPinA , INPUT);
  Wire.begin();
}

int val0 = 1024;
int val1 = 4096;
volatile int dac_value = 0;

void loop()
{
  analogReadResolution(12);

  volatile int svolt = analogRead(ClockPinV);
  volatile int scurr = analogRead(ClockPinA);
  volatile int set_voltage = (3.3/4096)*svolt;
  volatile int set_curr =  (3.3/4096)*scurr;
  volatile int securr = analogRead(currsensPin);
  volatile int real_curr = (3.3/4096)*securr;
  volatile int sevolt= analogRead(voltsensPin);
  volatile int real_output2 = (3.3/4096)*sevolt;

if(real_curr < set_curr){
    if(set_voltage > real_output2)
    {
      dac_value = dac_value + 1;
    }
    if(set_voltage < real_output2)
    {
      dac_value = dac_value - 1;
    }
  }
  else if(real_curr > set_curr)
  {
    dac_value --;
  }

  dac_value = constrain(dac_value, 0, 2673);
  buffer[0] = 0b01000000; //control byte
  buffer[1] = dac_value >> 4; //MSB 11-4 shift right 4 places
  buffer[2] = dac_value << 4; //LSB 3-0 shift left 4 places

  Wire.beginTransmission(MCP4725); //address device
  Wire.write(buffer[0]); //pointer
  Wire.write(buffer[1]); //8 MSB
  Wire.write(buffer[2]); //4 LSB
  Wire.endTransmission();

  // val1 = constrain(val1, 0, 2673);
  buff[0] = 0b01000000; //control byte
  buff[1] = svolt >> 4; //MSB 11-4 shift right 4 places
  buff[2] = svolt << 4; //LSB 3-0 shift left 4 places

  Wire.beginTransmission(MCP4725B); //address device
  Wire.write(buff[0]); //pointer
  Wire.write(buff[1]); //8 MSB
  Wire.write(buff[2]); //4 LSB
  Wire.endTransmission();

  Serial.println("=============================");
  Serial.println("=============================");
  Serial.println("========= Volt Test =========");
  Serial.println("test: " + String(set_voltage));
  Serial.println("      " + String(real_output2));
  Serial.println("======== Current Test =======");
  Serial.println("test: " + String(set_curr));
  Serial.println("      " + String(real_curr));
  Serial.println("=============================");
  Serial.println("=============================");
}
}

How do you see, that its the if statements, which is slow? Are you sure, that your problem doesn't lie at another place? And what means "slow" in this case?

I asume that... tride a pot connected to a analog pin and output directly to dac - it was working fast...

Why are you using volatile everywhere? What do you mean by "slow" and "fast"? How have you measured that?

"if" isn't slow, just for your info. The things you do inside the "if" will be affecting what the rest of the code is doing. For example, if you say "if it is Monday, sleep for 4 hours" then the "if" isn't the problem, it is "sleep for 4 hours" that is.

It's not the if statement itself that makes your code slow. But it may well be the sketch behaving differently than you expect which makes you believe it was slow. Compare and print timestamps to determine how long the execution of certain parts takes.

if I read a pot on a analog pin and write to dac in serial print i can see it changing the dac value as i spin the pot. In the same time if the conditions in the if are met and i increase the voltage i can see dac_value incrementing very slow. it takes seconds until it reaches the set value...

as I said... new here so pleas don't jump at me. I agree that my problem could be  something else - that is why i posted. hopefully to find a solution and to learn something new :P

No-one is attacking you. We are just curious as to some things about your code. If you can explain, we can better advise you.

if the conditions in the if are met and i increase the voltage i can see dac_value incrementing very slow. - you mean, the serial prints are slower?

yes, but just the dac reading dac_value. If I print anything else + dac_value everything updates fast except the dac_value...

I didn't understand that.

From your code it seems, that you are trying to do a control loop (outputting a control signal via DAC, reading correlated values back and change the control signal based on that. The behavior of such control loops are not always obvious. I'm rather sure this is one of these cases. So please describe, how everything is connected, what you are trying to control and what exactly you expect to happen. A schematic or wiring diagram (and maybe a good image of your real circuit) would also help here

try if (real_curr <= set_curr){

int ClockPinV = PB1;  int ClockPinA = PA6;  is nonsense, BTW. pinMode and analogRead do work with Arduino pin numbers.

@DataFiddler: made it with rotary enc first. Removed and now using pot but did not change pin name... also board is stm32f103

added full main.cpp to github. https://github.com/mariusdp/psu_test.git

The if statements (plural) you posted on GitHub are a lot different to the one you posted above. They contain a lot of of print commands to the LCD, so I think this is what is slowing your code down. It's a fair effort at nicely formatting the output on the display, but is rather convoluted.
Here is a simplified version which writes to the LCD as little as possible (2 cursor moves and 2 prints). The formatting of the string is done in Arduino memory before sending it out to the LCD as one complete string.
I couldn't understand your variable names, so I've renamed them.
setup()
I moved the analogReadResolution(12) from loop() to setup() for a slight performance gain.
void setup()
{
  pinMode(currsensPin , INPUT_ANALOG);
  pinMode(voltsensPin , INPUT_ANALOG);
  pinMode(voltPin, INPUT_ANALOG);
  pinMode(currPin, INPUT_ANALOG);
  Wire.begin();
  lcd0.begin(20, 4);
  lcd0.backlight();

  analogReadResolution(12);  // Moved from loop(). Only need to call it once.

  Serial.begin(115200);
}

loop()
I've grouped the analogue reads together to give a smaller sampling window. Since it's for a control loop, these values should ideally be sampled at exactly the same time and synchronised to a clock (e.g. in hardware).
float real_current_offset = 0;

void loop()
{
  //
  // Obtain data samples as close together as possible with no interrupts.
  //
  cli();  // Disable interrupts.
  int svolt = analogRead(voltPin);
  int scurr = analogRead(currPin);
  int raw_voltage = analogRead(voltsensPin);
  int raw_current = analogRead(currsensPin);
  sei();  // Enable interrupts.

  // Calculate set voltage and current.
  float set_voltage = (3.3 / 4096) * svolt;
  float set_current =  (3.3 / 4096) * scurr;

  // Calculate real voltage and current.
  float real_voltage = (3.3 / 4096) * raw_voltage;
  float real_current = raw_current * (3.3 / 4096) - real_current_offset;
  float real_current_ma = real_current * 1000.0;

  int dac_value = dac_value
              + (real_current <= set_current) * (set_voltage > real_voltage)
              - (real_current < set_current) * (set_voltage < real_voltage)
              - (real_current > set_current);

  buffer[0] = 0b01000000;
  buffer[1] = dac_value >> 4;
  buffer[2] = dac_value << 4;
  Wire.beginTransmission(MCP4725);
  Wire.write(buffer[0]);
  Wire.write(buffer[1]);
  Wire.write(buffer[2]);
  Wire.endTransmission();

  DisplayDataOnLcd(set_voltage, set_current, real_voltage, real_current);
}

DisplayDataOnLcd()
I created a new function for displaying the data on the LCD. It's good practice to break the code down into smaller functional blocks.
void DisplayDataOnLcd(const int set_voltage, const int set_current, const int real_voltage, const int real_current)
{
  Serial.println("\nLCD Data Display");

  // Define the formats for printing to the LCD.
  const char *data_format_set  = "Set : %s V %s mA";
  const char *data_format_real = "Real: %s V %s mA";
  char voltage_str[10];
  char current_str[10];
  char data_str[30];

  // Format the set voltage and current, and display on the LCD.
  dtostrf(set_voltage, 6, 3, voltage_str);
  dtostrf(set_current, 6, 3, current_str);
  sprintf(data_str, data_format_set, voltage_str, current_str);
  lcd0.setCursor(0, 0);
  lcd0.println(data_str);
  Serial.println(data_str);

  // Format the real voltage and current, and display on the LCD.
  dtostrf(real_voltage, 6, 3, voltage_str);
  dtostrf(real_current, 6, 3, current_str);
  sprintf(data_str, data_format_real, voltage_str, current_str);
  lcd0.setCursor(0, 1);
  lcd0.println(data_str);
  Serial.println(data_str);
}

Thank you. Will try later today. Q: I do not know lot of things so be patient with me please. On the LCD the only value that updates slow is the reading from dac (dac_value), all else updates fast... That is why I assumed I am doing something wrong... . The test I made was - pot on a analog input and the reading sent over i2c to dac converter - output from converter to another adc pin as feedback and feedback to LCD trough i2c ==> this setup was updating in real time (or fast enough to perceive as real time and be able to work with it)...

I'm struggling to understand your control loop. Could you post a full schematic of it please? Edit your original post to add an image. I can't see how writing 3 bytes to the MCP4725 DAC at the standard 100 kbps is drastically slowing down the loop. Try adding debug statements to the loop to Serial.println() the time of each iteration.

DAC connected to analog pin controlled by pot or enc and "if" conditionals... the DAC controls a mosfet driver IC. Divider for voltage monitor (real_voltage) and made low side current sensor from LM358 and shunt for "real_current". The way has to work is if set_volt < real_volt the DAC output should get lower... it does that but is to slow. In a short would smoke (output is up to 100VDC 20Amp LINEAR) Before u ask - linear is less noisy and a lot cheaper to build than buy + using trafo I see it silly to make it switch mode. :P THANK YOU!

Nice answer guy, I think your assumption was right. Every I2C liquid crystal display I have used with arduino are dreadfully slow for w.e reason. +1


text:
Saving a value with a click
I have a rotary encoder and 2 buttons to a. Store the encoder value b. Reset the encoder value to 0. The reset buttons work fine the issue is with the set/store button. Where the value changes without pressing the button as well. Any help is appreciated.
int encoderPin1 = 2;
int encoderPin2 = 3;

volatile int lastEncoded = 0;
volatile double encoderValue = 0;
long lastencoderValue = 0;

int lastMSB = 0;
int lastLSB = 0;

// buttons
int resetPin = 43;
int settPin = 22;
int val = 0;
int val2 = 0;

//reset-set
double setValue = 0.0;
double resetValue = 0.0;

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

  pinMode(encoderPin1, INPUT);
  pinMode(encoderPin2, INPUT);

  digitalWrite(encoderPin1, HIGH);
  digitalWrite(encoderPin2, HIGH);

  attachInterrupt(0, updateEncoder, CHANGE);
  attachInterrupt(1, updateEncoder, CHANGE);

  //buttons
  pinMode(resetPin, INPUT);
  pinMode(settPin, INPUT);

  pinMode(LED_BUILTIN, OUTPUT);

}
void loop(){
  //Serial.println(encoderValue); //print
  delay(1000);

  //
val = digitalRead(settPin);
if (val == HIGH){
  set();
  digitalWrite(LED_BUILTIN, HIGH);
}

/*val2 = digitalRead(resetPin);
if (val2 == HIGH){
  //reset
  encoderValue = resetValue;
  Serial.println(encoderValue);
  Serial.print("reset");
  delay(100);
}*/

}

void set(){
  //set the value
  setValue = encoderValue;
  Serial.println(setValue);
  Serial.print("setValue");
  delay(100);
}

 void updateEncoder(){
  int MSB = digitalRead(encoderPin1);
  int LSB = digitalRead(encoderPin2);

  int encoded = (MSB << 1) |LSB;
  int sum = (lastEncoded << 2) | encoded;

  if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
  if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;

  lastEncoded = encoded;
  }

what is the problem with your code?  ... are you getting errors?

Do you use external pulldown resistors?

the encoder does not require an interrupt on both signal pins ... enable an interrupt on raising (or falling)  on one signal pin ... the state of the other pin at the time of the interrupt signifies the direction of rotation

thank you for your suggestion. The issue isn't with the code but was with the button. I changed the button and it worked fine. Thanks for the help!


text:
Adafruit/Arduino SAMD BSP package and adding SAME51 compatibilty
I am trying to make a SAME51 variant of an arduino board, in the end I would like to have an arduino compatible board, BSP, and library for controlling canbus.
I have already gone through some things, but I believe I need a slight bit of guidance for the next step, mostly just reference files.
What I have done so far is fork the adafruit SAMD BSP and added a variant. Since the normal Bossa does not recognize my CPU ID I had to add it and recompile bossa. I also went ahead and made a UF2 style bootloader and a corresponding windows driver with matching PIDs/VIDs. At this point I had a working arduino board, but it still thinks it's a SAMD51, not a SAME51. Asking for anything to do with can leads to missing references, which makes sense since SAMD does not have CAN (but it's in DFPs?)
So finally I decided to edit boards.txt again and change the build flag from -D__SAMD51G19A to SAME51G19A. I also found SAME51 DFP online and added them to arduino/tools/CMSIS-Atmel, but this is just me guessing. I also used the DFP to build the UF2 bootloader previously. This breaks everything and if I had to guess from looking the compiler is missing the DFP and everything is very upset about that.
Earlier I had found a version of what I am after, except for a SAMC21 and not a SAME51. I thought the can peripheral was the same for each, so this should be an easy port besides maybe configuring the gclk since those are different from M0 to M4. If you compare DFPs, both are identical as far as CANBUS is concerned, at least at that level.
But, using this code and the SAMC21 BSP referenced in the readme will compile!
https://github.com/hugllc/samc21_can
Is it something to do with adafruit fork using CMSIS 5.4 and arduino using CMSIS-Atmel 1.2.0?
Thank you in advance for any and all tips!

https://arduino.stackexchange.com/questions/54484/adding-a-custom-board-to-the-arduino-ide/60660#60660

I have that part worked out, and it works fine for the SAMC21. When compiling for SAME51 all definitions are missing. I believe the issue is Arduino SAMD core has compile support for SAMC21 in /arduino15/packages/arduino/tools/cmsis-atmel/1.2.0.../samc21. By default there is no same51, so using SAME51G19 as a build flag fails.
I don't know how to add support for same51, nor am I even sure the adafruit fork uses the same compiler tools in the first place. I think that's where I'm stuck.

and if you reference the Adadruit BSP with SAMD51 support? https://github.com/adafruit/ArduinoCore-samd

That is the initial fork of the BSP I modified, not the official arduino BSP. I still have the official core installed because the Adafruit BSP references many of the arduino/tools/ files.

I think I may have made it work. I am not certain, but I think any sam.h defines in the BSP point to CMSIS-ATMEL. The default does not have same51 support, and just adding the files isn't enough. Have to edit the sam.h files to make sure the required files are included.


text:
Connect and detect multiple arduinos using firmata
i am trying to connect several arduinos to usb ports and have the abillity to define between them.
i added Firmata.attach function on the arduino board. how do i call it from my python script?
thank you
#define BOARD_NAME '1'
void readName() {
      Firmata.sendString(BOARD_NAME);
    }

void setup()
{
  Firmata.attach(READ_NAME, readName);
  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);

  Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
  Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
  Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
  Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
  Firmata.attach(SET_PIN_MODE, setPinModeCallback);
  Firmata.attach(SET_DIGITAL_PIN_VALUE, setPinValueCallback);
  Firmata.attach(START_SYSEX, sysexCallback);
  Firmata.attach(SYSTEM_RESET, systemResetCallback);

  // to use a port other than Serial, such as Serial1 on an Arduino Leonardo or Mega,
  // Call begin(baud) on the alternate serial port and pass it to Firmata to begin like this:
  // Serial1.begin(57600);
  // Firmata.begin(Serial1);
  // However do not do this if you are using SERIAL_MESSAGE

  Firmata.begin(57600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for ATmega32u4-based boards and Arduino 101
  }

  systemResetCallback();  // reset to default config
}

with pyfirmata.


text:
My motor driver gets stuck in either high or low with a certain speed super randomly. Motor output stops going based on accelerometer input
Running a DC motor(6.5A max input), motor driver (MD10C 7Amp peak output), and arduino Mega.
Basically, I am creating a stabilized object based on the accelerometer's input. It works great but all of a sudden, very randomly, it glitches and gets stuck in whatever mode it was in last, so if it was motor A HIGH and motor B LOW at speed 200, itll just do that and I have to unplug it, put in a blank code, then my code again, then start it, itll work great then do it all over again. The time it takes for it to glitch out is random, I can't seem to find any patterns to it.
here is my code
//Code for accelerometer controlling an encoded DC
#include <Encoder.h>
#include <Wire.h>
#include <MPU6050.h>
#include <QueueArray.h>

//Class to read the encoder
Encoder myEnc(19,18);

//I2C address of the MPU-6050
const int MPU_addr=0x68;

const uint16_t t1_load = 0;

// Timer1 compare value:
// Clock frequency / Prescaler / Required frequency = Compare value
// 16 MHz          / 64        / 200 Hz              = 1250
const uint16_t t1_comp = 1250;

// Buffered data for sending/receiving to/from the ISR
volatile bool isr_flag = false;  //Used to flag when the ISR when triggered
volatile unsigned long isr_time = 0;  //Input updated by ISR
volatile byte isr_motor_direction; //Output calculated and updated in loop()
volatile byte isr_motor_speed = 0; // Output calculated and updated in loop()

//initializing the MPU6050 (accel/gyro input)
MPU6050 sensor;

//accerleromter in the y direction
int16_t AcY;
//not using
int16_t AcX, AcZ, GyX, GyY, GyZ, Tmp;

//new varible for mapping the accelerometer to degrees
int yAng;

//Variables to create PID method
int currentTheta;
float error;
int dt = 5;
long integral=0;
long deriv;
int previousError;

//accel on light, always want it at 0
int setpoint = 0;

//change speeds of the motor
#define MOTOR_SPEED_PIN    3
//change direction of the motor
#define MOTOR_DIRECTION_PIN   2
#define MOTOR_DIRECTION_CW    LOW
#define MOTOR_DIRECTION_CCW   HIGH

void setup()
{
  //Disable global interrupt
  cli();

  // Reset Timer1 Control Reg A
  TCCR1A = 0;

  // Set CTC mode
  TCCR1B &= ~(1 << WGM13);
  TCCR1B |= (1 << WGM12);

  // Set to prescalar of 64
  TCCR1B &= ~(1 << CS12);
  TCCR1B |= (1 << CS11);
  TCCR1B |= (1 << CS10);

  // Reset Timer1 and set compare value
  TCNT1 = t1_load;
  OCR1A = t1_comp;

  // Enable Timer1 compare interrupt
  TIMSK1 = (1 << OCIE1A);

  // Enable global interrupt
  sei();

  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);

  Serial.begin(9600);

  pinMode(MOTOR_SPEED_PIN, OUTPUT);
  pinMode(MOTOR_DIRECTION_PIN, OUTPUT);

  sensor.initialize();
}

void loop()
{
    //Begin critical section
    //

    cli();
    bool flag = isr_flag; //Copy the ISR flag
    isr_flag = false; //Reset the ISR flag
    sei();

    //
    //End critical section

    if (flag == true)
    {
      DebugMsgTime("PID algorithm begin");

      //Begin critical section
      //

      //Getting a copy of the data that has been modified by the ISR
      cli();
      unsigned long time = isr_time;
      sei();

      //
      //End critical section

      static unsigned long previous_time = 0;
      previous_time = time;

      //Wire reading

      Wire.beginTransmission(MPU_addr);
      Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
      Wire.endTransmission(false);
      Wire.requestFrom(MPU_addr,14,true);

      //reading each of the 6 axis's of the MPU6050 and the temp
      AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
      //Only using AcY
      AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
      AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
      Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
      GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
      GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
      GyZ=Wire.read()<<8|Wire.read();

      //mapping AcY to yAng from accel units to degrees
      yAng = map(AcY, -17000, 17000, -90, 90);

      //Calculate motor parameters locally
      long pos = PID(yAng);
      byte motor_direction = pos > 0 ? MOTOR_DIRECTION_CW : MOTOR_DIRECTION_CCW //make sure that this is correct
      pos = abs(pos);
      pos = constrain(pos, 0, 100);
      byte motor_speed = map(pos, 0, 100, 0, 200);

      //Begin Critical Section
      //

      // Update the ISR data ready for output at the next interrupt.
      // This keeps the outputs locked to each other and synchronised to the interrupt.
      cli();
      isr_motor_direction = motor_direction;
      isr_motor_speed = motor_speed;
      sei();

      //
      //End Critical Section

      DebugMsgTime("PID algorithm end");
    }
}

ISR(TIMER1_COMPA_vect)
{
  //Output
  digitalWrite(MOTOR_DIRECTION_PIN, isr_motor_direction);
  analogWrite(MOTOR_SPEED_PIN, isr_motor_speed);

  //Input
  isr_time = micros();
  isr_flag = true;
}

//PID loop to find error between setpoint and currentTheta
long PID(int currentTheta)
{
    error = setpoint - currentTheta;
    integral = integral + error*dt;
    deriv = (error-previousError)/dt;
    long output = 1.9 * error; + .8 * integral + 40 * deriv; //2.8,.7,70 //1.3,.8,40
    previousError = error;
    return output;
}

void DebugMsgTime(const char *msg)
{
  static unsigned long previous_time = 0;
  unsigned long time = micros();
  unsigned long delta_time = time - previous_time;
  previous_time = time;

  Serial.println(msg);
  Serial.println(time);
  Serial.println(delta_time);
}

What is that while loop for? I cannot see any sense in it, considering, that you don't have any other code inside void loop(), but outside of the while loop, and void loop() is already looping. Also you seem to be reading the raw accelerometer data, which can be quite noisy. You can use a complementary filter to do sensor fusion with the gyroscope and get more stable results. And lastly you are using a library for the MPU, but then you are reading the data directly via Wire, instead of using the libraries functions. Is there a reason for this?

How would I use a complementary? what would that look like?
Would using the library be better than reading directly from the wire? I thought they were one in the same.

You can google for the complementary filter. Basically you mix the acceleration with the integral of the gyroscope measurements to get a more stable reading. About the library: I think its  the same, was just curious why you are first using the library and then not.

What happens if the while condition fails? i.e. if millis() - time is greater than or equal to 20. Is this what you intended? If there's too much other stuff in the while loop, it may quit it and never re-enter it.
loop()
I've added a call to a function that prints debug information.
unsigned long time = 0;

void loop()
{
  DebugMsgTime("loop() begin");

  while (millis() - time < 20)
  {
    DebugMsgTime("while begin");

    time = millis();

    //delay(10);  // Short delay OK.
    delay(20);  // Long delay causes while loop to quit.

    DebugMsgTime("while end");
  }
  DebugMsgTime("loop() end");
}

DebugMsgTime()
This function prints a message along with the current time and the delta time since it was last called.
void DebugMsgTime(const char *msg)
{
  static unsigned long previous_time = 0;
  unsigned long time = millis();
  unsigned long delta_time = time - previous_time;
  previous_time = time;

  Serial.println(msg);
  Serial.println(time);
  Serial.println(delta_time);
}

Debug Output

It works great but all of a sudden, very randomly, it glitches and
gets stuck in whatever mode it was in last

Basic Encoder Test:
loop() begin
0
0
while begin  // It works great...
1
1
while end
2
1
while begin
12
10
while end
34
22           // but all of a sudden, very randomly, it glitches...
loop() end   // and gets stuck in whatever mode it was in last
54
20
loop() begin
74
20
loop() end
97
23
loop() begin
118
21
loop() end

As you can see, using this while loop is a very inaccurate way to generate regular sampling times.
loop() FIX
As @FerryBig pointed out in the comments, you need to change the time comparison < at the start of the loop. You also don't need the while loop because loop() is already called cyclically. Instead, put the time comparison in an if statement, something like this which gives you a rough 20 ms:
void loop()
{
  static unsigned long previous_time = 0;
  unsigned long time = millis();
  unsigned long delta_time = time - previous_time;

  if (delta_time >= 20)
  {
    previous_time = time;

    // Do PID algorithm.
  }
}

However, for a PID controller you may need more accuracy.
Timer Interrupt
A better method would be to use a timer interrupt to call an Interrupt Service Routine (ISR) at regular intervals. This ISR would do two simple things in this order:

Output: digitalWrite(motor_direction); and analogWrite(3, mtr2);
Input: set a flag that indicates that the gyro Wire needs reading.

Then, when the flag is set, the main loop() would read the gyro Wire, and calculate motor_direction and mtr2 in readiness for the next interrupt.
const uint16_t t1_load = 0;

// Timer1 compare value:
// Clock frequency / Prescaler / Required frequency = Compare value
// 16 MHz          / 64        / 10 Hz              = 25000
const uint16_t t1_comp = 25000;

volatile bool isr_flag = false;       // Used to flag when the ISR has updated the data.
volatile unsigned long isr_time = 0;  // The data.

void setup()
{
  // Disable global interrupt
  cli();

  // Reset Timer1 Control Reg A
  TCCR1A = 0;

  // Set CTC mode
  TCCR1B &= ~(1 << WGM13);
  TCCR1B |= (1 << WGM12);

  // Set to prescalar of 64
  TCCR1B &= ~(1 << CS12);
  TCCR1B |= (1 << CS11);
  TCCR1B |= (1 << CS10);

  // Reset Timer1 and set compare value
  TCNT1 = t1_load;
  OCR1A = t1_comp;

  // Enable Timer1 compare interrupt
  TIMSK1 = (1 << OCIE1A);

  // Enable global interrupt
  sei();

  Serial.begin(9600);
}

void loop()
{
  //
  // BEGIN CRITICAL SECTION (Atomic)
  //

  cli();
  bool flag = isr_flag;  // Copy the ISR flag.
  isr_flag = false;      // Reset the ISR flag.
  sei();

  //
  // END CRITICAL SECTION
  //

  Serial.println(flag);

  if (flag == true)
  {
    //
    // BEGIN CRITICAL SECTION (Atomic)
    //

    // Get a copy of the data that has been modified by the ISR.
    cli();
    unsigned long time = isr_time;
    sei();

    //
    // END CRITICAL SECTION
    //

    static unsigned long previous_time = 0;
    Serial.println(time - previous_time);
    previous_time = time;
  }

  delay(25);
}

ISR(TIMER1_COMPA_vect)
{
  //TCNT1 = t1_load;  // No need to reload here because it auto reloads.
  isr_time = micros();
  isr_flag = true;  // Indicate that new data is available.
}

PID Controller
This is the full implementation of the PID controller. It should give you a solid foundation to develop the PID algorithm for your motor, and to filter the gyro inputs.
//Code for accelerometer controlling an encoded DC
#include <Encoder.h>
#include <Wire.h>
#include <MPU6050.h>
#include <QueueArray.h>

//Class to read the encoder
Encoder myEnc(19, 18);

//I2C address of the MPU-6050 idk if i need
const int MPU_addr = 0x68;

const uint16_t t1_load = 0;

// Timer1 compare value:
// Clock frequency / Prescaler / Required frequency = Compare value
// 16 MHz          / 64        / 10 Hz              = 25000
//const uint16_t t1_comp = 25000;

// If the PID algorithm takes less than 5 ms, it's possible to run Timer1 at a maximum of about 200 Hz.
// 16 MHz          / 64        / 200 Hz             = 1250
const uint16_t t1_comp = 1250;

// Buffered data for sending/receiving to/from the ISR.
volatile bool          isr_flag = false;            // Used to flag when the ISR has triggered.
volatile unsigned long isr_time = 0;                // Input updated by ISR.
volatile byte          isr_motor_direction = LOW;   // Output calculated and updated in loop().
volatile byte          isr_motor_speed = 0;         // Output calculated and updated in loop().

//initializing the MPU6050 (accel/gyro input)
MPU6050 sensor;

//accerleromter in the y direction
int16_t AcY;
//not using
int16_t AcX, AcZ, GyX, GyY, GyZ, Tmp;

//new varible for mapping the accelerometer to degrees
int yAng;

//Variables to create PID method
int currentTheta;
float error;
int dt = 5;
long integral = 0;
long deriv;
int previousError;

//accel on light, always want it at 0
int setpoint = 0;

//this is the enable pin (PWM) to run speeds to the motor
#define MOTOR_SPEED_PIN         3

//change direction of the motor
// TODO: Check whether LOW and HIGH are correct.
#define MOTOR_DIRECTION_PIN     2
#define MOTOR_DIRECTION_CW      LOW
#define MOTOR_DIRECTION_CCW     HIGH

void setup()
{
  // Disable global interrupt.
  cli();

  // Reset Timer1 Control Reg A
  TCCR1A = 0;

  // Set CTC mode
  TCCR1B &= ~(1 << WGM13);
  TCCR1B |= (1 << WGM12);

  // Set to prescalar of 64
  TCCR1B &= ~(1 << CS12);
  TCCR1B |= (1 << CS11);
  TCCR1B |= (1 << CS10);

  // Reset Timer1 and set compare value
  TCNT1 = t1_load;
  OCR1A = t1_comp;

  // Enable Timer1 compare interrupt
  TIMSK1 = (1 << OCIE1A);

  // Enable global interrupt
  sei();

  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);

  Serial.begin(9600);
  Serial.println("Basic Encoder Test:");

  //pinMode(MOTOR_SPEED_PIN, OUTPUT);  // Not needed for analogWrite().
  pinMode(MOTOR_DIRECTION_PIN, OUTPUT);

  sensor.initialize();
}

void loop()
{
  //
  // BEGIN CRITICAL SECTION (Atomic)
  //

  cli();
  bool flag = isr_flag;  // Copy the ISR flag.
  isr_flag = false;      // Reset the ISR flag.
  sei();

  //
  // END CRITICAL SECTION
  //

  //Serial.println(flag);

  if (flag == true)
  {
    DebugMsgTime("PID algorithm begin");

    //
    // BEGIN CRITICAL SECTION (Atomic)
    //

    // Get a copy of the data that has been modified by the ISR.
    cli();
    unsigned long time = isr_time;
    sei();

    //
    // END CRITICAL SECTION
    //

    static unsigned long previous_time = 0;
    //Serial.println(time);
    //Serial.println(time - previous_time);
    previous_time = time;

    //
    // Read gyro Wire.
    //

    Wire.beginTransmission(MPU_addr);
    Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(MPU_addr, 14, true);

    //reading each of the 6 axis's of the MPU6050 and the temp
    AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
    //Only using AcY
    AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
    AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
    Tmp = Wire.read() << 8 | Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
    GyX = Wire.read() << 8 | Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
    GyY = Wire.read() << 8 | Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
    GyZ = Wire.read() << 8 | Wire.read();

    //mapping AcY to yAng from accel units to degrees
    yAng = map(AcY, -17000, 17000, -90, 90);

    //
    // Calculate motor parameters locally.
    //

    long pos = PID(yAng);
    byte motor_direction = pos > 0 ? MOTOR_DIRECTION_CW : MOTOR_DIRECTION_CCW;  // TODO: Check whether defines are correct.
    pos = abs(pos);
    pos = constrain(pos, 0, 100);
    byte motor_speed = map(pos, 0, 100, 0, 200);

    //
    // BEGIN CRITICAL SECTION (Atomic)
    //

    // Update the ISR data ready for output at the next interrupt.
    // This keeps the outputs locked to each other and synchronised to the interrupt.
    cli();
    isr_motor_direction = motor_direction;
    isr_motor_speed = motor_speed;
    sei();

    //
    // END CRITICAL SECTION
    //

    DebugMsgTime("PID algorithm end");
  }

  //delay(1);
}

ISR(TIMER1_COMPA_vect)
{
  // Output.
  digitalWrite(MOTOR_DIRECTION_PIN, isr_motor_direction);
  analogWrite(MOTOR_SPEED_PIN, isr_motor_speed);

  // Input.
  isr_time = micros();
  isr_flag = true;
}

//PID loop to find error between setpoint and currentTheta
long PID(int currentTheta)
{
  error = setpoint - currentTheta;
  integral = integral + error * dt;
  deriv = (error - previousError) / dt;
  long output = 1.9 * error + .8 * integral + 40 * deriv; //2.8,.7,70 //1.3,.8,40
  previousError = error;
  return output;
}

void DebugMsgTime(const char *msg)
{
  static unsigned long previous_time = 0;
  unsigned long time = micros();
  unsigned long delta_time = time - previous_time;
  previous_time = time;

  Serial.println(msg);
  Serial.println(time);
  Serial.println(delta_time);
}

And I think there might be a typo in your PID controller:
long PID(int currentTheta)
{
    ...
    long output = 1.9*error; + .8*integral + 40*deriv;
                           |
                         typo?

This is equivalent to:
    long output = 1.9*error;

Which is not a PID controller.

For some reason that needs to be there. If i dont have that semi colon there, it wont work.
I had that while loop to run it every 20 ms. I think someone else on here told me that using that way instead of delay was better. It made it so a time was controlling each run time instead of every time it got information.

@ThunderDornhofer The semicolon will end the expression there. So the rest of the line has no effect. What exactly do you mean by "if i don't have that semicolon there, it won't work"? How exactly does it now work?

@ThunderDornhofer, I've updated my post to show why your while loop doesn't work. A better method to generate regular time intervals is to use timer interrupts.

@ThunderDornhofer Your loop conditions actually seems reversed, if it is based on the Arduino blink without delay loop. https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay Your code works because you actually update time with the new values. tim's example doesn't include updating the time, which your code has

@Ferrybig, sorry, that was a sloppy copy-and-paste error when I updated my post. I've put the loop-breaking code back in now.

@tim the loop still breaks in the way you explained, but the loop is fixed by changing < to >, as that wil l prevent going into the loop for 20 MS< and only then go into the loop, resetting the "timer"

@Ferrybig, I agree, I was just about to follow-up my comment with if (currentMillis - previousMillis >= interval) from the tutorial you linked to. However, it's still not as accurate as a timer interrupt.

Thanks for the help. This made a lot of sense. I am going to try and fix this today.

@tim I believe i have attached an ISR interrupt? I followed a guys tutorial. I might be doing it wrong. I updated my original code if you could take a look at it. Thanks

@ThunderDornhofer, the timer code in setup() is good. I've added a code snippet to the Timer Interrupt section that will output the interrupt timings and it uses "critical sections" to retrieve data that has been modified by the ISR. But the code in your ISR takes for too much time to execute (over 3ms) which will interfere with the update of millis() because interrupts are disabled during an ISR and interrupts are used to update the counter that is read by 'millis()'. The maximum allowed is 2ms. The PID algorithm should be placed within the if statement in the loop().

@ThunderDornhofer, I've added a full implementation of the PID controller. There are a couple of TODO comments you need to verify are correct. Not sure what frequency you want to run the timer at, but I got about 200 Hz max. Hope that helps.

@tim Wow, tim that helped so much. It works great when I am moving my sensor, but still seems to glitch out causing me to have to press the reset button when the sensor is at rest, no motion. Do you have any idea what that might be or how to fix that? I have updated my code.

@tim Also side question, if i wanted to add more to this code such as buttons, would that output also go into the ISR method?

@tim It runs a lot better but after my tests, I have found that after a while, randomly, it will stop working yet again. When looking at the serial moniter, as it is runnning through the print statements, it reads "PID algorithm begin", then the time, then the delta time and then when it glitches it out, it stops and doesn't print "PID algorithm end


text:
Converting from Float to Int yielding weird results. What am I doing wrong?
So I am trying to take GPS data with a Neo 6M gpsmodule (that is what is covered up by the square for privacy sake) and process it by adding/multiplying to get large integers representing the GPS data. This is using Arduino nano. When I try and convert the float numbers to integers, it gives me totally different numbers. 1242895 turns into -2289, and 611194 turns into 21370. I have tried so many things, but am stumped as to what is going on. Is it related to pointing? It's been awhile since I learned about pointers in my C++ class. X and Y are initialized as int global variables.

Please copy and paste your code here instead of posting a screenshot.  A picture of some text is about the most useless thing on the internet.  It can't be copied and edited.  It's hard to read.  Screen readers can't touch it.  Please in the future just copy and paste the text itself.

Covered up for privacy sake? You are sharing the same data below, with only a trivial transformation.

On an Arduino board with the 328 processor, an INT is stored as a 2 byte value, so the max number is 32,767.
You want to use a LONG which is a 4 byte number which has a max of 2,147,483,647.
When the variable you are using is not big enough, the number rolls over, which is why you end up getting a negative number.

I've fixed up the capitalization in your post, but in future please try to make English sentences. They start with a capital letter. This isn't a game chat where you just type in all lower-case.

@NickGammon Wow. Thank you so much.


text:
Maintain constant PWM voltage with changing Vcc
I am making an arduino project with a single lithium ion battery, and want to be able to maintain a constant PWM voltage, even when the battery goes from 4.2-3.2v. I have been able to read the Vcc using the internal 1.1v reference, so I am wondering if I can make some sort of feedback system to increase the duty cycle when the battery discharges, in order to keep the same average voltage on the PWM. I want to be able to make it 3.2v constant, which should be attainable on Vcc from 4.2-3.2, with 100% duty cycle when the battery is at 3.2v.

That's just a math problem, and a simple one at that.  Read your voltage, calculate the PWM to get the average you want, then apply that PWM.  What part is sticking you?

That would work. Just note that the 1.1V reference can differ slightly, from chip to chip. So depending on your margin of error, you might have to do a bit of calibration. PS it sound like you already know, but just to reiterate; PWM output doesn't give out an analog voltage, despite the misleading analogWrite function name. You'd have to do some filtering to convert the PWM to a analog voltage.

Wouldn't a voltage regulator do that better than an Arduino?

Simple:
duty =  (3.2 / vcc) * 255;


text:
Problem with programming digispark ATtiny85 board with Arduino IDE
I have bought a Digispark ATtiny85 board to learn about that microcontroller. So I tried using internal register names in the code rather than using Arduino in built functions. I can get the board to work when comes just input and output operations. For example the below code works and I can get the on board LED to turn ON and OFF
#include<avr/io.h>
void setup()
{
  DDRB |=(1 << PB1);  //set PB1 as output
}
void loop() {
 PORTB |= (1 << PB1);    // Turning ON LED connected to PB1
 delay(1000);            //Using Arduino IDE inbuilt delay function to generate delay of 1 second
 PORTB &= ~(1 << PB1);   //Turning the LED off
 delay(1000);

}
I have tried using Timer0 of ATtiny85 module to generate time delay of one second. But unfortunately I couldn't get it to work.
#include<avr/io.h>
#define F_CPU 16500000UL
#include<util/delay.h>

void timer_config()
{
 DDRB =0b00000010; // set PB1 as output
 GTCCR|= (1<<TSM);      ///Halt the timer for configuration
 TCCR0A=0x00;             //Normal mode
 TCCR0B=0x00;
 TCCR0B |= (1<<CS00)|(1<<CS02);   //prescaling with 1024
 TCNT0=0;
 GTCCR&=~(1<<TSM); //Start the timer
}

void tmdel()
{
 int i=0;
 while(i<=6)
 {
  while((TIFR & (1 << TOV0) )==0);        //Waiting for 0-255 and flag to raise
  TIFR|=(1<<TOV0);      //Clear the flag
  i=i++;                          //increment by one
 }
}

int main()
{
 timer_config();
 while(1)
 {
  PORTB|=(1<<PB1);     //PortB1 high
  tmdel();                         //Delay of 1 second
  PORTB&=~(1<<PB1);     //PORTB1 low
  tmdel();
 }
}

I have used the overflow flag to identify TCNT0 register status. I have uploaded the above code but the LED isn't responding as anticipated.
When searching the internet I have got few suggestions that this might be because Arduino IDE uses timer registers for delay function. When user attempts to access timer registers it might not work as intended.
But am not sure about the validity of above opinion. Can anyone help me with it? Since am learning this controller, practicing core programming is quite important. If I cannot program ATtiny85 using Arduino IDE this way, can someone suggest a way or alternate hardware setup to program ATtiny85 and access its registers without a problem.

Since the Arduino ecosystem is open-sourced, you could look into their sources to find out about timer usage. -- However, as the Arduino IDE comes with a complete GCC for AVR, you can use any editor or IDE you like and write software without using the Arduino IDE / library.

Your code (the second one) does not use any Arduino functions, and thus the IDE is not relevant. It would help to indent your code in the usual way, to make it more readable.

Without going through your code line-by-line, I would say your issue is the registers you have used. The IDE is not relevant to your problem. Or possibly your use of i=i++ as I mentioned in my reply.

 i=i++;                          //increment by one

The result of the above statement is not defined. That is, it is not necessarily "i + 1".
See:

http://en.wikipedia.org/wiki/Sequence_point
http://c-faq.com/expr/seqpoints.html

Instead use:
i++;

Or:
i = i + 1;

A note about "undefined behavior":
http://en.wikipedia.org/wiki/Undefined_behavior

When an instance of undefined behavior occurs, so far as the language specification is concerned anything could happen, maybe nothing at all.

i = ++i; then? q-;

Very amusing. No.


text:
Error "cstddef: No such file or directory" on use AzureIoTHub
Good Morning
I'm trying to integrate with Azure IoT with Arduino Mega 2560.
I imported the AzureIoTHub and AzureIoTUtility lib.
I just created this part of the code
 #include <AzureIoTHub.h>

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

however, when I compile, I get the following error message.

In file included from
C:\Users\MercurioNote\Documents\Arduino\libraries\AzureIoTUtility\src/azure_c_shared_utility/platform.h:7:0,
from C:\Users\MercurioNote\Documents\Arduino\libraries\AzureIoTUtility\src/AzureIoTUtility.h:7,
from C:\Users\MercurioNote\Documents\Arduino\libraries\AzureIoTHub\src/AzureIoTHub.h:7,
from D:\Documents\Dev\Pocos\Arduino\ArduinoSolution\ArduinoSolution.ino\WiFiPoco\RoboCore\azureHub\azureHub.ino:3:
C:\Users\MercurioNote\Documents\Arduino\libraries\AzureIoTUtility\src/azure_c_shared_utility/strings.h:8:10:
fatal error: cstddef: No such file or directory  #include

I imported ArduinoStl and the problem continued.
what am i doing wrong in this case?
thanks

Did you happen to read the (very short) list of supported hardware in the README of the Azure IoT library? It is only for ESP8266 and ESP32 (and then only specific ones by the look of it).

Azure IoT is only supported on ESP8266 and ESP32. As stated in the README for the library:

Currently supported hardware:

ESP8266 based boards with esp8266/arduino

SparkFun Thing

Adafruit Feather Huzzah

ESP32 based boards with espressif/arduino-esp32

Adafruit HUZZAH32