Skip to content

Commit

Permalink
three faces with hands
Browse files Browse the repository at this point in the history
  • Loading branch information
MilovdZee committed Jan 15, 2022
1 parent a0080c3 commit ec4fbb0
Show file tree
Hide file tree
Showing 275 changed files with 466 additions and 46 deletions.
File renamed without changes.
16 changes: 16 additions & 0 deletions 4/hoursHand.pos
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
0 5 60
6 8 61
12 10 61
18 12 60
24 14 59
30 15 56
36 16 53
42 17 49
48 19 46
54 19 41
60 20 36
66 20 30
72 20 25
78 21 19
84 20 13

Binary file added 4/hoursHand_0.bmp
Binary file not shown.
Binary file added 4/hoursHand_12.bmp
Binary file not shown.
Binary file added 4/hoursHand_18.bmp
Binary file not shown.
Binary file added 4/hoursHand_24.bmp
Binary file not shown.
Binary file added 4/hoursHand_30.bmp
Binary file not shown.
Binary file added 4/hoursHand_36.bmp
Binary file not shown.
Binary file added 4/hoursHand_42.bmp
Binary file not shown.
Binary file added 4/hoursHand_48.bmp
Binary file not shown.
Binary file added 4/hoursHand_54.bmp
Binary file not shown.
Binary file added 4/hoursHand_6.bmp
Binary file not shown.
Binary file added 4/hoursHand_60.bmp
Binary file not shown.
Binary file added 4/hoursHand_66.bmp
Binary file not shown.
Binary file added 4/hoursHand_72.bmp
Binary file not shown.
Binary file added 4/hoursHand_78.bmp
Binary file not shown.
Binary file added 4/hoursHand_84.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_0.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_12.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_18.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_24.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_30.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_36.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_42.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_48.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_54.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_6.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_60.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_66.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_72.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_78.bmp
Binary file not shown.
Binary file added 4/hoursHand_mask_84.bmp
Binary file not shown.
16 changes: 16 additions & 0 deletions 4/minutesHand.pos
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
0 4 81
6 7 82
12 8 81
18 10 79
24 12 77
30 13 74
36 15 69
42 16 64
48 18 59
54 19 52
60 19 45
66 19 37
72 19 30
78 19 22
84 20 14

Binary file added 4/minutesHand_0.bmp
Binary file not shown.
Binary file added 4/minutesHand_12.bmp
Binary file not shown.
Binary file added 4/minutesHand_18.bmp
Binary file not shown.
Binary file added 4/minutesHand_24.bmp
Binary file not shown.
Binary file added 4/minutesHand_30.bmp
Binary file not shown.
Binary file added 4/minutesHand_36.bmp
Binary file not shown.
Binary file added 4/minutesHand_42.bmp
Binary file not shown.
Binary file added 4/minutesHand_48.bmp
Binary file not shown.
Binary file added 4/minutesHand_54.bmp
Binary file not shown.
Binary file added 4/minutesHand_6.bmp
Binary file not shown.
Binary file added 4/minutesHand_60.bmp
Binary file not shown.
Binary file added 4/minutesHand_66.bmp
Binary file not shown.
Binary file added 4/minutesHand_72.bmp
Binary file not shown.
Binary file added 4/minutesHand_78.bmp
Binary file not shown.
Binary file added 4/minutesHand_84.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_0.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_12.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_18.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_24.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_30.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_36.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_42.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_48.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_54.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_6.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_60.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_66.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_72.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_78.bmp
Binary file not shown.
Binary file added 4/minutesHand_mask_84.bmp
Binary file not shown.
53 changes: 42 additions & 11 deletions Analog_Clock.ino
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "ClockTFT.h"

#include "defines.h"
#include "clock.h""
boolean timeIsSet = false;
time_t lastNtpSet = 0;
Expand All @@ -21,23 +21,49 @@ time_t previousEffectTime = time(nullptr);
char ssid[60];
char wifiPassword[60];
int numberOfFacesFiles = 0;

ClockTFT tft(TFT_CS, TFT_DC, TFT_RST);
ESP8266WebServer server(80);
ESP8266HTTPUpdateServer httpUpdater;
uint8_t currentFaceNumber;
HandPosition hoursHandPositions[15];
HandPosition minutesHandPositions[15];
// Record the NPT set time
void timeUpdated() {
timeIsSet = true;
lastNtpSet = time(nullptr);
Serial.print("NTP Updated: "); Serial.println(ctime(&lastNtpSet));
Serial.printf("NTP Updated: % s\n", ctime(&lastNtpSet));
}
void printFreeRam() {
Serial.printf("Free ram: % d bytes\n", ESP.getFreeHeap());
}
void listAllFilesInDir(String dir_path)
{
Dir dir = LittleFS.openDir(dir_path);
while(dir.next()) {
if (dir.isFile()) {
// print file names
Serial.printf(" % s - % d\n", dir_path + dir.fileName(), dir.fileSize());
}
if (dir.isDirectory()) {
// print directory names
Serial.printf("Dir: % s / \n", dir_path + dir.fileName());
// recursive file listing inside new directory
listAllFilesInDir(dir_path + dir.fileName() + " / ");
}
}
}
void setup() {
Serial.begin(115200);
while (!Serial); // wait for serial attach
Serial.println();
printFreeRam();
// For the ESP the flash has to be read to a buffer
EEPROM.begin(512);
Expand All @@ -50,9 +76,7 @@ void setup() {
// Setup the wifi
EEPROM.get(SSID_ADDR, ssid);
EEPROM.get(WIFI_PASSWORD_ADDR, wifiPassword);
Serial.print("\r\nConnecting to WIFI '");
Serial.print(String(ssid));
Serial.print("'...\r\n");
Serial.printf("\nConnecting to WIFI '%s'...", String(ssid));
tft.fillCircle(clock_center_x, clock_center_y, SCREEN_DIAMETER / 10, GC9A01A_BLUE);
WiFi.mode(WIFI_STA);
WiFi.hostname(HOSTNAME);
Expand Down Expand Up @@ -103,12 +127,19 @@ void setup() {
delay(1000);
}
// Count the number of faces
Dir dir = LittleFS.openDir("/");
while (dir.next()) numberOfFacesFiles++;
// Show some FS info
FSInfo fs_info;
LittleFS.info(fs_info);
Serial.printf("Total space: % d bytes\n", fs_info.totalBytes);
Serial.printf("Total space used: % d bytes\n", fs_info.usedBytes);
Serial.printf("Block size: % d bytes\n", fs_info.blockSize);
Serial.printf("Page size: % d bytes\n", fs_info.totalBytes);
Serial.printf("Max open files: % d bytes\n", fs_info.maxOpenFiles);
Serial.printf("Max path length: % d bytes\n", fs_info.maxPathLength);
listAllFilesInDir(" / ");
// Initialize face
randomBMP("/clockface%d.bmp");
randomClockFace();
Serial.println();
Serial.println("Running...");
Expand Down
77 changes: 77 additions & 0 deletions BMPHelper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include <LittleFS.h>
#include "BMPHelper.h"

boolean readBMPFile(char *fileName, BMPInfo *bmpInfo) {
File file = LittleFS.open(fileName, "r");
if (!file) return false;

// find total file size
int fileSize = file.size();

// get image data offset
uint16_t imageDataOffset;
file.seek(0x0a);
file.read((uint8_t *)&imageDataOffset, sizeof(imageDataOffset));

// get image width
file.seek(0x12);
file.read((uint8_t *) & (bmpInfo->width), sizeof(bmpInfo->width));

// get image height
file.seek(0x16);
file.read((uint8_t *) & (bmpInfo->height), sizeof(bmpInfo->height));

// get bits per pixel
file.seek(0x1c);
file.read((uint8_t *) & (bmpInfo->bitsPerPixel), sizeof(bmpInfo->bitsPerPixel));

// get DIB size
uint16_t dibSize;
file.seek(0x0e);
file.read((uint8_t *) &dibSize, sizeof(dibSize));

// read colortable (only supported for 1 bit/pixel images)
if (bmpInfo->bitsPerPixel == 1) {
for (int colorIndex = 0; colorIndex <= bmpInfo->bitsPerPixel; colorIndex++) {
file.seek(0x0e + dibSize + colorIndex * 4);
uint32_t colorTableEntry;
file.read((uint8_t *)&colorTableEntry, 4);
uint8_t red = *((uint8_t *)&colorTableEntry);
uint8_t green = *((uint8_t *)&colorTableEntry + 1);
uint8_t blue = *((uint8_t *)&colorTableEntry + 2);
uint16_t color = ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3);
bmpInfo->colorTable[colorIndex] = color;
}
}

// allocate buffer
bmpInfo->paddedWidth = bmpInfo->width % (32 / bmpInfo->bitsPerPixel) ? bmpInfo->width - bmpInfo->width % (32 / bmpInfo->bitsPerPixel) + 32 / bmpInfo->bitsPerPixel : bmpInfo->width;
int bufferSize = bmpInfo->paddedWidth * bmpInfo->height * bmpInfo->bitsPerPixel / 8;

Serial.printf("readBMPFile: fileName='%s', imageDataOffset=%d, width=%d, height=%d, bitsPerPixel=%d, dibSize=%d, paddedWidth=%d, bufferSize=%d\n",
fileName, imageDataOffset, bmpInfo->width, bmpInfo->height, bmpInfo->bitsPerPixel, dibSize, bmpInfo->paddedWidth, bufferSize);

bmpInfo->pixelBuffer = (uint8_t *)malloc(bufferSize);
if (bmpInfo->pixelBuffer == NULL) return false;

// read the image data to the buffer
file.seek(imageDataOffset);
file.read(bmpInfo->pixelBuffer, bufferSize);

return true;
}

uint16_t getPixelColor(BMPInfo *bmpInfo, uint8_t x, uint8_t y) {
// Only support two modes: 1 bit or 16 bit per pixel
if (bmpInfo -> bitsPerPixel == 1) {
uint16_t bufferOffset = (x + y * bmpInfo->paddedWidth) / 8;
uint16_t color = bmpInfo->pixelBuffer[bufferOffset] & 0x80 >> x % 8 ? bmpInfo->colorTable[1] : bmpInfo->colorTable[0];
return color;
} else if (bmpInfo -> bitsPerPixel == 16) {
uint16_t bufferOffset = (x + y * bmpInfo->paddedWidth) * 2;
uint16_t color = *(uint16_t *)(bmpInfo->pixelBuffer + bufferOffset);
return color;
} else {
return 0;
}
}
12 changes: 12 additions & 0 deletions BMPHelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class BMPInfo {
public:
uint16_t width;
uint16_t paddedWidth;
uint16_t height;
uint16_t bitsPerPixel;
uint16_t colorTable[2];
uint8_t *pixelBuffer;
};

boolean readBMPFile(char *fileName, BMPInfo *bmpFile);
uint16_t getPixelColor(BMPInfo *bmpInfo, uint8_t x, uint8_t y);
2 changes: 1 addition & 1 deletion ClockTFT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
ClockTFT::ClockTFT(int8_t cs, int8_t dc, int8_t rst) : Adafruit_GC9A01A(cs, dc, rst) {}

int pixelCount = 0;
Pixel pixelBuffer[5000];
Pixel pixelBuffer[6000];

void ClockTFT::writePixel(uint16_t x, uint16_t y, uint16_t color) {
if (pixelCount < sizeof(pixelBuffer) / sizeof(Pixel)) {
Expand Down
3 changes: 3 additions & 0 deletions FileHelper.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
char* readLine(File &file) {

}
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,21 @@

# Info
- [GC9A01A Arduino Library](https://github.com/PaintYourDragon/Adafruit_GC9A01A)

# BMP files
All files must have a width that is a multiple of 4. This is because the BMP encoding pads all rows
to a 32 bit size.

# LittleFS
- [Arduino ESP8266 LittleFS Filesystem Uploade](https://github.com/earlephilhower/arduino-esp8266littlefs-plugin)

## Efficient LittleFS
To allow for more efficient use of the storage change the blocksize in:

boards.txt:
d1_mini.menu.eesz.4M3M.build.spiffs_blocksize=4096

Maybe also this fil `eagle.flash.4m.ld`:
PROVIDE ( _SPIFFS_start = 0x40308000 ); PROVIDE ( _SPIFFS_block = 0x1000 );

(This does not seem to work)
84 changes: 73 additions & 11 deletions bmp.ino
Original file line number Diff line number Diff line change
@@ -1,31 +1,93 @@
// File MUST be SCREEN_DIAMETER x SCREEN_DIAMETER pixels in 565 format uncompressed

#include "BMPHelper.h"

void drawBMPFromFile(int xOffset, int yOffset, int rotationX, int rotationY, int rotation, boolean erase, char *fileName) {
BMPInfo bmpInfo;
if (readBMPFile(fileName, &bmpInfo)) {
Serial.printf("drawBMPFromFile: file '%s', rotationX=%d, rotationY=%d, rotation=%d, erase=%d\n", fileName, rotationX, rotationY, rotation, erase);

tft.startWrite();
uint16_t bufferPosition = 0;
for (int y = 0; y < bmpInfo.height; y++) {
yield();
for (int x = 0; x < bmpInfo.width; x++) {
uint16_t color = getPixelColor(&bmpInfo, x, bmpInfo.height - y - 1);
// only draw actual pixels. Color 0x0000 is handled as keeping the background
if(color == 0) continue;

if(erase) {
// color 0x0000 erases the pixel and redraws the original color
if(color != 0) {
color = 0;
} else {
continue;
}
}
switch (rotation) {
case 0:
tft.writePixel(xOffset - rotationX + x, yOffset - rotationY + y, color);
break;
case 90:
tft.writePixel(xOffset - (bmpInfo.height - rotationY) + (bmpInfo.height - y), yOffset - rotationX + x, color);
break;
case 180:
tft.writePixel(xOffset + rotationX - x, yOffset + rotationY - y, color);
break;
case 270:
tft.writePixel(xOffset + (bmpInfo.height - rotationY) - (bmpInfo.height - y), yOffset + rotationX - x, color);
break;
}
}
}
tft.endWrite();
printFreeRam();
free(bmpInfo.pixelBuffer);
} else {
Serial.print("drawBMPFromFile: Failed processing '");
Serial.print(fileName);
Serial.println("'");
}
}

File bitmapFile;
long bitmapOffset;

void randomBMP(char *filename) {
int number = random(1, numberOfFacesFiles + 1);
void randomClockFace() {
currentFaceNumber = random(1, NUMBER_OF_FACE_FILES + 1);

readHandPositions("hoursHand.pos", hoursHandPositions);
readHandPositions("minutesHand.pos", minutesHandPositions);

char buffer[50];
snprintf(buffer, sizeof(buffer), filename, number);
initBMP(buffer);
drawBMP(tft);
snprintf(buffer, sizeof(buffer), "/%d/clockface.bmp", currentFaceNumber);
if (initBMP(buffer)) {
drawBMP(tft);
}
}

void initBMP(char* filename) {
boolean initBMP(char* fileName) {
// Get the offset to the first bytes of the actual bitmap
bitmapFile = LittleFS.open(filename, "r");
bitmapFile = LittleFS.open(fileName, "r");
if (!bitmapFile) {
Serial.printf("initBMP: Can't open '%s'\n", fileName);
return false;
}
bitmapFile.seek(10);
bitmapFile.read((uint8_t *)&bitmapOffset, sizeof(bitmapOffset));
return true;
}

void drawBMP(Adafruit_SPITFT &tft) {
void drawBMP(ClockTFT &tft) {
Serial.printf("drawBMP: bitmapOffset=%d\n", bitmapOffset);

tft.startWrite();
tft.setAddrWindow(0, 0, SCREEN_DIAMETER, SCREEN_DIAMETER);

uint16_t buffer[SCREEN_DIAMETER];
for(int y = 0; y < SCREEN_DIAMETER; y++) {
for (int y = 0; y < SCREEN_DIAMETER; y++) {
yield();

long seekPosition = bitmapOffset + (SCREEN_DIAMETER - y - 1) * SCREEN_DIAMETER * 2;
bitmapFile.seek(seekPosition, SeekSet);

Expand Down
7 changes: 7 additions & 0 deletions clock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

class HandPosition {
public:
uint8_t centerX;
uint8_t centerY;
};
Loading

0 comments on commit ec4fbb0

Please sign in to comment.