Skip to content

Commit

Permalink
refactor code
Browse files Browse the repository at this point in the history
  • Loading branch information
rabidaudio committed Sep 25, 2022
1 parent e5da67d commit d47b305
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 204 deletions.
4 changes: 2 additions & 2 deletions clock/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ States:

- Rate CV input
- Less jittery timer

- Faster speeds for sequencers? Negative subdivisions?
- Get working on bare ATMega328p
- Faster speeds with negative subdivisions

https://en.wikipedia.org/wiki/Swing_(jazz_performance_style)
https://github.com/adafruit/TinyWireM/blob/master/USI_TWI_Master.h
1 change: 1 addition & 0 deletions clock/src/Button.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once

#include <Arduino.h>

// A push-button toggle switch. Supports debouncing.
Expand Down
64 changes: 43 additions & 21 deletions clock/src/Display.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once

#include "SevenSegment.h"

// given a number, get the character at index `digit`
Expand All @@ -23,71 +24,92 @@ char getDigit(int16_t value, size_t digit)
return '0' + value;
}

// A set of 7-segment displays.
// Expects
// An array of 7-segment displays.
// Uses the same digit control port but only addresses one at a time,
// round robbin. This means the more segments there are the worse
// the brightness will be. Must call `tick` on a tight loop to
// switch the digit displayed or else the display will clearly flicker.
// Number of segments must be a compile time constant through `DIGITS`
// template.
// Displays signed 16-bit numbers.
template <size_t DIGITS>
class Display
{
private:
SevenSegment _digits[DIGITS];
size_t _index = 0;
SevenSegment _digits[DIGITS]; // LSB first
size_t _index = 0; // which segment is currently addressed
char _contents[DIGITS];

public:
void begin(volatile uint8_t* segmentPort, uint8_t* ctrlPins)
void begin(uint8_t portNumber, uint8_t *ctrlPins)
{
for(size_t i = 0; i < DIGITS; i++) {
_digits[i].begin(ctrlPins[i], segmentPort);
_contents[i] = ' ';
for (size_t i = 0; i < DIGITS; i++)
{
_digits[i].begin(portNumber, ctrlPins[i]);
setChar(i, ' ');
}
_index = 0;
}

// set all the displays to blank
void clear()
{
for (size_t i = 0; i < DIGITS; i++) {
_contents[i] = ' ';
for (size_t i = 0; i < DIGITS; i++)
{
setChar(i, ' ');
}
}

void tick() {
// update which display is showing
void tick()
{
_digits[_index].turnOff();
_index = (_index + 1) % DIGITS;
_digits[_index].display(_contents[_index]);
_digits[_index].turnOn();
}

void setChar(size_t i, char c) {
if (i < DIGITS) {
void setChar(size_t i, char c)
{
if (i < DIGITS)
{
_contents[i] = c;
}
}

// display a signed number on the
void displayNumber(int16_t number)
{
for (size_t i = 0; i < DIGITS; i++) {
_contents[i] = getDigit(number, i);
for (size_t i = 0; i < DIGITS; i++)
{
setChar(i, getDigit(number, i));
}
}

// light up all segments (all 8's)
void displayReset()
{
for (size_t i = 0; i < DIGITS; i++) {
_contents[i] = '0';
for (size_t i = 0; i < DIGITS; i++)
{
setChar(i, '8');
}
}

void blinkReset()
// blink the reset a few times.
// NOTE: blocking, will return after `blinkCount * 2 * blinkTime` milliseconds.
void blinkReset(size_t blinkCount = 3, uint8_t blinkTime = 50)
{
for (size_t i = 0; i < 3; i++)
for (size_t i = 0; i < blinkCount; i++)
{
clear();
for (size_t i = 0; i < 50; i++) {
for (size_t i = 0; i < blinkTime; i++)
{
tick();
delay(1);
}
displayReset();
for (size_t i = 0; i < 50; i++) {
for (size_t i = 0; i < blinkTime; i++)
{
tick();
delay(1);
}
Expand Down
1 change: 1 addition & 0 deletions clock/src/Knob.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once

#include <Arduino.h>

// A continuous rotary switch with evenly-valued resistors between each
Expand Down
115 changes: 69 additions & 46 deletions clock/src/SevenSegment.h
Original file line number Diff line number Diff line change
@@ -1,60 +1,83 @@
#pragma once

#include <Arduino.h>

#define CHAR_BLANK 0b00000000
#define CHAR_MINUS 0b00000010
#define CHAR_UNDERSCORE 0b00001000

// TODO: would switch be faster than
// array index?
const uint8_t LETTERS[] = {
// ABCDEGF
0b01111101,
0b00110000,
0b01101110,
0b01111010,
0b00110011,
0b01011011,
0b01011111,
0b01110000,
0b01111111,
0b01111011,
//_ABCDEGF
0b01111101,
0b00110000,
0b01101110,
0b01111010,
0b00110011,
0b01011011,
0b01011111,
0b01110000,
0b01111111,
0b01111011,
};

class SevenSegment {
private:
uint8_t _controlPin;
volatile uint8_t* _segmentPort;

public:
// NOTE: its up to the caller to set the segmentPort to an
// output since we don't know which registers to use
void begin(uint8_t controlPin, volatile uint8_t* segmentPort) {
_controlPin = controlPin;
_segmentPort = segmentPort;
pinMode(controlPin, OUTPUT);
turnOff();
}
// Addresses a common-cathode 7-segment display without a
// decimal.
// Assumes ABCDEGF segments are connected to pins 0-6 of
// a AVR port for faster addressing.
// The control pin should be connected to the common cathode.
// It is pulled low to turn on the LEDs.
class SevenSegment
{
private:
uint8_t _controlPin;
volatile uint8_t *_segmentPort;

void turnOff() {
digitalWrite(_controlPin, HIGH);
}
public:
void begin(uint8_t portNumber, uint8_t controlPin)
{
_controlPin = controlPin;
_segmentPort = portOutputRegister(portNumber);
pinMode(controlPin, OUTPUT);
volatile uint8_t *portModeRegister = portModeRegister(portNumber);
*portModeRegister = 0x7F;
turnOff();
}

void turnOn() {
digitalWrite(_controlPin, LOW);
}
void turnOff()
{
digitalWrite(_controlPin, HIGH);
}

bool display(char c) {
if (c >= '0' && c <= '9') {
*_segmentPort = LETTERS[c - '0'];
return true;
}
if (c == ' ') {
*_segmentPort = CHAR_BLANK;
return true;
}
if (c == '-') {
*_segmentPort = CHAR_MINUS;
return true;
}
// unsupported char
return false;
void turnOn()
{
digitalWrite(_controlPin, LOW);
}

bool display(char c)
{
if (c >= '0' && c <= '9')
{
*_segmentPort = LETTERS[c - '0'];
return true;
}
if (c == ' ')
{
*_segmentPort = CHAR_BLANK;
return true;
}
if (c == '-')
{
*_segmentPort = CHAR_MINUS;
return true;
}
if (c == '_')
{
*_segmentPort = CHAR_UNDERSCORE;
return true;
}
// unsupported char
return false;
}
};
1 change: 1 addition & 0 deletions clock/src/TapTempo.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once

#include <Arduino.h>

#define NO_TEMPO 0
Expand Down
Loading

0 comments on commit d47b305

Please sign in to comment.