Implement YL3 display

This commit is contained in:
Mikko Ahlroth 2019-10-26 09:09:53 +03:00
parent ba521c6988
commit 7ac56da7ce
7 changed files with 193 additions and 2 deletions

View file

@ -1,6 +1,7 @@
#include "src/debugger.hpp"
#include "src/game_manager.hpp"
#include "src/randomiser.hpp"
#include "src/yl3.hpp"
Input* input;
Randomiser* randomiser;
@ -8,6 +9,7 @@ GameManager* game;
void setup() {
initDebug(9600);
YL3::initDisplay();
input = new Input();
randomiser = new Randomiser(analogRead(0));
game = new GameManager(input, randomiser);

View file

@ -51,3 +51,18 @@ const auto DELAY_DECREMENT = [](uint16_t delay) -> uint16_t {
* Maximum amount of beeps you can be "behind" before the game is stopped.
*/
const uint8_t MAX_WAITING = 10;
/**
* RCK (latch) pin of YL3 display.
*/
const uint8_t YL3_RCK = 2;
/**
* SCK (clock) pin of YL3 display.
*/
const uint8_t YL3_SCK = 3;
/**
* DIO (data) pin of YL3 display.
*/
const uint8_t YL3_DIO = 4;

View file

@ -3,7 +3,7 @@
#include <Arduino.h>
#include "config.hpp"
void initDebug(uint16_t port) { Serial.begin(port); }
void initDebug(uint16_t speed) { Serial.begin(speed); }
void debugPrint(const String msg, const bool newline) {
if (DEBUG) {

View file

@ -2,5 +2,5 @@
#pragma once
void initDebug(uint16_t port);
void initDebug(uint16_t speed);
void debugPrint(const String msg, const bool newline = true);

View file

@ -7,11 +7,13 @@
#include "input.hpp"
#include "randomiser.hpp"
#include "speed_game.hpp"
#include "yl3.hpp"
GameManager::GameManager(Input* input, Randomiser* randomiser)
: input(input), randomiser(randomiser), state(State::GAME), currentScore(0) {
debugPrint("Initialising new game...");
currentGame = new SpeedGame(randomiser);
YL3::clearDisplay();
}
void GameManager::loop() {
@ -21,9 +23,11 @@ void GameManager::loop() {
if (nextOp.type == NextOperationType::ADD_SCORE) {
currentScore += nextOp.scoreToAdd;
debugPrint("Added score!");
YL3::drawNumber(currentScore);
} else if (nextOp.type == NextOperationType::END) {
debugPrint("Game ended.");
state = State::SCORE;
YL3::drawText("END");
}
}
}

58
src/yl3.cpp Normal file
View file

@ -0,0 +1,58 @@
#include "yl3.hpp"
#include "config.hpp"
byte YL3::char2byte(char c) {
if (c == 45) {
return CHARS[0];
} else if (c == 46) {
return CHARS[1];
} else if (c >= 48 && c < 58) {
return CHARS[c - 48 + 2];
} else if (c >= 65 && c < 91) {
return CHARS[c - 65 + 12];
} else {
return CHARS[0];
}
}
void YL3::drawBegin() { digitalWrite(YL3_RCK, LOW); }
void YL3::drawEnd() { digitalWrite(YL3_RCK, HIGH); }
void YL3::initDisplay() {
pinMode(YL3_RCK, OUTPUT);
pinMode(YL3_SCK, OUTPUT);
pinMode(YL3_DIO, OUTPUT);
}
void YL3::clearDisplay() {
drawBegin();
shiftOut(YL3_DIO, YL3_SCK, MSBFIRST, 0b11111111);
shiftOut(YL3_DIO, YL3_SCK, MSBFIRST, EMPTY);
drawEnd();
}
void YL3::drawText(const String text) {
clearDisplay();
const auto length = text.length();
uint8_t i = 0;
if (length > 8) {
i = length - 8;
}
for (; i < length; ++i) {
drawBegin();
const auto b = char2byte(text.charAt(i));
shiftOut(YL3_DIO, YL3_SCK, MSBFIRST, INDICES[length - 1 - i]);
shiftOut(YL3_DIO, YL3_SCK, MSBFIRST, b);
drawEnd();
}
}
void YL3::drawNumber(const uint32_t score) {
const auto str = String(score);
drawText(str);
}

112
src/yl3.hpp Normal file
View file

@ -0,0 +1,112 @@
#include <Arduino.h>
#include "config.hpp"
#pragma once
/*
* Data for the YL3 2x4 7-segment display.
*
* More reading:
* https://github.com/hennroja/raspberrypi-yl-3-demo/blob/master/demo-YL3.py
* http://forum.arduino.cc/index.php?topic=211197.msg1944509#msg1944509
* https://playground2014.wordpress.com/arduino/3461bs/
*/
namespace YL3 {
/**
* Data for all the characters. The pin order for the segments is PGFEDCBA. See this image for
* reference (P = DP):
* https://upload.wikimedia.org/wikipedia/commons/e/ed/7_Segment_Display_with_Labeled_Segments.svg
*
* Low (0) bit means the segment is lit up.
*/
const byte CHARS[] = {
0b10111111, // -
0b01111111, // .
0b11000000, // 0
0b11111001, // 1
0b10100100, // 2
0b10110000, // 3
0b10011001, // 4
0b10010010, // 5
0b10000010, // 6
0b11111000, // 7
0b10000000, // 8
0b10010000, // 9
0b10001000, // A
0b10000011, // B
0b10111001, // C
0b10100001, // D
0b10110000, // E
0b10001110, // F
0b10000010, // G
0b10001001, // H
0b11111001, // I
0b11110001, // J
0b10000111, // K
0b11000111, // L
0b11001000, // M
0b10101011, // N
0b11000000, // O
0b10001110, // P
0b10011000, // Q
0b10101111, // R
0b10010010, // S
0b10000111, // T
0b11000001, // U
0b11000001, // V
0b11000001, // W
0b10001001, // X
0b10011001, // Y
0b10100100, // Z
};
/**
* Indices to use to select digits on the display. This starts from the right and goes to the left
* for easier indexing when aligning to the right.
*/
const byte INDICES[] = {0b10000000, 0b01000000, 0b00100000, 0b00010000,
0b00001000, 0b00000100, 0b00000010, 0b00000001};
/**
* Empty byte to clear display.
*/
const byte EMPTY = 0b11111111;
/**
* Get byte to send to YL3 for given character.
*/
byte char2byte(const char c);
/**
* Begin drawing on the screen.
*/
void drawBegin();
/**
* End drawing on the screen.
*/
void drawEnd();
/**
* Initialise pins for display.
*/
void initDisplay();
/**
* Clear display entirely.
*/
void clearDisplay();
/**
* Draw text on the screen, right aligned. Text longer than 8 characters will be truncated.
*/
void drawText(const String text);
/**
* Draw a number on the screen, right aligned. Numbers larger than can fit on the display will be
* truncated.
*/
void drawNumber(const uint32_t score);
}; // namespace YL3