Analog to Digital conversion to control Servo feedback

So I have a project where I am using an Arduino Uno to control a servo. I want to make a feedback where if the servo's current increase, I would be able control the servo in a different direction or so. I am implementing this by controlling the servo, while reading the current values using a current sensor (1 amp per 1 volt), and reading it in one of the analog pins (i.e. A0). This means that I need continuous analog reading, hopefully multiple current readings (samples) per degree of rotation. I have used analogRead() in a for loop after every degree of rotation but it slowed down my servo and I didn't get the sampling rate that I need...so analogRead() isn't sufficient for me. I believe that I need to use interrupts to manually make analog to digital conversions at the same time as I control the servo.

That being said, I am a beginner at this and I am really just taking part of codes developed by other people online and modifying it. Please see attached code for what I have so far.

My issues with this code are:

  1. I am not sure which analog pin (A0, A1, A2..etc) should I use or does it not matter?
  2. Is the variable aval, suppose to be the number that I am interested in seeing? In other words is it whats being read by the analog pin?
  3. I am getting numbers that range between the 20s and 40s or so, so I know its wrong,since I am suppose to get something that range between 0 and 1024, so what am I doing wrong to get that?
  4. How can I save the information being printed on the serial monitor to an array, I am hoping to export it later on to another software, to do some signal analysis

Your help is greatly appreciated, please let me know if you can't see the code... or if you need any more clarification. Also please don't give me short answers that I would wonder about, clarify please, as I send I am a very new beginner..Thanks

Code:

#include<Servo.h>
Servo myservo;

int marker = 12; // marker output pin
int aval = 0; // analog value

void setup() {
pinMode(marker, OUTPUT); // pin = output
DIDR0 = 0x3F; // digital inputs disabled
ADMUX = 0x43; // measuring on ADC3, use the internal 1.1 reference
ADCSRA = 0xAC; // AD-converter on, interrupt enabled, prescaler = 16
ADCSRB = 0x40; // AD channels MUX on, free running mode
bitWrite(ADCSRA, 6, 1); // Start the conversion by setting bit 6 (=ADSC) in ADCSRA
sei(); // set interrupt flag

myservo.attach(11);
Serial.begin(9600);
Serial.println("Start");

}

int minposition = 700; //adjust this value smaller to find start end position by 5 usec steps
int maxposition = 2300; //adjust this value larger to find stop end position by 5 uses steps
int pos= 0;
void loop() {
// This is my servo controls
for(pos = minposition; pos < maxposition; pos += 5) // move in 5 usec steps
{
myservo.writeMicroseconds(pos); // tell servo to go to position in variable 'pos'
delay(10);
Serial.print(aval);
Serial.print("\n");
}
for(pos = maxposition; pos>= minposition; pos-=5) // move in 5 usec steps
{
myservo.writeMicroseconds(pos); // tell servo to go to position in variable 'pos'
delay(10);
}

}

/*** Interrupt routine ADC ready ***/
ISR(ADC_vect) {
bitClear(PORTB, 4); // marker low
aval = ADCL; // store lower byte ADC
aval += ADCH << 8; // store higher bytes ADC
bitSet(PORTB, 4); // marker high
}

ADC.ino (1.62 KB)

The first thing newbies need to learn is how to put their code in its own window as seen in other posts. This can be done by placing     [code] and [/code]  around the code. This makes it easier for others to read.

Weedpharma

It's only a short piece of code (which is good). Here is is within code tags

#include<Servo.h>
Servo myservo;

int marker = 12;   // marker output pin
int aval = 0;      // analog value



void setup() {
  pinMode(marker, OUTPUT); // pin = output
  DIDR0 = 0x3F;            // digital inputs disabled
  ADMUX = 0x43;            // measuring on ADC3, use the internal 1.1 reference
  ADCSRA = 0xAC;           // AD-converter on, interrupt enabled, prescaler = 16
  ADCSRB = 0x40;           // AD channels MUX on, free running mode
  bitWrite(ADCSRA, 6, 1);  // Start the conversion by setting bit 6 (=ADSC) in ADCSRA
  sei();                   // set interrupt flag
 
  myservo.attach(11);
  Serial.begin(9600);
  Serial.println("Start");

}

int minposition = 700;    //adjust this value smaller to find start end position by 5 usec steps
int maxposition = 2300;   //adjust this value larger to find stop end position by 5 uses steps
int pos= 0;
void loop() {
// This is my servo controls
for(pos = minposition; pos < maxposition; pos += 5)  // move in 5 usec steps
  {                                   
    myservo.writeMicroseconds(pos);    // tell servo to go to position in variable 'pos'
    delay(10);
    Serial.print(aval);   
    Serial.print("\n");
}
  for(pos = maxposition; pos>= minposition; pos-=5)     // move in 5 usec steps
  {                               
    myservo.writeMicroseconds(pos);              // tell servo to go to position in variable 'pos'
    delay(10);
  }

}

/*** Interrupt routine ADC ready ***/
ISR(ADC_vect) {
  bitClear(PORTB, 4); // marker low
  aval = ADCL;        // store lower byte ADC
  aval += ADCH << 8;  // store higher bytes ADC
  bitSet(PORTB, 4);   // marker high
}

There are two very basic problems with this code - the use of delay() and the use of FOR loops

If you get rid of both then you can use analogRead() to read the current as often as you want without any need for interrupts.

You need to have a variable the represents the position of the servo and another representing the increment. At intervals then you update the position. The intervals are determined using the millis() as in the demo several things at a time. The servo sweep function in that demo should do almost exactly what you want.

...R

int aval = 0;      // analog value
...
/*** Interrupt routine ADC ready ***/
ISR(ADC_vect) {
  bitClear(PORTB, 4); // marker low
  aval = ADCL;        // store lower byte ADC
  aval += ADCH << 8;  // store higher bytes ADC
  bitSet(PORTB, 4);   // marker high
}

Variables shared between an ISR and main code could should be volatile.

My link above has a section about "Read the Analog-to-Digital converter asynchronously".

  1. I am not sure which analog pin (A0, A1, A2..etc) should I use or does it not matter?

Yes, it matters. Naturally.