#include "image.h"
#include <SPI.h>
#include <Adafruit_ILI9341.h>
#include <Adafruit_GFX.h>
#include <LiquidCrystal.h>
#include <SevSeg.h>
#include <Keypad.h>
#include <Arduino_FreeRTOS.h>
#include <semphr.h>
#define start_pin A1
#define stop_pin A2
const byte rows = 4;
const byte cols = 3;
byte rowPins[rows] = {A15, A14, A13, A12};
byte colPins[cols] = {A11, A10, A9};
char keys[rows][cols] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
Keypad KP(*keys, rowPins, colPins, rows, cols);
SemaphoreHandle_t displayMutex;
QueueHandle_t MQ;
SevSeg uah;
SevSeg litres;
Adafruit_ILI9341 telek = Adafruit_ILI9341(53, 49);
LiquidCrystal tablo(13, 12, 11, 10, 9, 8);
LiquidCrystal tablo_2(7, 6, 5, 4, 3, 2);
// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 67312)
static int result = 0;
static int START = 0;
static int STOP = 0;
static int PHOTO = 0;
static int WAIT = 0;
const unsigned char* photos[4] = {
photo_0,
photo_1,
photo_2,
photo_3
};
byte up[8] = {
B00100,
B01110,
B11111,
B00100,
B00100,
B00100,
B00100,
B00000
};
byte down[8] = {
B00000,
B00100,
B00100,
B00100,
B00100,
B11111,
B01110,
B00100
};
void setup() {
displayMutex = xSemaphoreCreateMutex();
TCCR1A = 0;
TCCR1B = 0;
bitSet(TCCR1B, CS11);
bitSet(TCCR1B, CS10);
bitSet(TIMSK1, TOIE1);
Serial.begin(115200);
pinMode(start_pin, INPUT_PULLUP);
pinMode(stop_pin, INPUT_PULLUP);
byte hardwareConfig = COMMON_CATHODE;
byte numDigits = 4;
byte digitPins[] = {14, 15, 16, 17};
byte segmentPins[] = {22, 23, 24, 25, 26, 27, 28, 29};
bool resistorsOnSegments = true;
bool updateWithDelays = false;
bool leadingZeros = false;
bool disableDecPoint = false;
MQ = xQueueCreate(200, sizeof(int));
uah.begin(hardwareConfig, numDigits, digitPins,
segmentPins, resistorsOnSegments,
updateWithDelays, leadingZeros,
disableDecPoint);
uah.blank();
byte digitPins_2[] = {18, 19, 20, 21};
byte segmentPins_2[] = {32, 33, 34, 35, 36, 37, 38, 39};
litres.begin(hardwareConfig, numDigits, digitPins_2,
segmentPins_2, resistorsOnSegments,
updateWithDelays, leadingZeros,
disableDecPoint);
litres.blank();
telek.begin();
tablo.createChar(3, up);
tablo.createChar(2, down);
tablo.begin(16, 2);
tablo_2.begin(16, 2);
telek.drawBitmap(0, 0, photos[0], 240, 320, ILI9341_WHITE);
tablo.print("Litres - \x03");
tablo.setCursor(0, 1);
tablo.print("Uah - \x02");
tablo_2.print(" \x7F START");
tablo_2.setCursor(0, 1);
tablo_2.print(" STOP \x7E");
xTaskCreate(video, "video", configMINIMAL_STACK_SIZE, NULL, 0, NULL);
xTaskCreate(my_loop, "ML", configMINIMAL_STACK_SIZE, NULL, 0, NULL);
}
static int l = 0;
ISR(TIMER1_OVF_vect) {
if (START == 1 && result > 0 && STOP == 0 && WAIT == 1) {
result--;
}
if (result == 0 && START == 1) {
if (PHOTO > 0) displayByteArray(photos[0]);
START = 0;
PHOTO = 0;
WAIT = 0;
}
}
void video(void *p) {
for (;;) {
xQueueReceive(MQ, &START, portMAX_DELAY);
if (START == 1 && result > 0) {
if (PHOTO == 0) {
displayByteArray_Up_to_Down(photos[1]);
WAIT = 1;
}
displayByteArray(photos[2]);
vTaskDelay(pdMS_TO_TICKS(10));
PHOTO++;
}
}
vTaskDelete(NULL);
}
void my_loop(void *p) {
for (;;) {
byte key = KP.getKey();
int num_digits = (int)log10(result) + 1;
if (result == 0) uah.setNumber(0);
if (num_digits == 5) {
uah.blank();
result = 0;
}
if (key != NO_KEY) {
if (key >= '0' && key <= '9') {
result = result * 10 + (key - '0');
uah.setNumber(result);
} else {
switch (key) {
case '*': {
uah.blank();
result = 0;
}
case '#': {
uah.blank();
result = 0;
}
}
}
}
uah.setNumber(result);
litres.setNumber(result);
if (digitalRead(start_pin) == LOW) {
STOP = 0;
START = 1;
xQueueSend(MQ, &START, portMAX_DELAY);
} else if (digitalRead(stop_pin) == LOW) {
STOP = 1;
}
uah.refreshDisplay();
litres.refreshDisplay();
vTaskDelay(pdMS_TO_TICKS(10));
}
vTaskDelete(NULL);
}
void displayByteArray(const unsigned char* byteArray) {
for (int y = 320 ; y > 0; y--) {
if (STOP != 1) {
for (int x_byte = 0; x_byte < 240 / 8; x_byte++) {
uint8_t byte = pgm_read_byte(&byteArray[y * 240 / 8 + x_byte]);
for (int bit = 0; bit < 8; bit++) {
uint16_t color = (byte & (1 << (7 - bit))) ? ILI9341_WHITE : ILI9341_BLACK;
telek.drawPixel(x_byte * 8 + bit, y, color);
}
}
vTaskDelay(pdMS_TO_TICKS(10 + result * 2));
}
else{
y++;
}
}
}
void displayByteArray_Up_to_Down(const unsigned char* byteArray) {
for (int y = 0; y < 320; y++) {
for (int x_byte = 0; x_byte < 240 / 8; x_byte++) {
uint8_t byte = pgm_read_byte(&byteArray[y * 240 / 8 + x_byte]);
for (int bit = 0; bit < 8; bit++) {
uint16_t color = (byte & (1 << (7 - bit))) ? ILI9341_WHITE : ILI9341_BLACK;
telek.drawPixel(x_byte * 8 + bit, y, color);
}
}
vTaskDelay(pdMS_TO_TICKS(10));
}
}
void loop() {
}