GOAL:
Monitor the DC current of a servo motor while the motor is in operation.
PROBLEM:
Both the current sensor code section and the servo motor code section work fine individually. I don’t know how to combine the two sections to ensure they run in tandem.
From what I’m seeing, the Arduino will start reading the current, stop the current measurement, and then begin rotating the servo without actually measuring the current (looped). I need it to read the current while the servo is rotating. Thoughts?
I haven't worked with servos yet, but I can suggest a couple of things that might help you get better help from others in addition to helping you write code that's easier to follow.
Get in the habit of adding comments, spaces, and indents to your code to make it more readable (for you and others)
When you post code here it REALLY helps if it can be posted with the appropriate tags so that it appears in it's own scrollable section (especially important for mobile users). It's really easy to do that; in the IDE just select everything (ctrl+A) and then choose "Copy for Forum" from the edit menu; it'll pop it onto the clipboard so all you need to do is a ctrl+V to paste it here.
There's also a ctrl+T option in the IDE that formats your code according to the proper conventions (that I haven't quite followed here as I like my curly braces to all be on their own lines -- but other than that it's pretty close).
Here's how your code could look if you do all that (I made a couple of other changes too - but not sure if that would make any difference or not). Keep in mind too that you currently have approx zero time between the servo stopping at the end of 1 loop and starting again at the beginning of the next one - so if that's not your intention then you might like to add another delay().
PS: When you see code presented like this you can copy it to your clipboard with one click by aiming for the control in the top/right of the box.
Hope this helps.
#include <Wire.h> // Include serial, sensor, and servo libraries
#include <Adafruit_INA219.h>
#include <Servo.h>
Adafruit_INA219 ina219; // Initialise sensor & servo interfaces
Servo Servos;
float current_mA = 0; // Define variables to hold readings
float power_mW = 0;
void setup()
{
Serial.begin(115200); // Initialise the serial interface
Servos.attach(3); // Attach the servo
}
void loop()
{
//POWER MONITOR
current_mA = ina219.getCurrent_mA(); // Get the current and power readings from the sensor
power_mW = ina219.getPower_mW();
Serial.print("Current: "); // Print the current and power readings
Serial.print(current_mA);
Serial.println(" mA");
Serial.print("Power: ");
Serial.print(power_mW);
Serial.println(" mW");
Serial.println("");
//SERVO
Servos.write(0); // Rotate the servo clockwise
delay(800);
Servos.write(90); // Stop rotating
delay(3000);
Servos.write(360); // Rotate the servo counter-clockwise
delay(800);
Servos.write(90); // Stop rotating
}
Thank you @anon12459472! I was trying to figure out how to add code tags on PC like I could do in the previous Arduino forms but I didn't see any buttons for it. (I didn't think to check the IDE) I'll make sure to do that from now on, now that you taught me
@midnightsparks ,
Welcome. This is a common problem for people new to writing code and comes up often on here, so do some searching on the forum for help already given to others. When you have got this working you will have learned a lot about writing good code.
Your biggest problem is this:
delay(800);
Lots of them. delay(800) means 'do absolutely nothing for 800 milliseconds'. That's 800 milliseconds when your code could be doing something else useful, so the first thing you need to do is understand these tutorials:
You need to re-write your code to take into account the principals in those tutorials.
This will also help you:
Reading through those links, I was still confused on using Millis() (It wasn't the contents fault, I'm a visual type learner)
However, I then went on YouTube and found these two videos regarding Millis() and it really helped re-enforce the concept of Millis(). https://www.youtube.com/watch?v=BYKQ9rk0FEQ https://www.youtube.com/watch?v=hD3cR25MbW8
I think I undersand now what you're talking about @PerryBebbington.
I'm going to rewrite the sketch and try it again using Millis().
millis() is just a "timestamp" - so you can then do other things relative to that timestamp. Here's an example that I did for someone who wanted an output held high so long as a pulsed input continued (x2 independent circuits - so the code is "doubled up")
const int inputOne = 2; // Define input & output pins
const int inputTwo = 3;
const int outputOne = 12;
const int outputTwo = 13;
long stopTimeOne = 0; // Turn off time for each channel
long stopTimeTwo = 0;
void setup()
{
pinMode(inputOne, INPUT); // Set correct pin modes
pinMode(inputTwo, INPUT);
pinMode(outputOne, OUTPUT);
pinMode(outputTwo, OUTPUT);
digitalWrite(outputOne, LOW); // Start with everything off
digitalWrite(outputTwo, LOW); //
}
void loop()
{
if (digitalRead(inputOne) == HIGH) // Pulse being received for input 1?
{
stopTimeOne = millis() + 1000; // If yes then set new stop time
}
if (digitalRead(inputTwo) == HIGH) // Pulse being received for input 2?
{
stopTimeTwo = millis() + 1000; // If yes then set new stop time
}
if (millis() < stopTimeOne) // Time to turn off channel 1?
{
digitalWrite(outputOne, HIGH); // If not then turn it on
}
else
{
digitalWrite(outputOne, LOW); // If so then turn it off
}
if (millis() < stopTimeTwo) // Time to turn off channel 2?
{
digitalWrite(outputTwo, HIGH); // If not then turn it on
}
else
{
digitalWrite(outputTwo, LOW); // If so then turn it off
}
}
PS: Just be aware that millis() rolls around to 0 after it's been running for about 49 days. Good coding will allow for that ... and my example here is a great example of how NOT to do it if something will be running that long.
Thank you for the article @terryking228 I read it through a couple times.
I was able to get the two sketches combined into one (for anyone in the future with this same problem of wanting to monitor a servo motor's current draw in real time)
#include <Wire.h>
#include <Servo.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;
Servo myservo;
int pos = 0;
//---------------
void setup(void)
{
Serial.begin(115200);
myservo.attach(9);
uint32_t currentFrequency;
Serial.println("Hello!");
// Initialize the INA219.
// By default the initialization will use the largest range (32V, 2A). However
// you can call a setCalibration function to change this range (see comments).
if (! ina219.begin())
{
Serial.println("Failed to find INA219 chip");
while (1)
{
delay(10);
}
}
// To use a slightly lower 32V, 1A range (higher precision on amps):
//ina219.setCalibration_32V_1A();
// Or to use a lower 16V, 400mA range (higher precision on volts and amps):
//ina219.setCalibration_16V_400mA();
Serial.println("Measuring voltage and current with INA219 ...");
}
//---------------
void loop(void)
{
for (pos = 0; pos <= 180; pos += 1)
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
float current_mA = 0;
current_mA = ina219.getCurrent_mA();
Serial.print("Current: ");
Serial.print(current_mA); Serial.println(" mA");
Serial.println("");
delay(15); // waits 15 ms for the servo to reach the position
}
delay (1000);
for (pos = 180; pos >= 0; pos -= 1)
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
float current_mA = 0;
current_mA = ina219.getCurrent_mA();
Serial.print("Current: ");
Serial.print(current_mA); Serial.println(" mA");
Serial.println("");
delay(15); // waits 15 ms for the servo to reach the position
}
}