Creating part 3 base
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
.pio
|
||||||
|
.vscode/.browse.c_cpp.db*
|
||||||
|
.vscode/c_cpp_properties.json
|
||||||
|
.vscode/launch.json
|
||||||
|
.vscode/ipch
|
||||||
@@ -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,29 @@
|
|||||||
|
#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();
|
||||||
|
int speed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Digital_in c1;
|
||||||
|
Digital_in c2;
|
||||||
|
Digital_out led;
|
||||||
|
|
||||||
|
bool previousC1;
|
||||||
|
volatile int count;
|
||||||
|
int pastCount;
|
||||||
|
uint32_t pastTime;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#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 = 115200
|
||||||
@@ -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,106 @@
|
|||||||
|
#include <encoder.h>
|
||||||
|
#include <Arduino.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();
|
||||||
|
|
||||||
|
activeEncoder = this;
|
||||||
|
|
||||||
|
// Clear any pending PORTB pin-change interrupt
|
||||||
|
PCIFR |= (1 << PCIF0);
|
||||||
|
|
||||||
|
// Enable pin-change interrupts for PORTB
|
||||||
|
PCICR |= (1 << PCIE0);
|
||||||
|
|
||||||
|
// Enable interrupt specifically for PB3 / D8 / C1
|
||||||
|
PCMSK0 |= (1 << PCINT0);
|
||||||
|
|
||||||
|
|
||||||
|
//capture baseline
|
||||||
|
previousC1 = c1.is_hi();
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
// Enable global interrupts
|
||||||
|
sei();
|
||||||
|
|
||||||
|
// Set initial states for speed
|
||||||
|
pastCount = count;
|
||||||
|
pastTime = micros();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int Encoder::speed()
|
||||||
|
{
|
||||||
|
int currentCount = position();
|
||||||
|
uint32_t currentTime = micros(); //gives arduino microseconds since program started running
|
||||||
|
|
||||||
|
//from spec sheet we get 1400 counts per revolution from driver
|
||||||
|
// or from assignment 1: 2100
|
||||||
|
int rpm = ((currentCount-pastCount)*6e7)/((currentTime-pastTime)*2100); // we turn counts to rotations by dividing by 1400 and microsecond to minutes by multiplying with 60 and 10^6
|
||||||
|
|
||||||
|
pastTime = currentTime;
|
||||||
|
pastCount = currentCount;
|
||||||
|
|
||||||
|
return rpm;
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
|
#include <encoder.h>
|
||||||
|
#include <digital_out.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
|
||||||
|
Encoder encoder(0, 1, 5);
|
||||||
|
|
||||||
|
Digital_out ain1(3); // D11
|
||||||
|
Digital_out ain2(4); // D12
|
||||||
|
|
||||||
|
encoder.init();
|
||||||
|
|
||||||
|
ain1.init();
|
||||||
|
ain2.init();
|
||||||
|
|
||||||
|
// Motor initially OFF
|
||||||
|
ain1.set_lo();
|
||||||
|
ain2.set_lo();
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
// Give time to open the serial monitor
|
||||||
|
delay(3000);
|
||||||
|
|
||||||
|
Serial.println("time_ms,rpm");
|
||||||
|
|
||||||
|
// Fresh baseline for speed calculation
|
||||||
|
encoder.speed();
|
||||||
|
|
||||||
|
uint32_t startTime = micros();
|
||||||
|
|
||||||
|
// Step input: motor OFF -> full voltage
|
||||||
|
// This direction should give positive RPM
|
||||||
|
ain1.set_lo();
|
||||||
|
ain2.set_hi();
|
||||||
|
|
||||||
|
while ((micros() - startTime) < 4000000UL)
|
||||||
|
{
|
||||||
|
int rpm = encoder.speed();
|
||||||
|
uint32_t time_ms = (micros() - startTime) / 1000UL;
|
||||||
|
|
||||||
|
Serial.print(time_ms);
|
||||||
|
Serial.print(",");
|
||||||
|
Serial.println(rpm);
|
||||||
|
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop motor
|
||||||
|
ain1.set_lo();
|
||||||
|
ain2.set_lo();
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user