NOOB help STEPPER TIMELAPSE project

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

NOOB help STEPPER TIMELAPSE project

Postby k_pop » Thu Feb 09, 2012 1:33 pm

hey guys!

after hours of digging threw code i decided to ask a few questions. first a little bit about my self.

i am a tv editor, i work for a major broadcaster making youth related tv shows. i also love to tinker. my major hobby,
is RC related projects. here is my youtube channel.

http://www.youtube.com/user/kpopRC
check it out!

anyway. i have always wanted to improve my gopro timelapse shots. and after finding a few egg timer projects like this one...
Image
http://hackaday.com/2011/09/21/build-cheap-panning-camera-mounts-for-time-lapse-photography/

i decided to dive into arduino code, and make my own controlable stepper platform.
the first thing i did was buy a arduino starter kit, and assemble the example projects, and modify the sketch provided. it was a funn weekend
of wiring up leds trying to matrix them, and all that fun stuff.

i ended up getting the ada motor sheild for the stepper motor that i will be using.
http://www.ladyada.net/make/mshield/
^ that one^

and i also got a rotary encoder with led
http://mayhewlabs.com/products/rotary-encoder-led-ring

after spending a few hours, i got the stepper to work using the library AF_MOTOR. and can control it step by step, using a delay between steps.
my idea is to be able to adjust the delay between steps with the rotary encoder... each click of the wheel will change the delay value between steps.

so, here's where my NOOBNESS begins.

i downloade the test sketch for the rotary encoder, and am digging threw it, and i am lost. here is the sketch.


Code: Select all

//These are the pins that will talk to the shift register through SPI
#define SDI    2    //Data
#define CLK    3    //Clock
#define LE     4    //Latch

//These are the rotary encoder pins A, B, and switch
#define ENC_A    8
#define ENC_B    9
#define ENC_SW   10
#define ENC_PORT PINB  //The port that the rotary encoder is on (see http://www.arduino.cc/en/Reference/PortManipulation)

// Global variables
int scaledCounter = 0;  //The LED output is based on a scaled veryson of the rotary encoder counter
int sequenceNumber=0;   //The output sequence for the LEDs
int incomingByte = 0;   //Serial input to select LED output sequence


/*This is a 2 dimensional array with 3 LED sequences.  The outer array is the sequence;
  the inner arrays are the values to output at each step of each sequence.  The output values
  are 16 bit hex values (hex math is actually easier here!).  An LED will be on if its
  corresponding binary bit is a one, for example: 0x7 = 0000000000000111 and the first 3 LEDs
  will be on.
 
  The data type must be 'unsigned int' if the sequence uses the bottom LED since it's value is 0x8000 (out of range for signed int).
*/
unsigned int sequence[3][16] = {{0x0,0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x100,0x200,0x400,0x800,0x1000,0x2000,0x4000},
                                };

void setup()
{
  //Set SPI pins to output
  pinMode(SDI, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(LE,OUTPUT);
  //Set encoder pins to input, turn internal pull-ups on
  pinMode(ENC_A, INPUT);
  digitalWrite(ENC_A, HIGH);
  pinMode(ENC_B, INPUT);
  digitalWrite(ENC_B, HIGH);
  pinMode(ENC_SW, INPUT);
  digitalWrite(ENC_SW, HIGH);

}


void loop()
{
  //Local Variables
  static uint8_t counter = 0;      //this variable will be changed by encoder input
  int8_t tmpdata;
 
  //Get any serial input
  if (Serial.available() > 0)
  {
    incomingByte = Serial.read();
  }
 
 
   
  //Call read_encoder() function   
  tmpdata = read_encoder();
 
  //if the encoder has moved
  if(tmpdata)
    {
     
      //Set the new counter value of the encoder
      counter += tmpdata;     
     
      //Scale the counter value for referencing the LED sequence
      //***NOTE: Change the map() function to suit the limits of your rotary encoder application.
      //         The first two numbers are the lower, upper limit of the rotary encoder, the
      //         second two numbers 0 and 14 are limits of LED sequence arrays.  This is done
      //         so that the LEDs can use a different scaling than the encoder value.
      scaledCounter = map(counter,0,100,0,15);
     
      //Send the LED output to the shift register
      digitalWrite(LE,LOW);
      shiftOut(SDI,CLK,MSBFIRST,(sequence[sequenceNumber][scaledCounter] >> 8));    //High byte first
      shiftOut(SDI,CLK,MSBFIRST,sequence[sequenceNumber][scaledCounter]);           //Low byte second
      digitalWrite(LE,HIGH);
    }
 
  //If the encoder switch is pushed, this will turn on the bottom LED.  The bottom LED is turned
  //on by 'OR-ing' the current display with 0x8000 (1000000000000000 in binary)
  if (!digitalRead(ENC_SW))
  {
    digitalWrite(LE,LOW); 
    shiftOut(SDI,CLK,MSBFIRST,((sequence[sequenceNumber][scaledCounter]|0x8000) >> 8));
    shiftOut(SDI,CLK,MSBFIRST,sequence[sequenceNumber][scaledCounter]);             
    digitalWrite(LE,HIGH);   
  }
}



/*************************************************************************
*    read_encoder() function as provided by Oleg:                        *
*    http://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino *
*                                                                        *
*    Returns change in encoder state (-1,0,1)                            *
************************************************************************ */
int8_t read_encoder()
{
  int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
  static uint8_t old_AB = 0;
  /**/
  old_AB <<= 2;                   //remember previous state
  old_AB |= ( ENC_PORT & 0x03 );  //add current state
  return ( enc_states[( old_AB & 0x0f )]);
}



so here are a few EXTREMELY noobish questions!

so i know that there are 3 wires for the rotary encoder. as well as 3 for the shift register.
i understand that there are more steps in the encoder then lights on the board. so i get the whole scaled section of code.
i also under stand the led sequence. there used to be 3 sequences but i deleted the other 2.

i also get that in the void setup we are telling the arduino that the spi pins are outputs, and the enc's are inputs. so that's all gravy!
i am having a hard time understanding the loop function!

static unit8_t counter = 0:
int8_t tmpdata;

can some one explain what is happening here. i need to see how the variables changed by the encoder can trigger a delay between my stepper motor's steps.

ill post the code i have written for the stepper the motor later today.

any help with this project will be appriciated. i am elbows deep in the cookbook for arduinos, and seem to think that it's more of a reference guide, then something you can read cover to cover. plus i work better seeing examples, and differences in sketches.

sorry for the extreme noobish post. and expect me to post the project as it evolves, and as i gain experience with code!

thanks guys

k
k_pop
 
Posts: 3
Joined: Thu Feb 09, 2012 1:01 pm

Re: NOOB help STEPPER TIMELAPSE project

Postby adafruit_support_bill » Thu Feb 09, 2012 2:10 pm

The simplest approach is to calculate a delay based on your encoder position, then call delay() between steps. But that will not be very responsive.

The problem you are going to have here is that your encoder example code is polled instead of interrupt driven, so during the delay, it will miss any encoder input. You should look into an interrupt-driven encoder library (one was posted in these forums recently). You should also look into using a timer instead of calling delay(). I would also recommend using the Adafruit version of the AccelStepper library (you can download this from the MotorShield Downloads page.)
User avatar
adafruit_support_bill
 
Posts: 16617
Joined: Sat Feb 07, 2009 9:11 am

Re: NOOB help STEPPER TIMELAPSE project

Postby k_pop » Thu Feb 09, 2012 2:14 pm

YESSSS. i will read up on everything you mentioned...

do you think it will be easier to use a variable resistor instead of using the rotary encoder?


k
k_pop
 
Posts: 3
Joined: Thu Feb 09, 2012 1:01 pm

Re: NOOB help STEPPER TIMELAPSE project

Postby philba » Thu Feb 09, 2012 3:09 pm

This is very close to a project that I have full intent to get to. some day...

An encoder has an advantage over a potentiometer in that it's precise. A potentiometer can change value based on humidity, temperature, dirt/dust and so on. A potentiometer will be easier to use, though.

The encoder code looks like it could work for you but it's got some disadvantages. He's reading the encoder pins by reading a whole port and then masking out the pins he doesn't care about. He then maps that into a direction. Direction is determined via what's called a state machine. He then uses the current "state" of the pins and the previous state of the pins as an index into the state array. It's a very good technique for direction. If called frequently enough, you can tell when a click happens since he only returns a non-zero value when a "click" has happened and you just add the return to you counter. An interrupt driven approach is better, though. You could just run this code off of a timer that interrupts every 50 mS or so. I'd be a little concerned about debouncing if your encoder has mechanical switches. The other disadvantage of the code is that it expects the encoder pins to be on the same port and adjacent. This isn't necessary and is an easy mod.
philba
 
Posts: 387
Joined: Mon Dec 19, 2011 5:59 pm

Re: NOOB help STEPPER TIMELAPSE project

Postby k_pop » Thu Feb 09, 2012 5:26 pm

yes guys thanks for the juicy info!


i found this amazing page...

http://www.electronicsblog.net/examples-of-using-arduinoatmega-16-bit-hardware-timer-for-digital-clock/

i am trying to learn about interpret functions.

take a look guys. i am trying to make the stepper click one step every second. and see if i can figure out a way to change the length of time between each step. i am not too worried about each step being 1.048576sec.

stay tuned!
if you guys have any ideas please share!

thanks

k
k_pop
 
Posts: 3
Joined: Thu Feb 09, 2012 1:01 pm

Re: NOOB help STEPPER TIMELAPSE project

Postby philba » Thu Feb 09, 2012 6:14 pm

That's what interrupts are all about. I don't understand why the guy didn't put the digitalWrite in the ISR too. You can halt the AVR from running other than the timer so power consumption is much much lower.
philba
 
Posts: 387
Joined: Mon Dec 19, 2011 5:59 pm


Return to General Project help

Who is online

Users browsing this forum: Google [Bot] and 3 guests

Stuff to buy from the Adafruit store and links to product documentation!


New Products [114]

Raspberry Pi[82]
 
FLORA[24]
 
Bunnie Studios[9]
 
FPGA[1]
 
mbed[12]
Arduino[60]
 
NETduino[14]
 
BeagleBone[23]
 
Android[6]
 
XBee[10]
More Dev Boards[30]


 
BoArduino[8]
 
SpokePOV[4]
 
TV-B-Gone[4]
 
MiniPOV[3]
 
SIM reader[3]
 
Microtouch[5]
 
Clocks & Watches[18]
 
Drawdio[4]
 
Brain Machine[1]
 
Game of Life[2]
 
MintyBoost[2]
More DIY Kits[16]


 
MaKey MaKey[3]
 
Tweet-a-Watt[5]
 
Young Engineers[39]
 
Discover Electronics[2]
 
Snap Circuits[4]
 
littleBits[3]
 
Project packs[9]


 
Breakout Boards[35]
LCDs & Displays[49]
Components & Parts[70]
Batteries & Power[54]
EL Wire/Tape/Panel[52]
LEDs[112]
 
Wireless[16]
Cables[66]
 
Lasers[6]
Sensors/Parts[147]
 
Enclosures/Cases[11]
 
Solar[11]
 
RFID / NFC[13]
Prototyping[70]
 
iDevices[13]
Tools[71]
 
Wearables[41]
 
CNC[37]
 
Robotics[29]
 
3D printing[1]
 
Materials[25]


 
Stickers[41]
 
Skill badges[55]
 
Books[26]
 
Circuit Playground[7]
 
Gift Certificates[4]