const byte pinA =2;//encoder pin A to Arduino pin 2 which is also interrupt pin 0 which we will useconst byte pinB =3;//encoder pin B to Arduino pin 3 which is also interrupt pin 1 but we won't use it
byte state =0;//will store two bits for pins A & B on the encoder which we will get from the pins aboveint level =0;//a value bumped up or down by the encoder//For demo purposes we will create an array of these binary digits *-
String bits[]={-00-,-01-,-10-,-11-};//A truth table of possible moves 1 for clockwise//-1 for counter clockwwise 0 for error - keybounce *-int bump[]={0,0,-1,1};void setup(){
pinMode(pinA,INPUT);//reads Pin A of the encoder
pinMode(pinB,INPUT);//reads Pin B of the encoder -* Writing to an Input pin turns on an internal pull up resistor *-
digitalWrite(pinA,HIGH);
digitalWrite(pinB,HIGH);//Set up to call our knob function any time pinA rises *-
attachInterrupt(0,knobTurned,RISING);//calls our 'knobTurned()' function when pinA goes from LOW to HIGH level = 50; //a value to start with //Set up for using the on-screen monitor *-
Serial.begin(115200);//make sure your monitor baud rate matches this
Serial.println(-Encoder Ready-);
Serial.print(-level =-);
Serial.println(level);//to remind us where we're starting}void loop(){}void knobTurned(){//AH HA! the knob was turned *-
state =0;//reset this value each time
state = state + digitalRead(pinA);//add the state of Pin A
state --=1;//shift the bit over one spot
state = state + digitalRead(pinB);//add the state of Pin B /* now we have a two bit binary number that holds the state of both pins 00 - something is wrong we must have got here with a key bounce 01 - sames as above - first bit should never be 0 10 - knob was turned backwards 11 - knob was turned forwards We can pull a value out of our truth table and add it to the current level */
level = level + bump[state];// Let's see what happened *-
Serial.print(bits[state]+--);// show us the two bits
Serial.print(bump[state],DEC);// show us the direction of the turn
Serial.print(--);
Serial.println(level);//show us the new value}
https://www.youtube.com/watch?v=FGxLXqzPe3Q is the source for the above code. I saw many codes for MikroC but most are too heavy. I think the above one is light weight and easily port it into MikroC
Okay the code that I posted earlier does what you want.
The reason for why the code is increasing unexpectedly is more than likely because you are not waiting for the encoder to turn. The arduino code using an interrupt to detect a change on one of the pins. Only if there is a change does it call the function turn knobTurned. If you call the function in a loop without waiting for a change then the function will always increment or decrement depending on what state it currently stuck in.
I am also using interrupt. The code, I posted earlier was the Interrupt handler in MikroC.
I have some other doubt.
Code C - [expand]
1
2
3
4
5
6
state =0;
state = state + PORTB.RB0;
state = state <<1;
state = state + PORTB.RB1;
level = level + bump[state];
Display_RPM(state);
This is the code, you posted earlier. Just think PORTB.RB0 = 1 and PORTB.RB1 = 1 then what is the value of state in 5th line of code ? It's 11 Dec or 11 Hex or 11 Binary ? I declare state as Unsigned int. The result is 10 Dec or 11 Dec added to the current value of state. In the arduino code, state is byte in MikroC, there is no byte type variable.
This is the code, you posted earlier. Just think PORTB.RB0 = 1 and PORTB.RB1 = 1 then what is the value of state in 5th line of code ? It's 11 Dec or 11 Hex or 11 Binary ? I declare state as Unsigned int. The result is 10 Dec or 11 Dec added to the current value of state. In the arduino code, state is byte in MikroC, there is no byte type variable.
Yes that is the code you want. What it does is this:
The first line sets state to zero. The second line places a one or a zero in the least significant bit of state depending on the state of the input RB0. The third line shifts that bit that bit over one or multiples it by two. (Note shifting to the left keeps the bit, while shifting to the right removes the bit) The third line places a one or a zero in the least significant bit of state depending on the state of the input RB1.
So after the second line state will be 0 or 1. After the third state will be 0 or 2. After the forth state will be 0, 1, 2, or 3.
This is done using arithmetic and bit wise operations. The calculation is done in such a way that the variable type does not matter. Mainly due to the fact that we are using only the lower two bits. (The sign of the number is determined by the most significant bit.) The data is calculated and read in binary so there is not problem with it indexing outside of the array. The array length is 4 and the max value is 3, which points to the end of the array.
If you need a byte in C you can use any of the following: unsigned char, char, short, or unsigned short. You can always cast the data as one type or another to change the way the compiler reads the bits.
unsignedint i,level,state =0;int bump[]={0,0,-1,1};char*value ="00";void Display_RPM(unsignedint num){
value[1]=(num/10)%10+48;
value[0]= num%10+48;
UART1_Write_Text(value);}void main(){
TRISB =1;
PORTB =0;
TRISC =0;
ADCON0 =0;
INTCON.GIE=1;// Global Interrupt Enable
INTCON.INTE=1;// RB0/INT External Interrupt Enable bit
UART1_Init(9600);// Initialize UART module at 9600 bps
Delay_ms(100);// Wait for UART module to stabilizewhile(1){
PORTC.RC1=1;}}void interrupt()//Interrupt Handler{
INTCON.GIE=0;//Disable Global Interuptif(INTCON.INTF)//RB0/INT External Interrupt Flag bit is set{
state =0;
state = state + PORTB.RB0;
state <<1;
state = state + PORTB.RB1;
level = level + bump[state];
Display_RPM(state);}
INTCON.INTF=0;//Clear RB0/INT External Interrupt Flag bit
INTCON.GIE=1;//Enable Global Interrupt}
This is my test code. But it not working as I want.
Thanks for help from everyone. The actual problem was related to the Display_RPM function. The corrected code is posted here. Special thanks for bluelasers for correcting the shift left function.