/*
LoadFromSD.ino
Demonstrate how to read a XBM file from SD card.
This example will write a XBM image to SD card as a preparation during setup ("u8g2.bin").
The written file content will be displayed.
There is also an external conversion tool, which generates the expected binary from a PNG file:
https://github.com/olikraus/u8g2/tree/master/tools/png2bin
Remember to adjust SD.begin(SD_CS) argument.
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2019, [email protected]
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <Adafruit_NeoPixel.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <SPI.h>
#include <SD.h>
// Define the pin numbers for the LCD interface
#define NEOPIXEL_PIN 6
#define NUM_PIXELS 3
#define LCD_CS 8
#define LCD_A0 9
#define LCD_RST 10
#define SPI_MOSI 11
#define SPI_MISO 12
#define SPI_SCLK 13
#define LCD_MOSI A1
#define LCD_SCK A2
// Define the pins for the switch, the encoder, and the buzzer
#define ENCODER_PIN_A 3
#define ENCODER_PIN_B 4
#define BUTTON_PIN 2
#define BUZZER_PIN 5
// Create an instance of the U8g2 library for a 3-wire SPI interface
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0); // Comment out for real hardware
// U8G2_UC1701_MINI12864_1_4W_HW_SPI u8g2(U8G2_R2, LCD_CS, LCD_A0, LCD_RST); // comment out for testing
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, NEOPIXEL_PIN, NEO_RGB + NEO_KHZ800);
bool sd = false;
void drawFile(u8g2_int_t x, u8g2_int_t y, const char *filename)
{
uint8_t w;
uint8_t h;
uint8_t b;
uint8_t mask;
uint8_t len;
u8g2_int_t xpos;
File myFile = SD.open(filename);
if (myFile)
{
w = myFile.read(); // read the dimension of the bitmap
h = myFile.read();
while (h > 0)
{ // handle all lines of the bitmap
xpos = x;
len = w; // len will contain the horizontal number of pixel
mask = 1;
b = myFile.read(); // load the first 8 pixel into "b"
/* The following code has an issue with some values for "w", see issue 2179 */
/*
while(len > 0) { // draw all pixel of one line
if ( b & mask ) { // check one pixel
u8g2.setDrawColor(1);
u8g2.drawPixel(xpos,y);
} else {
u8g2.setDrawColor(0);
u8g2.drawPixel(xpos,y);
}
xpos++; // calculate next x pos of the pixel
mask <<= 1; // update the mask
if ( mask == 0 )
{
mask = 1; // revert mask and ...
b = myFile.read(); // ... load the next 8 pixel values from the file
}
len--; // decrease the horizontal width (remaining pixel)
}
*/
/* new code */
for (;;)
{ // draw all pixel of one line
if (b & mask)
{ // check one pixel
u8g2.setDrawColor(1);
u8g2.drawPixel(xpos, y);
}
else
{
u8g2.setDrawColor(0);
u8g2.drawPixel(xpos, y);
}
xpos++; // calculate next x pos of the pixel
mask <<= 1; // update the mask
len--; // decrease the horizontal width (remaining pixel)
if (len == 0) // check if row is finished
break;
if (mask == 0)
{
mask = 1; // revert mask and ...
b = myFile.read(); // ... load the next 8 pixel values from the file
}
}
y++; // goto next line
h--; // decrease the number of remaining lines
}
myFile.close(); // all done, close the file
}
u8g2.setDrawColor(1); // restore color
}
bool sdcheck()
{
if (!SD.begin(7))
{
for (int i = 0; i < NUM_PIXELS; i++)
{
strip.setPixelColor(i, 0, 100, 0);
}
strip.show();
Serial.println("initialization failed!\n Reseat SD card and wait");
sd = false;
u8g2.firstPage();
do
{
u8g2.setCursor(0, 12);
u8g2.print(F("NO SD "));
u8g2.print(F("TRY AGAIN "));
} while (u8g2.nextPage());
return;
}
Serial.println("initialization done.");
for (int i = 0; i < NUM_PIXELS; i++)
{
strip.setPixelColor(i, 100, 100, 100);
}
strip.show();
sd = true;
return true;
}
void setup()
{
strip.begin();
for (int i = 0; i < NUM_PIXELS; i++)
{
strip.setPixelColor(i, 0, 0, 100);
}
strip.show();
// Open serial communications and wait for port to open:
Serial.begin(9600);
if (sd != true)
{
u8g2.setColorIndex(1); // set the color to white
u8g2.begin();
u8g2.clearDisplay();
u8g2.setBitmapMode(1);
u8g2.setContrast(255);
u8g2.setFont(u8g2_font_helvR10_tr);
u8g2.firstPage();
do
{
u8g2.setCursor(0, 12);
u8g2.print(F("NO SD "));
u8g2.print(F("TRY AGAIN "));
} while (u8g2.nextPage());
}
else
{
u8g2.setColorIndex(1); // set the color to white
u8g2.begin();
u8g2.clearDisplay();
u8g2.setBitmapMode(1);
u8g2.setContrast(255);
drawSprite();
u8g2.setFont(u8g2_font_helvR10_tr);
u8g2.firstPage();
do
{
u8g2.setCursor(0, 12);
u8g2.print(F("Read from SD:"));
} while (u8g2.nextPage());
}
}
int spriteX = 64; // The sprite's initial x-position
int direction = 1; // The direction the sprite is moving (1 for right, -1 for left)
int frameCounter = 0; // Add a frame counter
void loop()
{
// Move the sprite
spriteX += direction;
// If the sprite has reached the edge of the screen, change direction
if (spriteX <= 0 || spriteX >= 84)
{
direction *= -1;
}
if (!sd)
{
sdcheck();
delay(500);
}
else
{
// Increment the frame counter
frameCounter++;
drawSprite();
}
}
int framesPerSprite = 3; // Number of frames to show each sprite
void drawSprite()
{
sdcheck();
u8g2.firstPage();
do
{
u8g2.setCursor(0, 12);
// Choose the sprite based on the direction of movement
if (direction > 0)
{
if ((frameCounter / framesPerSprite) % 2 == 0)
{
drawFile(spriteX, 20, "agumonR.bin");
}
else
{
drawFile(spriteX, 20, "agumonR2.bin");
}
}
else
{
if ((frameCounter / framesPerSprite) % 2 == 0)
{
drawFile(spriteX, 20, "agumonL.bin");
}
else
{
drawFile(spriteX, 20, "agumonL2.bin");
}
}
u8g2.print(F("Read from SD:"));
} while (u8g2.nextPage());
}