Pages: [1]   Go Down
Author Topic: Rotary Encoder--Need help solving three problems  (Read 1113 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey guys, I'm new to Arduino and Processing and coding in general and could really use a hand. I've got a rotary encoder hooked up to a hand drill and eventually my goal is to make every every turn of the handrill spin through 12 frames or so of a 24 frame looped animation on a projector. I'm early in the project but I've come against 3 major issues which I'm not yet quite equipped to deal with. I'm sure with time I'll figure it out but any help at all I'll greatly appreciate.

Issue #1: My encoder functions great with the code below, which I found on another site. The encoder has 24 steps per rotation which is dandy and all, but the problem is that every step it prints in increments of 4. Meaning one step takes me from 0 to 3, the next from 3 to 7, and so on. My diabolical plan was that I'd name my still frames something like MyAnimation_(VARIABLE).png, and I'd just call up MyAnimation_0.png and MyAnimation_1.png and so on, but that won't work if the code is going to skip every 3 frames. How can I tame it? I imagine it's something simple like dividing something by 4 somewhere? But what exactly?

Issue #2: The encoder cranks up to 255 and then zips right back to zero. If I go backwards from 0, then it goes to 255. The behavior itself is great for my loop, but the number 255 is no good. I need to make the cap something divisible by 24, like 239 for example (That way I can save out frames for 10 consecutive loops and personalize each loop so it doesn't seem quite so...loopy.) I confess I have no idea what to do here.

Issue #3: This is more of a question for another forum and I'm more worried about taming the encoder right now, but if you guys have any ideas. What are some good ways to call on and playback the frames of the animation, preferably fullscreen? Again this is something I'm worried about more later on and at that point I'll find the appropriate forum for it, but if you just happened to have some information that points me in the right direction ahead of time. It would be most appreciated.

Thanks so much in advance. Here's the code I'm using at the moment:

Code:
/* Rotary encoder read example */
#define ENC_A 14
#define ENC_B 15
#define ENC_PORT PINC
 
void setup()
{
  /* Setup encoder pins as inputs */
  pinMode(ENC_A, INPUT);
  digitalWrite(ENC_A, HIGH);
  pinMode(ENC_B, INPUT);
  digitalWrite(ENC_B, HIGH);
  Serial.begin (115200);
  Serial.println("Start");
}
 
void loop()
{
 static uint8_t counter = 0;      //this variable will be changed by encoder input
 int8_t tmpdata;
 /**/
  tmpdata = read_encoder();
  if( tmpdata ) {
    Serial.print("Counter value: ");
    Serial.println(counter, DEC);
    counter += tmpdata;
  }
}
 
/* returns change in encoder state (-1,0,1) */
int8_t read_encoder()
{
  static 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 )]);
}
Logged

Indonesia
Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

could you please tell / show us what encoder you have ?

-bino-
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1273
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Issue #2:

Code:
static uint8_t counter = 0;      //this variable will be changed by encoder input
 uint8_t tmpdata;

uint8_t is an unsigned 8-bit (byte) value that can count 0-255. Change this to uint16_t to get 0-65535.

Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34210
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I can't see anywhere where you actually read the encoder, so you are clearly not posting ALL the code. Why hide the problem you want fixing?

You can use processing for the display but you will have trouble loading that many pictures into memory so the solution is to make it a movie and have processing play to a specific line number. This is your biggest problem.
Logged

Offline Offline
Edison Member
*
Karma: 3
Posts: 1001
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The state-model you use to read your rotary encoder is the right approach for low-cost mechanical encoders and should give you a consistent and reliable directional count. 4-steps per detent is as expected, but you can easily limit this to one if so desired.

You would then need to rewrite your loop along the following lines:

-   Create a static int8_t variable to hold step_count (one count per detent, signed)
-   Create a static int8_t variable to hold loop_count (one count per loop, signed)
-   Create a static int8_t variable to hold read_count (replaces your temp variable)
-   Add the output from read_encode to read_count each time through the loop
-   If read_count >= 4 add one to step_count and set read_count to 0
-   If read_count <= -4 subtract one from step_count and set read_count to 0
-   if step_count >= 24 add one to loop_count and set step_count to 0
-   if step_count <= -24 subtract one from loop_count and set step_count to 0[/li][/list]

You can then act on step_count for single increments/decrements or loop_count for full rotations.

The state model (your “read_encoder “ function) requires frequent polling (not to miss steps) and this may be challenged as you add code to your sketch. To overcome this, you want to look at triggering encoder reads using pin change interrupts.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah, thanks so much for the prompt responses everyone. I'll reply to each one by one.

BenF: Thank you very much, this will be immensely helpful. I'll do my best to implement it immediately and get back to this thread should I fail to execute.

GrumpyMike: I apologize, but this is the entirety of the code. I've double checked it to be sure. All it does at the moment is read the encoder's outputs on pins 8 and 9 on my Arduino Uno R3 and then prints the results in the serial monitor. It does not reflect any of my desires at the moment. Thank you for the suggestion to use a movie clip instead. That makes a lot of sense.

Marco_C: That's informative, thank you. It's helpful to understand the nature of this value better.

binooetomo: Apologies, here's the link to my exact encoder: http://www.sgbotic.com/index.php?dispatch=products.view&product_id=1093 It is hooked to my Arduino Uno R3 precisely as the datasheet suggests.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm sorry BenF, I'm grasping the concept but the syntax of the code is beyond me. Could I possibly trouble you to phrase it in the form of code, just in the context of loop function?
Logged

Pages: [1]   Go Up
Jump to: