New to Arduino and the Forum.I have searched for this for days before actualy purchasing my First Arduino board... but didn't find information.
I found lots of information on how to READ Gray Code but not to Output Gray Code...
I need to use momentary switches to generate Gray Code from Arduino to send to a device that is usualy controlled by a rotary encoder.
The Device is using a 16 Position encoder to Select one of 16 available programs.
I would like to use two momentary push buttons to act as a UP (clockwise rotation) and DOWN (Counter clockwise rotation) to controll this device instead of a rotary encoder.
The goal is to use footswitches for handsfree control of the device. I will send feedback of the Gray Code position to a LCD to know what the current selection is. (I've got that part down faking the encoder using a regular Pot.)
I understand how to read the switches, send human readable text to the LCD and such. My challenge is using Arduino to act as a rotary encoder and send the gray code as if it was a physical encoder. Should I use small relays to do the switching ? Can I simply use the digital outputs ?
any tips on how to Read momentary switches and Send Gray Code ?
any tips on how to Read momentary switches and Send Gray Code ?
I can work it out conceptually in my head as a pretty easy task.
I would define a constant byte array to hold the gray code sequence of 4 bit patterns, so that is in effect a look up table.
Button up and down should simply increment or decrement a simple 16 step counter variable to be used to address into the loop up table.
Extract the 4 bit pattern data for each step change detected and using direct port I/O access I would output the 4 bit data pattern out the low four bits of B port on a 328p based board.
However being a hardware guy I can't whip you out a quick sketch like many of the software gurus we have hanging about.
Anyway the heart is the grey code lookup table which would be as follows:
Not got time to go into this in detail, but here is a C prog I wrote some time ago to both encode and decode grey code. Look at the code, and you should be able to work out how to use the bits you want. There is no need for look-up tables.
/*
Convert decimal number to Grey code and back again
*/
# include<stdio.h>
#define SIZE 32
int bits[SIZE], i; // could be chars in 8 bit machine
unsigned long num; // could be int if less than 17 bit Grey code
void main(){
printf("\n ");
printf("%d",SIZE);
printf(" bit number conversion\n");
printf("\n Enter number ");
scanf("%lu",&num);
/* converting number to binary equivalent */
/* MSB is 1st element in array */
for(i = 0; i < SIZE; i ++){
bits[SIZE-1-i] = (num >> i) & 1;
}
/* printing binary */
printf(" Binary ");
for(i = 0; i < SIZE; i ++){
printf("%d",bits[i]);
}
/* in-line gray code conversion */
for(i = SIZE-1; i > 0; i --){
bits[i] = bits[i] ^ bits[i - 1];
}
/* printing gray code */
printf("\n Gray code ");
for(i = 0; i < SIZE; i ++){
printf("%d",bits[i]);
}
/* in-line conversion back to binary */
for(i = 1; i < SIZE; i++){
bits[i] = bits[i] ^ bits[i - 1];
}
/* reprinting binary */
printf("\n Restored binary ");
for(i=0;i<SIZE;i++){
printf("%d",bits[i]);
}
/* convert back to decimal */
num = 0;
for (i = 0; i < SIZE; i ++){
num = (num<<1) | bits[i];
}
/* reprinting decimal number */
printf("\n Restored decimal ");
printf("%lu",num);
printf("\n");
}
//define pins
#define OUT_A 0 //ch-A of the encoder emulator
#define OUT_B 1 //ch-B of the encoder emulator
#define ENC_CW 1 //direction setting. clockwise
#define ENC_CCW 0 //direction setting. counterclockwise
const unsigned char encout_wf[]={
b01, //0b00 -> 0b01
b11, //0b01 -> 0b11
b00, //0b10 -> 0b00
b10 //0b11 -> 0b10
};
unsigned char encout_val(signed char step) {
//use enc_cw table for clockwise
if (step==ENC_CW) return encout_wf[((digitalRead(OUT_A)?0b10:0b00) | ((digitalRead(OUT_B)?0b01:0b00)];
//use inverse of it for counter-clockwise
else return ~encout_wf[(digitalRead(OUT_A)?0b10:0b00) | (digitalRead(OUT_B)?0b01:0b00)];
}
encout_val(), when called with the direction, will produce the next value for the encoder. For example encout_val(ENC_CW) will produce the next clockwise value from ch-A/B's current positions.
It essentially returns two bits: Bit 0 is Ch-B's output (a '1' is high and a '0' is low), and Bit 1 is Ch-A's output.
Outputting that value, however, is extremely tricky in arduino: you have to ensure that the output is atomic. As such, it is highly implementation dependent.
Should I simply connect the digital pins using resistors where the encoder used to be connected and turn them high/low to simulate the encoder?
It depends on what these switches are connected to. If they are feeding into TTL inputs you can simply connect them no need for resistors. If not then one way is to wire them up across the collector / emitter of a transistor. Check what voltage is across the pins, and connect the collector to the most positive one. Emitter to ground of the switch and the arduino. Base to a 1K resistor and then on to the arduino output pin.