Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 2 | |||
![]() |
| × | 2 | |||
Software apps and online services | ||||||
![]() |
| |||||
![]() |
|
This scoreboard was setup for American football, but can do any sport, etc for score keeping using the buttons on the TM1638 board or a BLE Bluetooth app.
Code provided is for the Arduino IDE. I have commented a lot of details in the sketch code that should be helpful.
Setting up the ESP32 to work with the Arduino IDE - this YouTube video I found explains how to: https://www.youtube.com/watch?v=mBaS3YnqDaU
The video below is one I made to help explain things.
I also attached the Android app code (ex. Scoreboard.aia ) that can be imported into MIT app inventor website to modify the blocks code http://appinventor.mit.edu/explore/ or you can use Thunkable - https://thunkable.com which is compatible with the attached code.
I believe there is a few other online Android app makers that are compatible as well.
Important Notes:
1. In the MIT app Inventor you will have to change the MAC address to match the your ESP's Bluetooth MAC address. (In the "blocks" section it is the only code I commented on)
Here is a link of how to find out your ESP32 Bluetooth MAC address:
https://techtutorialsx.com/2018/03/09/esp32-arduino-getting-the-bluetooth-device-address/
2. Save these files in the same directory.
- Scoreboard_MKII.ino
- wiring_shift_mod.cpp
- wiring_shift_mod.h
- The app should auto connect and light up the LED when it is opened.
- Your Android device needs to support bluetooth 4.0 (BLE) to do this as well have paired the device (Show up as Scoreboard in your bluetooth settings) and (for some reason) have location services turned on for it to connect properly.
- The Android app will automatically Update the Score from the ESP32.
Here is the files to 3d print the scoreboard I have posted on my Thingiverse page.
https://www.thingiverse.com/thing:3365782
Other Resources I found to build this: (I can take little credit in this development for this project)
https://www.hackster.io/botletics/esp32-ble-android-arduino-ide-awesome
7 Segment Hex values:https://en.wikipedia.org/wiki/Seven-segment_display
sendCommand(0x8f) = Hex value at max brightness. Lowest brightness hex value = 0x8a
// ESP32 Dev board - DOIT ESP32 DEVKIT V1
// TM1638 7 Segment Display with buttons
// 10K resistor (x2)
// PushButton (x2)
// Blue LED
/* Wiring Notes as per code below:
Blue LED -
Negative (short LED pin) -> GND
Positive (long LED pin) -> D21 (GPIO pin)
Home & Vistor push buttons -
Button pin -> D22 (home)GPIO pin / D23 (visitor) GPIO pin
Button pin -> 10K resistor -> GND
Other side button pin -> 3V3 pin
TM1638 7 Segment Display with buttons -
VCC > 3V3
GND > GND
STB > D4 (GPIO pin)
CLK > RX2 (16 GPIO pin)
DIO > TX2 (17 GPIO pin)
*/
// To Do: Fix diplays when plugged in
#include "wiring_shift_mod.h"
#define CLOCK_TYPE CLOCK_INVERT
#define CLOCK_DELAY_US 1
// Bluetooth
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
BLEServer *pServer = NULL;
BLECharacteristic * pTxCharacteristic;
bool deviceConnected = false;
bool oldDeviceConnected = false;
// See the following for generating UUIDs: https://www.uuidgenerator.net/
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_ScoreTX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
// ESP32 pins used for Segment display
uint8_t strobe_pin = 4;
uint8_t clock_pin = 16; // pin RX2
uint8_t data_pin = 17; // pin TX2
//Variables
uint8_t hScore = 0; // 1st digit in Home Score
uint8_t hScore2 = 0; // 2nd digit in Home Score
uint8_t vScore = 0; // 1st digit in Vistor Score
uint8_t vScore2 = 0; // 2nd digit in Vistor Score
uint8_t hTScore = 0; //Total Home score for Bluetooth Android app
uint8_t vTScore = 0; //Total Home score for Bluetooth Android app
uint8_t currentHomePoints = hTScore; //Used to compare scores for loop to prevent consent BT packets been sent to Client
uint8_t currentVisitorPoints = vTScore; //Used to compare scores for loop to prevent consent BT packets been sent to Client
//Reset Buttons
const uint8_t resetHomePin = 22;
const uint8_t resetVisitorPin = 23;
// variables will change:
uint8_t resetbuttonStateH = 0; // variable for reading the pushbutton status
uint8_t resetbuttonStateV = 0;
// Displays numbers in order of array Hex values(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) ex. NUMBERS[5] displays the number 5.
const uint8_t NUMBERS[] = {
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F
};
// Display Segment that is used left to right in order of (array Hex values 0-7 on 8 segment display) ex. SSD[0] uses first 7 Segment display
const uint8_t SSD[] = {
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce
};
uint8_t readButtons(void)
{
uint8_t buttons = 0;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, 0x42);
pinMode(data_pin, INPUT);
for (uint8_t i = 0; i < 4; i++)
{
uint8_t v = shiftInMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US) << i; buttons |= v;
}
pinMode(data_pin, OUTPUT);
digitalWrite(strobe_pin, HIGH);
return buttons;
}
///////////////////////////////////////////////////////////
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
uint8_t buttons = readButtons();
// Print out in Serial Monitor buttons pressed
//if (rxValue.length() > 0) {
//Serial.println("*********");
//Serial.print("Received Value: ");
// for (int i = 0; i < rxValue.length(); i++)
// Serial.print(rxValue[i]);
if (rxValue.find("update") != -1) {
updateBTapp();
}
if (rxValue.find("rHome") != -1) {
resetHome();
}
if (rxValue.find("rVisitor") != -1) {
resetVisitor();
}
if (rxValue.find("h1") != -1) {
addHome1Point();
}
if (rxValue.find("h2") != -1) {
addHome2Points();
}
if (rxValue.find("h3") != -1) {
addHome3Points();
}
if (rxValue.find("h6") != -1) {
addHome6Points();
}
if (rxValue.find("v1") != -1) {
addVisitor1Point();
}
if (rxValue.find("v2") != -1) {
addVisitor2Points();
}
if (rxValue.find("v3") != -1) {
addVisitor3Points();
}
if (rxValue.find("v6") != -1) {
addVisitor6Points();
}
// Serial.println();
//Serial.println("*********");
}
};
/////////////////////////////////////////////////////////
void sendCommand(uint8_t value)
{
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, value);
digitalWrite(strobe_pin, HIGH);
}
//////////////////////////////////////////////////////////////
void reset(){
digitalWrite(strobe_pin, LOW);
for (uint8_t i = 0; i < 8; i++){
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[i]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, 0x00);
}
digitalWrite(strobe_pin, HIGH);
hScore = 0; // Reset value of 1st digit in Home Score
hScore2 = 0; // Reset value of 2nd digit in Home Score
vScore = 0; // Reset value of 1st digit in Vistor Score
vScore2 = 0; // Reset value of 2nd digit in Vistor Score
hTScore = 0; //Reset Home score for Bluetooth Android app
vTScore = 0; //Reset Home score for Bluetooth Android app
currentHomePoints = 0;
currentVisitorPoints = 0;
}
//////////////////////////////////////////////////////////////
void resetHome() {
digitalWrite(strobe_pin, LOW);
for (uint8_t i = 0; i < 4; i++){
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[i]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, 0x00); // Clears Vistor Segments
}
digitalWrite(strobe_pin, HIGH);
hScore = 0; // Reset value of 1st digit in Home Score
hScore2 = 0; // Reset value of 2nd digit in Home Score
hTScore = 0; //Reset Home score for Bluetooth Android app
}
/////////////////////////////////////////////////////////////
void resetVisitor() {
digitalWrite(strobe_pin, LOW);
for (uint8_t i = 4; i < 8; i++){
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[i]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, 0x00); // Clears Vistor Segments
}
digitalWrite(strobe_pin, HIGH);
vScore = 0; // Reset value of 1st digit in Vistor Score
vScore2 = 0; // Reset value of 2nd digit in Vistor Score
vTScore = 0; //Reset Home score for Bluetooth Android app
}
////////////////////////////////////////////////////////////
void addHome1Point() {
if (hScore2 < 9) { // Displays 1-9 on Home scoreboard
hScore2 = hScore2 + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore2]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hTScore++;
}
else if (hScore2 == 9) { // Displays (10,20,30,40,50,60,70,80,90) on Home scoreboard
hScore = hScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[1]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[0]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hScore2 = 0;
hTScore++;
}
}
////////////////////////////////////////////////////////////
void addHome2Points() {
if (hScore2 < 8) { // Displays 1-9 on Home scoreboard
hScore2 = hScore2 + 2;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore2]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hTScore = hTScore+2;
}
else if (hScore2 == 8) { // Displays (10,20,30,40,50,60,70,80,90) on Home scoreboard
hScore = hScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[1]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[0]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hScore2 = 0;
hTScore = hTScore+2;
}
else if (hScore2 == 9) { // Displays (11,21,31,41,51,61,71,81,91) on Home scoreboard
hScore = hScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[1]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[1]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hScore2 = 1;
hTScore = hTScore+2;
}
}
////////////////////////////////////////////////////////////
void addHome3Points() {
if (hScore2 < 7) { // Displays 1-9 on Home scoreboard
hScore2 = hScore2 + 3;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore2]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hTScore = hTScore+3;
}
else if (hScore2 == 7) { // Displays (10,20,30,40,50,60,70,80,90) on Home scoreboard
hScore = hScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[1]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[0]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hScore2 = 0;
hTScore = hTScore+3;
}
else if (hScore2 == 8) { // Displays (11,21,31,41,51,61,71,81,91) on Home scoreboard
hScore = hScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[1]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[1]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hScore2 = 1;
hTScore = hTScore+3;
}
else if (hScore2 == 9) { // Displays (12,22,32,42,52,62,72,82,92) on Home scoreboard
hScore = hScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[1]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[2]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hScore2 = 2;
hTScore = hTScore+3;
}
}
////////////////////////////////////////////////////////////
void addHome6Points() {
if (hScore2 < 4) { // Displays 1-9 on Home scoreboard
hScore2 = hScore2 + 6;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore2]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hTScore = hTScore+6;
}
else if (hScore2 == 4) { // Displays (10,20,30,40,50,60,70,80,90) on Home scoreboard
hScore = hScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[1]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[0]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hScore2 = 0;
hTScore = hTScore+6;
}
else if (hScore2 == 5) { // Displays (11,21,31,41,51,61,71,81,91) on Home scoreboard
hScore = hScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[1]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[1]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hScore2 = 1;
hTScore = hTScore+6;
}
else if (hScore2 == 6) { // Displays (12,22,32,42,52,62,72,82,92) on Home scoreboard
hScore = hScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[1]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[2]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hScore2 = 2;
hTScore = hTScore+6;
}
else if (hScore2 == 7) { // Displays (13,23,33,43,53,63,73,83,93) on Home scoreboard
hScore = hScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[1]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[3]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hScore2 = 3;
hTScore = hTScore+6;
}
else if (hScore2 == 8) { // Displays (14,24,34,44,54,64,74,84,94) on Home scoreboard
hScore = hScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[1]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[4]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hScore2 = 4;
hTScore = hTScore+6;
}
else if (hScore2 == 9) { // Displays (15,25,35,45,55,65,75,85,95) on Home scoreboard
hScore = hScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[1]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[hScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[2]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[5]);
digitalWrite(strobe_pin, HIGH);
delay(250);
hScore2 = 5;
hTScore = hTScore+6;
}
}
////////////////////////////////////////////////////////////
void addVisitor1Point() {
if (vScore2 < 9) { // Displays 1-9 on Visitor scoreboard
vScore2 = vScore2 + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore2]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vTScore++;
}
else if (vScore2 == 9) { // Displays (10,20,30,40,50,60,70,80,90) on Visitor scoreboard
vScore = vScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[5]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[0]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vScore2 = 0;
vTScore++;
}
}
////////////////////////////////////////////////////////////
void addVisitor2Points() {
if (vScore2 < 8) { // Displays 1-9 on Visitor scoreboard
vScore2 = vScore2 + 2;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore2]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vTScore = vTScore+2;
}
else if (vScore2 == 8) { // Displays (10,20,30,40,50,60,70,80,90) on Visitor scoreboard
vScore = vScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[5]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[0]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vScore2 = 0;
vTScore = vTScore+2;
}
else if (vScore2 == 9) { // Displays (11,21,31,41,51,61,71,81,91) on Visitor scoreboard
vScore = vScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[5]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[1]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vScore2 = 1;
vTScore = vTScore+2;
}
}
////////////////////////////////////////////////////////////
void addVisitor3Points() {
if (vScore2 < 7) { // Displays 1-9 on Visitor scoreboard
vScore2 = vScore2 + 3;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore2]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vTScore = vTScore+3;
}
else if (vScore2 == 7) { // Displays (10,20,30,40,50,60,70,80,90) on Visitor scoreboard
vScore = vScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[5]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[0]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vScore2 = 0;
vTScore = vTScore+3;
}
else if (vScore2 == 8) { // Displays (11,21,31,41,51,61,71,81,91) on Visitor Scoreboard
vScore = vScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[5]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[1]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vScore2 = 1;
vTScore = vTScore+3;
}
else if (vScore2 == 9) { // Displays (12,22,32,42,52,62,72,82,92) on Visitor Scoreboard
vScore = vScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[5]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[2]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vScore2 = 2;
vTScore = vTScore+3;
}
}
////////////////////////////////////////////////////////////
void addVisitor6Points() {
if (vScore2 < 4) { // Displays 1-9 on Visitor scoreboard
vScore2 = vScore2 + 6;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore2]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vTScore = vTScore+6;
}
else if (vScore2 == 4) { // Displays (10,20,30,40,50,60,70,80,90) on Visitor scoreboard
vScore = vScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[5]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[0]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vScore2 = 0;
vTScore = vTScore+6;
}
else if (vScore2 == 5) { // Displays (11,21,31,41,51,61,71,81,91) on Visitor Scoreboard
vScore = vScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[5]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[1]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vScore2 = 1;
vTScore = vTScore+6;
}
else if (vScore2 == 6) { // Displays (12,22,32,42,52,62,72,82,92) on Visitor Scoreboard
vScore = vScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[5]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[2]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vScore2 = 2;
vTScore = vTScore+6;
}
else if (vScore2 == 7) { // Displays (13,23,33,43,53,63,73,83,93) on Visitor Scoreboard
vScore = vScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[5]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[3]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vScore2 = 3;
vTScore = vTScore+6;
}
else if (vScore2 == 8) { // Displays (14,24,34,44,54,64,74,84,94) on Visitor Scoreboard
vScore = vScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[5]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[4]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vScore2 = 4;
vTScore = vTScore+6;
}
else if (vScore2 == 9) { // Displays (15,25,35,45,55,65,75,85,95) on Visitor Scoreboard
vScore = vScore + 1;
digitalWrite(strobe_pin, LOW);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[5]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[vScore]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, SSD[6]);
shiftOutMod(data_pin, clock_pin, LSBFIRST, CLOCK_TYPE, CLOCK_DELAY_US, NUMBERS[5]);
digitalWrite(strobe_pin, HIGH);
delay(250);
vScore2 = 5;
vTScore = vTScore+6;
}
}
////////////////////////////////////////////////////////////
// Buttons to add points to Scoreboard
void addPoints() {
uint8_t buttons = readButtons(); //Reads what button was pushed
// Add Points to Home Score (left side)
// Button to add 1 point to Home Scoreboard
if (buttons == 1) {
addHome1Point();
}
// Button to add 2 points to Home Scoreboard
if (buttons == 2) {
addHome2Points();
}
// Button to add 3 points to Home Scoreboard
if (buttons == 4) {
addHome3Points();
}
// Button to add 6 points to Home Scoreboard
if (buttons == 8) {
addHome6Points();
}
//////////////////
// Add Points to Visitor Score (right side)
// Button to add 1 point to Visitor Scoreboard
if (buttons == 16) {
addVisitor1Point();
}
// Button to add 2 points to Visitor Scoreboard
if (buttons == 32) {
addVisitor2Points();
}
// Button to add 3 points to Visitor Scoreboard
if (buttons == 64) {
addVisitor3Points();
}
// Button to add 6 points to Visitor Scoreboard
if (buttons == 128) {
addVisitor6Points();
}
}
//////////////////////////////////////////////////////////////
void points2BTapp() {
if (hTScore != currentHomePoints) {
//For Displaying Home Team score to Bluetooth app
//Convert the value to a char array:
char hTString[8]; //the ASCII of the integer will be stored in this char array
itoa(hTScore,hTString,10); //(integer, yourBuffer, base)for integer variable convert to string for BT app
char sHome[] = "h";
char sHomeBT [] = {0};
// Merge Char arrays to have "h" appear before the score for BT app control
strcat(sHomeBT, sHome);
strcat(sHomeBT, hTString);
pTxCharacteristic->setValue(sHomeBT);
pTxCharacteristic->notify(); // Send the value to the app!
Serial.print("*** Home: ");
Serial.print(sHomeBT);
Serial.println(" ***");
currentHomePoints = hTScore;
}
if (vTScore != currentVisitorPoints) {
//For Displaying Home Team score to Bluetooth app
//Convert the value to a char array:
char vTString[8]; //the ASCII of the integer will be stored in this char array
itoa(vTScore,vTString,10); //(integer, yourBuffer, base)for integer variable convert to string for BT app
char sVisitor[] = "v";
char sVisitorBT [] = {0};
// Merge Char arrays to have "v" appear before the score for BT app control
strcat(sVisitorBT, sVisitor);
strcat(sVisitorBT, vTString);
pTxCharacteristic->setValue(sVisitorBT);
pTxCharacteristic->notify(); // Send the value to the app!
Serial.print("*** Visitors: ");
Serial.print(sVisitorBT);
Serial.println(" ***");
currentVisitorPoints = vTScore;
}
}
////////////////////////////////////////////////////////////
void updateBTapp() { // reset scores on BT Android app
char hTString[8]; //the ASCII of the integer will be stored in this char array
itoa(hTScore,hTString,10); //(integer, yourBuffer, base)for integer variable convert to string for BT app
char sHome[] = "h";
char sHomeBT [] = {0};
// Merge Char arrays to have "h" appear before the score for BT app control
strcat(sHomeBT, sHome);
strcat(sHomeBT, hTString);
pTxCharacteristic->setValue(sHomeBT);
pTxCharacteristic->notify(); // Send the value to the app!
currentHomePoints = hTScore;
//For Displaying Home Team score to Bluetooth app
//Convert the value to a char array:
char vTString[8]; //the ASCII of the integer will be stored in this char array
itoa(vTScore,vTString,10); //(integer, yourBuffer, base)for integer variable convert to string for BT app
char sVisitor[] = "v";
char sVisitorBT [] = {0};
// Merge Char arrays to have "v" appear before the score for BT app control
strcat(sVisitorBT, sVisitor);
strcat(sVisitorBT, vTString);
pTxCharacteristic->setValue(sVisitorBT);
pTxCharacteristic->notify(); // Send the value to the app!
currentVisitorPoints = vTScore;
}
////////////////////////////////////////////////////////////
void setup() {
Serial.begin(115200);
pinMode(strobe_pin, OUTPUT);
pinMode(clock_pin, OUTPUT);
pinMode(data_pin, OUTPUT);
pinMode(2, OUTPUT); //initialize Internal LED pin
pinMode(21, OUTPUT); //initialize LED pin using for showing Bluetooth device connected
pinMode(resetHomePin, INPUT); // initialize the pushbutton pins as an input:
pinMode(resetVisitorPin, INPUT);
sendCommand(0x8f); // activate at max brightness
reset(); // initialize screen
// Create the BLE Device
BLEDevice::init("ScoreBoard"); //Set Name of ESP device
// Create the BLE Server
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pTxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_ScoreTX, BLECharacteristic::PROPERTY_NOTIFY);
pTxCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE);
pRxCharacteristic->setCallbacks(new MyCallbacks());
// Start the service
pService->start();
// Start advertising
pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");
}
///////////////////////////////////////////////////////////
void loop()
{
//sendCommand(0x44); // set single
if (deviceConnected) {
points2BTapp();
delay(100); // bluetooth stack will go into congestion, if too many packets are sent -> adjust delay for better response times from Android app
digitalWrite(21, HIGH);
}
// disconnecting
if (!deviceConnected && oldDeviceConnected) {
delay(500); // give the bluetooth stack the chance to get things ready
pServer->startAdvertising(); // restart advertising
Serial.println("start advertising");
oldDeviceConnected = deviceConnected;
digitalWrite(21, LOW);
}
// connecting
if (deviceConnected && !oldDeviceConnected) {
// do stuff here on connecting
oldDeviceConnected = deviceConnected;
}
addPoints();
resetbuttonStateH = digitalRead(resetHomePin); // read the state of the pushbutton values
if (resetbuttonStateH == HIGH) { // check if the pushbutton is pressed
resetHome();
}
resetbuttonStateV = digitalRead(resetVisitorPin); // read the state of the pushbutton values
if (resetbuttonStateV == HIGH) { // check if the pushbutton is pressed
resetVisitor();
}
}
wiring_shift_mod.cpp
C/C++/*
wiring_shift_mod.c - clocked shift functions
Based on Arduino's wiring_shift.c
Original work Copyright 2005-2006 David A. Mellis
Modified work Copyright 2017 Martin F. Falatic
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
#include "wiring_private.h"
#include "wiring_shift_mod.h"
uint8_t shiftInMod(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t clock_type, uint16_t clock_delay_us) {
uint8_t value = 0;
uint8_t i;
for (i = 0; i < 8; ++i) {
digitalWrite(clockPin, (clock_type ? LOW : HIGH));
delayMicroseconds(clock_delay_us);
if (bitOrder == LSBFIRST)
value |= digitalRead(dataPin) << i;
else
value |= digitalRead(dataPin) << (7 - i);
digitalWrite(clockPin, (clock_type ? HIGH : LOW));
}
return value;
}
void shiftOutMod(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t clock_type, uint16_t clock_delay_us, uint8_t val)
{
uint8_t i;
for (i = 0; i < 8; i++) {
if (bitOrder == LSBFIRST)
digitalWrite(dataPin, !!(val & (1 << i)));
else
digitalWrite(dataPin, !!(val & (1 << (7 - i))));
digitalWrite(clockPin, (clock_type ? LOW : HIGH));
delayMicroseconds(clock_delay_us);
digitalWrite(clockPin, (clock_type ? HIGH : LOW));
}
}
wiring_shift_mod.h
C/C++#ifndef wiring_shift_mod_h
#define wiring_shift_mod_h
#define CLOCK_NORMAL 0
#define CLOCK_INVERT 1
void shiftOutMod(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t clock_type, uint16_t clock_delay_us, uint8_t val);
uint8_t shiftInMod(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t clock_type, uint16_t clock_delay_us);
#endif
Scoreboard_MKII.aia
C/C++No preview (download only).
Comments
Please log in or sign up to comment.