View Single Post
  #33  
Old 20-11-2017, 08:24 AM
bojan's Avatar
bojan
amateur

bojan is offline
 
Join Date: Jul 2006
Location: Mt Waverley, VIC
Posts: 6,964
While waiting for keypad/LCD board to arrive, I was thinking to temporary use Digispark board as quadrature decoder (conversion of encoder output to STEP/DIR).
While I know that this is not really needed (because encoder could be connected directly to STEP/DIR inputs of the Pololu driver (of course, the back/forward transitions of STEP could be interpreted as continuous movement in one direction, but it is not the real issue here), my reason for using this $2 board is the 5V regulator, needed for optical encoder power supply (Oak-Grisby).

I found an interesting code for controlling the intensity of LED (tried it, works on Digispark after changing the port for LED). The idea is to replace the "analogWrite" function with STEP/DIR pulse outputs (1us duration)...

If I try hard enough, I will probably do it myself but... it may be easier if someone could point me to suitable piece of code? Thanks in advance!

EDIT:

This code is tested and works OK, output is DIR and PULSE at each interrupt (5 usec duration), depending on encoder movement direction.


******************************
#include "avr/interrupt.h";

volatile int lastEncoded = 0;

void setup()
{
pinMode(0, OUTPUT); // DIR
pinMode(1, OUTPUT); // STEP, on-board LED

// set pins 3 and 4 to input
pinMode(3, INPUT);
pinMode(4, INPUT);
digitalWrite(3, HIGH); // and enable pullup resisters
digitalWrite(4, HIGH);

digitalWrite(0, LOW);
digitalWrite(1, LOW);


GIMSK = 0b00100000; // Enable pin change interrupts
PCMSK = 0b00011000; // Enable pin change interrupt for PB3 and PB4
sei(); // Turn on interrupts
}

void loop()
{
}


// This is the ISR that is called on each interrupt
// Taken from http://bildr.org/2012/08/rotary-encoder-arduino/


ISR(PCINT0_vect)
{
int MSB = digitalRead(3); //MSB = most significant bit
int LSB = digitalRead(4); //LSB = least significant bit

int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value

if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011)

digitalWrite(0, HIGH); // Direction forward

if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000)

digitalWrite(0, LOW); // Direction backwards

// Pulse after delay
delayMicroseconds(5);
digitalWrite(1, HIGH);
delayMicroseconds(5);
digitalWrite(1, LOW);

lastEncoded = encoded; //store this value for next time
}

EDIT 2:

I stumbled on un-expected hardware problem with Digispark Attiny board - because of protection zener diodes on USB connector (marked as 'W4', supposedly 3.6V), input voltage levels from encoder were around 2.5V only - so the whole thing worked very erratically at 5V due to the noise from Pololu drivers. After I removed those diodes ( I think they were not really needed, they were placed "just in case" and they were obviously not 3.6V as marked in some schematics found on web), the circuit worked as expected.

Last edited by bojan; 23-11-2017 at 09:13 AM.
Reply With Quote