In the sketch below I am unable to have the functions switchRead() and adjustValue() give the desired display value.
when switchRead is commented The rotary encoder increments/decrements as desired. it roll overs from 9 to 0 and 0 to 9.
and when the adjustValue() function and PORTB |= (1<<PB0) are commented out the display digits are selected individually on single, double triple and ffour taps and all displays off on hold, and all four displays on on tapandhold. the sketch is
//For ATmega328
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
/* Defines for encoder and button(sw)*/
#define CLK PC0
#define DATA PC1
#define SW PC2
static uint8_t prevNextCode = 0;
static uint16_t store = 0;
static int8_t rot_enc_table[] = {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0};
int lastButtonState = HIGH; // the previous reading from the input pin
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
bool buttonState = HIGH; //saving state of the switch
volatile byte tapCounter; //for saving no. of times the switch is pressed
int timediff; //for saving the time in between each press and release of the switch
bool flag1, flag2; //just two variables
long double presstime, releasetime; //for saving millis at press and millis at release
/* Defines for Seven segment display */
#define disp1 PB0
#define disp2 PB1
#define disp3 PB2
#define disp4 PB3
//volatile uint8_t digit[4];
volatile uint8_t segmentsfa[] = {0b11111100, 0b00011000, 0b01101100, 0b00111100, 0b10011000, 0b10110100, 0b11110100, 0b00011100, 0b11111100, 0b10111100};
volatile uint8_t segmentsg[] = {0b00000000, 0b00000000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00000000, 0b00100000, 0b00100000};
volatile int k, j, i, h, val = 0 ;
volatile int temp;
void setup() {
DDRC &= ~((1 << DDC2) | (1 << DDC1) | (1 << DDC0)); //Set PC0 and PC1 and PC2 as input
PINC |= ((1 << PINC2) | (1 << PINC1) | (1 << PINC0)); // Input pullups enabled
PORTD = 0xFF; /* Writing all bits on port D to 0 */
DDRD = 0xFF; /* Port D set as ouput */
DDRD &= ~(1 << DDD0); // Setting PDO as input
PIND = (1 << PIND0); // Enabled input pullup.
PORTB = 0b00000000;
DDRB = 0b11111111 ; /* define port direction for PB0 to PB5 as output */
noDisp();
Serial.begin(9600);
}
void loop () {
adjustValue();
PORTB |=(1 << PB0);
//switchRead();
}
int switchRead () {
int reading = PINC & (1 << PC2);
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
}
}
//when switch is pressed
if (buttonState == 0 && flag2 == 0)
{
presstime = millis(); //time from millis fn will save to presstime variable
flag1 = 0;
flag2 = 1;
tapCounter++; //tap counter will increase by 1
}
//when sw is released
if (buttonState == 1 && flag1 == 0)
{
releasetime = millis(); //time from millis fn will be saved to releasetime var
flag1 = 1;
flag2 = 0;
timediff = releasetime - presstime; //here we find the time gap between press and release and stored to timediff var
}
if ((millis() - presstime) > 400 && buttonState == 1) //wait for some time and if sw is in release position
{
if (tapCounter == 1) //if tap counter is 1
{
if (timediff >= 400) //if time diff is larger than 400 then its a hold
{
//Serial.println("Hold");
hold(); //fn to call when the button is hold
}
else //if timediff is less than 400 then its a single tap
{
//Serial.println("single tap");
singleTap(); //fn to call when the button is single taped
}
}
else if (tapCounter == 2 ) //if tapcounter is 2
{
if (timediff >= 400) // if timediff is greater than 400 then its single tap and hold
{
// Serial.println("single tap and hold");
tapAndHold(); //fn to call when the button is single tap and hold
}
else // if timediff is less than 400 then its just double tap
{
//Serial.println("double tap");
doubleTap(); //fn to call when doubletap
}
}
else if (tapCounter == 3) //if tapcounter is 3 //then its triple tap
{
//Serial.println("triple tap");
tripleTap(); //fn to call when triple tap
}
else if (tapCounter == 4) //if tapcounter is 4 then its 4 tap
{
//Serial.println("four tap");
fourTap();//fn to call when four tap
}
tapCounter = 0;
}
lastButtonState = reading;
}
void noDisp()
{
PORTB &= ~((1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3));
}
void singleTap()
{
noDisp();
PORTB |= (1 << PB0);
}
void doubleTap()
{
noDisp();
PORTB |= (1 << PB1);
}
void tripleTap()
{
noDisp();
PORTB |= (1 << PB2);
}
void fourTap()
{
noDisp();
PORTB |= (1 << PB3);
}
void hold()
{
noDisp();
}
void tapAndHold()
{
noDisp();
PORTB |= ((1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3));
//PORTB &= ~(1 << PB1);
//PORTB &= ~(1 << PB2);
//PORTB &= ~(1 << PB3);
}
// A valid CW or CCW move returns 1, invalid returns 0
int read_rotary() {
prevNextCode <<= 2;
if (PINC & (1 << DATA)) prevNextCode |= 0x02; //digitalRead the DATA pin
if (PINC & (1 << CLK)) prevNextCode |= 0x01; //digitalRead the CLK pin
prevNextCode &= 0x0f;
//if valid store as 16 bit data
if (rot_enc_table[prevNextCode]) {
store <<= 4;
store |= prevNextCode;
if ((store & 0xff) == 0x2b) return -1;
if ((store & 0xff) == 0x17) return 1;
}
return 0;
}
int adjustValue () {
PORTB = segmentsg[temp];
PORTD = segmentsfa[temp];
if (val = read_rotary()) {
temp += val;
if (temp >= 10) {
temp = 0;
}
if (temp <= -1) {
temp = 9;
}
}
}
How can I rewrite get these functions to get them working like a thumbwheel interface, I am not getting it. I am using Arduino Uno .