Adding Project 1 rotary encoder implementations
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
**/.pio/
|
||||
**/.vscode/
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef DIGITAL_IN_H
|
||||
#define DIGITAL_IN_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class Digital_in
|
||||
{
|
||||
public:
|
||||
Digital_in(int pin);
|
||||
|
||||
void init();
|
||||
|
||||
bool is_hi();
|
||||
bool is_lo();
|
||||
|
||||
private:
|
||||
uint8_t pinMask;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef DIGITAL_OUT_H
|
||||
#define DIGITAL_OUT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class Digital_out
|
||||
{
|
||||
public:
|
||||
Digital_out(int pin);
|
||||
|
||||
void init();
|
||||
void set_hi();
|
||||
void set_lo();
|
||||
void toggle();
|
||||
|
||||
private:
|
||||
uint8_t pinMask;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef ENCODER_H
|
||||
#define ENCODER_H
|
||||
|
||||
#include <digital_in.h>
|
||||
#include <digital_out.h>
|
||||
|
||||
class Encoder
|
||||
{
|
||||
public:
|
||||
Encoder(int c1Pin, int c2Pin, int ledPin);
|
||||
|
||||
void init();
|
||||
void update();
|
||||
int position();
|
||||
|
||||
private:
|
||||
Digital_in c1;
|
||||
Digital_in c2;
|
||||
Digital_out led;
|
||||
|
||||
bool previousC1;
|
||||
int count;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
[env:nanoatmega328new]
|
||||
platform = atmelavr
|
||||
board = nanoatmega328new
|
||||
framework = arduino
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <digital_in.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
Digital_in::Digital_in(int pin)
|
||||
{
|
||||
pinMask = static_cast<uint8_t>(1U << pin);
|
||||
}
|
||||
|
||||
void Digital_in::init()
|
||||
{
|
||||
// Configure pin as input
|
||||
DDRB &= static_cast<uint8_t>(~pinMask);
|
||||
|
||||
// Enable internal pull-up resistor
|
||||
PORTB |= pinMask;
|
||||
}
|
||||
|
||||
bool Digital_in::is_hi()
|
||||
{
|
||||
return (PINB & pinMask) != 0;
|
||||
}
|
||||
|
||||
bool Digital_in::is_lo()
|
||||
{
|
||||
return (PINB & pinMask) == 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <digital_out.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
Digital_out::Digital_out(int pin)
|
||||
{
|
||||
pinMask = static_cast<uint8_t>(1U << pin);
|
||||
}
|
||||
|
||||
void Digital_out::init()
|
||||
{
|
||||
DDRB |= pinMask;
|
||||
}
|
||||
|
||||
void Digital_out::set_hi()
|
||||
{
|
||||
PORTB |= pinMask;
|
||||
}
|
||||
|
||||
void Digital_out::set_lo()
|
||||
{
|
||||
PORTB &= static_cast<uint8_t>(~pinMask);
|
||||
}
|
||||
|
||||
void Digital_out::toggle()
|
||||
{
|
||||
PORTB ^= pinMask;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#include <encoder.h>
|
||||
|
||||
Encoder::Encoder(int c1Pin, int c2Pin, int ledPin)
|
||||
: c1(c1Pin), c2(c2Pin), led(ledPin),
|
||||
previousC1(false), count(0)
|
||||
{
|
||||
}
|
||||
|
||||
void Encoder::init()
|
||||
{
|
||||
c1.init();
|
||||
c2.init();
|
||||
led.init();
|
||||
|
||||
led.set_lo();
|
||||
|
||||
previousC1 = c1.is_hi();
|
||||
count = 0;
|
||||
}
|
||||
|
||||
void Encoder::update()
|
||||
{
|
||||
led.set_lo();
|
||||
|
||||
bool currentC1 = c1.is_hi();
|
||||
|
||||
if (currentC1 != previousC1)
|
||||
{
|
||||
bool currentC2 = c2.is_hi();
|
||||
|
||||
if (currentC1 == currentC2)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
count--;
|
||||
}
|
||||
|
||||
previousC1 = currentC1;
|
||||
led.set_hi();
|
||||
}
|
||||
}
|
||||
|
||||
int Encoder::position()
|
||||
{
|
||||
return count;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <encoder.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
Encoder encoder(0, 1, 5);
|
||||
|
||||
encoder.init();
|
||||
|
||||
while (1)
|
||||
{
|
||||
encoder.update();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef DIGITAL_IN_H
|
||||
#define DIGITAL_IN_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class Digital_in
|
||||
{
|
||||
public:
|
||||
Digital_in(int pin);
|
||||
|
||||
void init();
|
||||
|
||||
bool is_hi();
|
||||
bool is_lo();
|
||||
|
||||
private:
|
||||
uint8_t pinMask;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef DIGITAL_OUT_H
|
||||
#define DIGITAL_OUT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class Digital_out
|
||||
{
|
||||
public:
|
||||
Digital_out(int pin);
|
||||
|
||||
void init();
|
||||
void set_hi();
|
||||
void set_lo();
|
||||
void toggle();
|
||||
|
||||
private:
|
||||
uint8_t pinMask;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef ENCODER_H
|
||||
#define ENCODER_H
|
||||
|
||||
#include <digital_in.h>
|
||||
#include <digital_out.h>
|
||||
|
||||
class Encoder
|
||||
{
|
||||
public:
|
||||
Encoder(int c1Pin, int c2Pin, int ledPin);
|
||||
|
||||
void init();
|
||||
void update();
|
||||
int position();
|
||||
|
||||
private:
|
||||
Digital_in c1;
|
||||
Digital_in c2;
|
||||
Digital_out led;
|
||||
|
||||
bool previousC1;
|
||||
int count;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,5 @@
|
||||
[env:nanoatmega328new]
|
||||
platform = atmelavr
|
||||
board = nanoatmega328new
|
||||
framework = arduino
|
||||
monitor_speed = 9600
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <digital_in.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
Digital_in::Digital_in(int pin)
|
||||
{
|
||||
pinMask = static_cast<uint8_t>(1U << pin);
|
||||
}
|
||||
|
||||
void Digital_in::init()
|
||||
{
|
||||
// Configure pin as input
|
||||
DDRB &= static_cast<uint8_t>(~pinMask);
|
||||
|
||||
// Enable internal pull-up resistor
|
||||
PORTB |= pinMask;
|
||||
}
|
||||
|
||||
bool Digital_in::is_hi()
|
||||
{
|
||||
return (PINB & pinMask) != 0;
|
||||
}
|
||||
|
||||
bool Digital_in::is_lo()
|
||||
{
|
||||
return (PINB & pinMask) == 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <digital_out.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
Digital_out::Digital_out(int pin)
|
||||
{
|
||||
pinMask = static_cast<uint8_t>(1U << pin);
|
||||
}
|
||||
|
||||
void Digital_out::init()
|
||||
{
|
||||
DDRB |= pinMask;
|
||||
}
|
||||
|
||||
void Digital_out::set_hi()
|
||||
{
|
||||
PORTB |= pinMask;
|
||||
}
|
||||
|
||||
void Digital_out::set_lo()
|
||||
{
|
||||
PORTB &= static_cast<uint8_t>(~pinMask);
|
||||
}
|
||||
|
||||
void Digital_out::toggle()
|
||||
{
|
||||
PORTB ^= pinMask;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#include <encoder.h>
|
||||
|
||||
Encoder::Encoder(int c1Pin, int c2Pin, int ledPin)
|
||||
: c1(c1Pin), c2(c2Pin), led(ledPin),
|
||||
previousC1(false), count(0)
|
||||
{
|
||||
}
|
||||
|
||||
void Encoder::init()
|
||||
{
|
||||
c1.init();
|
||||
c2.init();
|
||||
led.init();
|
||||
|
||||
led.set_lo();
|
||||
|
||||
previousC1 = c1.is_hi();
|
||||
count = 0;
|
||||
}
|
||||
|
||||
void Encoder::update()
|
||||
{
|
||||
led.set_lo();
|
||||
|
||||
bool currentC1 = c1.is_hi();
|
||||
|
||||
if (currentC1 != previousC1)
|
||||
{
|
||||
bool currentC2 = c2.is_hi();
|
||||
|
||||
if (currentC1 == currentC2)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
count--;
|
||||
}
|
||||
|
||||
previousC1 = currentC1;
|
||||
led.set_hi();
|
||||
}
|
||||
}
|
||||
|
||||
int Encoder::position()
|
||||
{
|
||||
return count;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#include <Arduino.h>
|
||||
#include <encoder.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
init();
|
||||
|
||||
Encoder encoder(0, 1, 5);
|
||||
|
||||
encoder.init();
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
while (1)
|
||||
{
|
||||
encoder.update();
|
||||
|
||||
Serial.println(encoder.position());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef DIGITAL_IN_H
|
||||
#define DIGITAL_IN_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class Digital_in
|
||||
{
|
||||
public:
|
||||
Digital_in(int pin);
|
||||
|
||||
void init();
|
||||
|
||||
bool is_hi();
|
||||
bool is_lo();
|
||||
|
||||
private:
|
||||
uint8_t pinMask;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef DIGITAL_OUT_H
|
||||
#define DIGITAL_OUT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class Digital_out
|
||||
{
|
||||
public:
|
||||
Digital_out(int pin);
|
||||
|
||||
void init();
|
||||
void set_hi();
|
||||
void set_lo();
|
||||
void toggle();
|
||||
|
||||
private:
|
||||
uint8_t pinMask;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef ENCODER_H
|
||||
#define ENCODER_H
|
||||
|
||||
#include <digital_in.h>
|
||||
#include <digital_out.h>
|
||||
|
||||
class Encoder
|
||||
{
|
||||
public:
|
||||
Encoder(int c1Pin, int c2Pin, int ledPin);
|
||||
|
||||
void init();
|
||||
void update();
|
||||
int position();
|
||||
|
||||
private:
|
||||
Digital_in c1;
|
||||
Digital_in c2;
|
||||
Digital_out led;
|
||||
|
||||
bool previousC1;
|
||||
volatile int count;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:nanoatmega328new]
|
||||
platform = atmelavr
|
||||
board = nanoatmega328new
|
||||
framework = arduino
|
||||
monitor_speed = 9600
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <digital_in.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
Digital_in::Digital_in(int pin)
|
||||
{
|
||||
pinMask = static_cast<uint8_t>(1U << pin);
|
||||
}
|
||||
|
||||
void Digital_in::init()
|
||||
{
|
||||
// Configure pin as input
|
||||
DDRB &= static_cast<uint8_t>(~pinMask);
|
||||
|
||||
// Enable internal pull-up resistor
|
||||
PORTB |= pinMask;
|
||||
}
|
||||
|
||||
bool Digital_in::is_hi()
|
||||
{
|
||||
return (PINB & pinMask) != 0;
|
||||
}
|
||||
|
||||
bool Digital_in::is_lo()
|
||||
{
|
||||
return (PINB & pinMask) == 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <digital_out.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
Digital_out::Digital_out(int pin)
|
||||
{
|
||||
pinMask = static_cast<uint8_t>(1U << pin);
|
||||
}
|
||||
|
||||
void Digital_out::init()
|
||||
{
|
||||
DDRB |= pinMask;
|
||||
}
|
||||
|
||||
void Digital_out::set_hi()
|
||||
{
|
||||
PORTB |= pinMask;
|
||||
}
|
||||
|
||||
void Digital_out::set_lo()
|
||||
{
|
||||
PORTB &= static_cast<uint8_t>(~pinMask);
|
||||
}
|
||||
|
||||
void Digital_out::toggle()
|
||||
{
|
||||
PORTB ^= pinMask;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#include <encoder.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
static Encoder* activeEncoder = nullptr;
|
||||
|
||||
ISR(PCINT0_vect)
|
||||
{
|
||||
if (activeEncoder != nullptr)
|
||||
{
|
||||
activeEncoder->update();
|
||||
}
|
||||
}
|
||||
|
||||
Encoder::Encoder(int c1Pin, int c2Pin, int ledPin)
|
||||
: c1(c1Pin), c2(c2Pin), led(ledPin),
|
||||
previousC1(false), count(0)
|
||||
{
|
||||
}
|
||||
|
||||
void Encoder::init()
|
||||
{
|
||||
c1.init();
|
||||
c2.init();
|
||||
led.init();
|
||||
|
||||
led.set_lo();
|
||||
|
||||
previousC1 = c1.is_hi();
|
||||
count = 0;
|
||||
|
||||
activeEncoder = this;
|
||||
|
||||
// Enable pin-change interrupts for PORTB
|
||||
PCICR |= (1 << PCIE0);
|
||||
|
||||
// Enable interrupt specifically for PB0 / D8 / C1
|
||||
PCMSK0 |= (1 << PCINT0);
|
||||
|
||||
// Clear any pending PORTB pin-change interrupt
|
||||
PCIFR |= (1 << PCIF0);
|
||||
|
||||
// Enable global interrupts
|
||||
sei();
|
||||
}
|
||||
|
||||
void Encoder::update()
|
||||
{
|
||||
led.set_lo();
|
||||
|
||||
bool currentC1 = c1.is_hi();
|
||||
|
||||
if (currentC1 != previousC1)
|
||||
{
|
||||
bool currentC2 = c2.is_hi();
|
||||
|
||||
if (currentC1 == currentC2)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
count--;
|
||||
}
|
||||
|
||||
previousC1 = currentC1;
|
||||
|
||||
led.set_hi();
|
||||
}
|
||||
}
|
||||
|
||||
int Encoder::position()
|
||||
{
|
||||
uint8_t oldSREG = SREG;
|
||||
|
||||
cli();
|
||||
int currentCount = count;
|
||||
SREG = oldSREG;
|
||||
|
||||
return currentCount;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <Arduino.h>
|
||||
#include <encoder.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
init();
|
||||
|
||||
Encoder encoder(0, 1, 5);
|
||||
|
||||
encoder.init();
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
while (1)
|
||||
{
|
||||
Serial.println(encoder.position());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
# Embedded System Projects
|
||||
|
||||
## Project 1 - Rotary Encoder Driver
|
||||
|
||||
This repository contains the three implementations developed for Project 1 in T-738-EMBE.
|
||||
|
||||
### Part 1 - Polling
|
||||
Basic polling-based rotary encoder driver.
|
||||
|
||||
### Part 2 - UART
|
||||
Polling-based encoder driver with continuous Serial output at 9600 baud.
|
||||
|
||||
### Part 3 - Interrupt
|
||||
Interrupt-based encoder driver using a pin-change interrupt on C1.
|
||||
Reference in New Issue
Block a user