DC Servo position control

Can you post a link for the encoder you have and how you have it wired?

outsider, Your have solved the problem! thankyou!!

I checked the wiring, and had red as V in, should have been white.
So by applying voltage to one output lead i must have blown the encoder. I rewired it correctly and managed to get the occasional reading as it should be.

Time to order a new one.
Thanks again!

Ken

The plot thickens.....

Cheap ebay encoders. they were wired as noted on the label. red V+, instructions on site say white is V+.

So i open them up and found red is V+ after all. Everything looks and tests ok. 5 volt regulator and a couple of transistors. I am suppyling the 5v from a 7805 myself. i wonder if it needs more to get 5 volts out of the inbuilt regulator? says supply voltage of 5 to 25v.

https://www.ebay.com.au/itm/Rotary-Encoder-400P-R-6mm-Incremental-Optical-Shaft-Working-Measurement-5-24V-SH/252550089532?_trkparms=aid%3D555018%26algo%3DPL.SIM%26ao%3D1%26asc%3D52946%26meid%3Db03254ffcb034d9b98f816e887560beb%26pid%3D100005%26rk%3D3%26rkt%3D4%26sd%3D252862587483%26itm%3D252550089532&_trksid=p2047675.c100005.m1851

This is the encoder.

Further testing i can get it to count in the serial monitor by touching the power wire to the encoder on and off.

Have tried 5 and 12v supply to it, powered from the mega and seperate supply, and common ground wiring.......

I Have 2 encoders, both behave the same.

Anybody have any ideas?

Did you read this from the web page?

The color of wires may vary slightly,so there are two kind of the connection method you should refer to.
one is white=VCC, black=GND, red=A phase, green=B phase, the other is Yellow = A phase, Blue = B phase, Red =Vcc power +, Black = power -
Output is NPN open collector

Connecting either the A or B phase to V+ will burn out the transistors.

Says the outputs are open collector which means you need to connect phase A to an input pin and set that pin as INPUT_PULLUP, same with phase B. Interrupt should be set to FALLING.
Try with 5V first, if not work, report back before trying higher V.

outsider, you have solved it! Thankyou!

It works! i had to change encoderpin B to interrupt, now on pin 18 to get it to read clockwise and counterclockwise. Before it was only reading counterclockwise.

I had a feeling the NPN open collector may have been part of it. I didnt know how to configure the code to suit.

It counts up both CW and CCW, is there a way to make it count back ?

Next puzzle is to get it to run to the home switch then go to a preset point on startup.
I would take it this all needs to be coded in the void setup()?

Hi,

pinMode(PinNumber, INPUT_PULLUP);

Configures input with pull up resistor ON.

Tom... :slight_smile:

Hi Tom,

i have the microswitch fitted and reading 0 or 1 for open closed in the monitor.

Where are you locating the home sw and how do you want it to work? Post your latest code.

Home switch is a microswitch triggered by the leadscrew nut. it can over travel without damaging it.
Its located near one end, i want it to trigger the switch, then move the nut a yet to be calculated distance away on startup. This new position will then be the zero point from there.

Re the counting, it does count up and down. I was looking at the total counts.
One thing it does is when it reaches 400 it starts back at zero. By changing the count number in the code i hope to be able to count higher. It will have approx 50 rotations of travel.

I will post the code when i get a bit further along with it.

I have set encoder cycles to 20000. Should cover the amount of travel.

I have combined the encoder and motor driver code, but when going to centre on the pot to stop motor, it doesnt start again unless i give it a manual start. Something to do with interrupts maybe?

I do need the motor to move proportionally with the pot, and return to zero position when pot is zeroed( back at the start).

#define ENCODER0PINA         20      // this pin needs to support interrupts
#define ENCODER0PINB         18      // interuppt
#define CPR                  20000     // encoder cycles per revolution
#define CLOCKWISE            1       // direction constant
#define COUNTER_CLOCKWISE    2       // direction constant
 
// variables modified by interrupt handler must be declared as volatile
volatile long encoder0Position = 0;
volatile long interruptsReceived = 0;
 
// track direction: 0 = counter-clockwise; 1 = clockwise
short currentDirection = CLOCKWISE;
 
// track last position so we know whether it's worth printing new output
long previousPosition = 0;

int SENSOR_PIN = 0; // center pin of the potentiometer

int RPWM_Output = 5; // Arduino PWM output pin 5; connect to IBT-2 pin 1 (RPWM)
int LPWM_Output = 6; // Arduino PWM output pin 6; connect to IBT-2 pin 2 (LPWM)

// Example 1 - Receiving single characters

char receivedChar;
boolean newData = false;


void setup() 
{
  Serial.begin(9600);
  Serial.println("<Arduino is ready>");
  pinMode(RPWM_Output, OUTPUT);
  pinMode(LPWM_Output, OUTPUT);
  pinMode(36, INPUT_PULLUP); //home switch
  
   
  // inputs
  pinMode(ENCODER0PINA, INPUT_PULLUP);
  pinMode(ENCODER0PINB, INPUT_PULLUP);
 
  // interrupts
  attachInterrupt(3, onInterrupt, FALLING);
 
  // enable diagnostic output
  Serial.begin (9600);
  Serial.println("\n\n\n");
  Serial.println("Ready.");
}

void loop()
// only display position info if has changed
{  if (encoder0Position != previousPosition )
  {
    Serial.print(encoder0Position, DEC);
    Serial.print("\t");
    Serial.print(currentDirection == CLOCKWISE ? "clockwise" : "counter-clockwise");
    Serial.print("\t");
    Serial.println(interruptsReceived, DEC);
    previousPosition = encoder0Position;
  }
}
 
// interrupt function needs to do as little as possible
void onInterrupt()
{
  // read both inputs
  int a = digitalRead(ENCODER0PINA);
  int b = digitalRead(ENCODER0PINB);
 
  if (a = b )
  {
    // b is leading a (counter-clockwise)
    encoder0Position--;
    currentDirection = COUNTER_CLOCKWISE;
  }
  else
  {
    // a is leading b (clockwise)
    encoder0Position++;
    currentDirection = CLOCKWISE;
  }
 
// track 0 to 20000
  encoder0Position = encoder0Position % CPR;
 
  // track the number of interrupts
  interruptsReceived++;
 //read the pushbutton value into a variable
{  int sensorVal = digitalRead(36);
  //print out the value of the pushbutton
  Serial.println(sensorVal);
{
  int sensorValue = analogRead(SENSOR_PIN);

  // sensor value is in the range 0 to 1023
  // the lower half of it we use for reverse rotation; the upper half for forward rotation
  if (sensorValue < 512)



  {
    // reverse rotation
    int reversePWM = -(sensorValue - 511) / 2;
    analogWrite(LPWM_Output, 0);
    analogWrite(RPWM_Output, reversePWM);
  }
  else
  {
    // forward rotation
    int forwardPWM = (sensorValue - 512) / 2;
    analogWrite(LPWM_Output, forwardPWM);
    analogWrite(RPWM_Output, 0);
  }
  }
  }
}