// https://forum.arduino.cc/t/daft-punk-internal-hardware/1430058/3
// - Mount Matrix below eyesight
// - Horizontal slot, 120 degrees for vision
// - Hole below Matrix for walk/eat/drink view port
// - Internal OLED for HUD (time, temp, animation, warnings)
// - HC-SR04 for peripheral "vision"
void scrollText() { // https://wokwi.com/projects/423345032955134977
matrix.fillScreen(0); //Turn off all the LEDs
matrix.setCursor(scroll, 0); // start displaying Neopixels at the right edge
// matrix.print(sometext); // use with array of characters - no loop needed
for (int i = 0; i < textlength; i++) { // read all characters...
matrix.write(pgm_read_byte(sometext + i)); // ...from PROGMEM into buffer
}
if ( --scrollWidth < -scrolloff ) { // count from (size of matrix) to (negative)textlength
scrollWidth = matrix.width(); // re-start at the right
}
matrix.show(); // display the buffer
// delay(delayMS);
}
// color fade
// https://wokwi.com/projects/422068140806163457
// ALARM SETTING
byte alarmHour = 7, alarmMinute = 3; // 7:03 AM
// OLED is for information INSIDE the helmet... time, what's on the Matrix
#include <SSD1306Ascii.h> // https://github.com/greiman/SSD1306Ascii/blob/master/src/SSD1306Ascii.h
#include <SSD1306AsciiAvrI2c.h> // library does well with low memory
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiAvrI2c oled;
#include <Adafruit_NeoMatrix.h>
#define MATRIX_DATA 7 // Data pin
#define MATRIX_COLS 32 // 64 is too much for Uno/Nano
#define MATRIX_ROWS 8
#define MATRIX_LEDS MATRIX_ROWS * MATRIX_COLS
#define BRIGHTNESS 255
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(
MATRIX_COLS, MATRIX_ROWS, MATRIX_DATA,
NEO_MATRIX_TOP + // NEO_MATRIX_BOTTOM
NEO_MATRIX_LEFT + // NEO_MATRIX_RIGHT
NEO_MATRIX_ROWS + // NEO_MATRIX_COLUMNS
NEO_MATRIX_PROGRESSIVE, // NEO_MATRIX_ZIGZAG,
NEO_GRB + // NEO_RGB
NEO_KHZ800 // NEO_KHZ400
);
int scroll = matrix.width();
const char sometext[] PROGMEM = { // 5.33 characters per matrix
"OK" "yes" "no"
"-- --" "() ()" // blink
"===== "
" < < <" "< < < "
"<3 "
"hallo " "daft " "punk " "robot " "human "
"01100100 01100001 01100110 01110100 01110000 01110101 01101110 01101011" // daftpunk
};
/*
PIX ANIMATIONS:
pulse trace
blinking lights on sides
scanner
random red
fill/unfill
VU meter
pong
*/
const uint16_t color[] = {
matrix.Color( 0, 0, 0), // 0 blk
matrix.Color(255, 255, 255), // 1 wht
matrix.Color(255, 0, 0), // 2 red
matrix.Color(255, 128, 0), // 3 org
matrix.Color(255, 255, 0), // 4 yel
matrix.Color( 0, 255, 0), // 5 grn
matrix.Color( 0, 128, 255), // 6 sky
matrix.Color( 0, 255, 255), // 7 cyn
matrix.Color( 0, 0, 255), // 8 blu
matrix.Color(255, 255, 0), // 9 pur
};
#include <RTClib.h> // https://github.com/adafruit/RTClib
RTC_DS1307 rtc;
#define AM 0
#define PM 1
byte month, date;
#include <DHT.h> // https://github.com/adafruit/DHT-sensor-library
#define DHTTYPE DHT22
#define DHTPIN 9
DHT dht = DHT(DHTPIN, DHTTYPE);
// HC-SR04 ultrasonic transceiver
byte trigPin[] = {3, 7}; // right, left
byte echoPin[] = {2, 6}; // right, left
unsigned long timer, timeout = 1000; // event timers
void setup() {
Serial.begin(115200);
// serialtest();
for (int i = 0; i < 2; i++) { // HC-SR04
pinMode(trigPin[i], OUTPUT);
pinMode(echoPin[i], INPUT);
}
dht.begin();
rtc.begin();
oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
oled.setFont(Adafruit5x7);
oled.clear();
matrix.begin(); // Initialize the display object
matrix.setTextWrap(false);
matrix.setBrightness(BRIGHTNESS);
matrix.setTextColor(color[1]); // red
test();
}
void loop() {
// getDHT(); // every five seconds
// getRTC(); // every one second
// getSR04(); // four times per second
// displayOled(); // four times per second
// matrix(); // continuous
}
// =====================
// TEST FUNCTIONS
// =====================
void test() {
i2ctest(); // IIC/I2C - rtc and oled
sr04test();
dhttest();
rtctest();
oledtest();
matrixtest();
}
// =====================
// MATRIX FUNCTIONS
// =====================
void matrix() {
// https://wokwi.com/projects/423345032955134977
}
// =====================
// RTC FUNCTIONS
// =====================
void rtcMonDat() {
DateTime now = rtc.now();
oledPlaceData(1, 1, now.month());
oledPlaceData(1, 0, now.day());
}
// =====================
// DHT FUNCTIONS
// =====================
void dhtTempHumi() {
float humi = dht.readHumidity();
float temp = dht.readTemperature();
oledPlaceData(0, 1, temp); // temperature
oledPlaceData(0, 0, humi); // humidity
}
// =====================
// OLED DATA FUNCTIONS
// =====================
void oledAlarmSet(bool on) {
oled.set1X();
if (on) {
oled.setCursor(6, 1);
oled.setInvertMode(1);
oled.print(F(" "));
oled.setCursor(10, 1);
oled.print(F("ON"));
oled.setInvertMode(0);
} else {
oled.setCursor(6, 1);
oled.print(F("off"));
}
}
void oledAlarmAmPm(bool ampm) {
if (ampm) { // PM
oled.setCursor(113, 1);
oled.print(F("PM"));
} else { // AM
oled.setCursor(113, 0);
oled.print(F("AM"));
}
}
void oledAlarmTime(int hour, int minute) {
oled.set2X();
if (hour < 10) {
oled.setCursor(49, 0);
oled.print(hour);
} else {
oled.setCursor(37, 0);
oled.print(hour);
}
oled.setCursor(73, 0);
if (minute < 10) {
oled.print(F("0"));
oled.setCursor(85, 0);
oled.print(minute);
} else {
oled.print(minute);
}
}
void oledPlaceData (byte rtcdht, byte temphumi, byte val) {
byte y, tens, ones;
oled.set2X();
if (rtcdht) // 1 = RTC - month/date
y = 3; // oled 1X font row 3
else // 0 = DHT - temp/humi
y = 6; // oled 1X font row 6
if (temphumi) // 1 = month/temp
tens = 37, ones = 49; // month/temp columns
else // 0 = date/humi
tens = 99, ones = 111; // date/humi columns
oled.clearField(tens, y, 2); // clear col, row, characters
if (val < 10) {
oled.setCursor(ones, y);
oled.print(val);
} else {
// oled.setCursor(tens, y);
// oled.print(val / 10);
// oled.setCursor(ones, y);
// oled.print(val % 10);
oled.setCursor(tens, y);
oled.print(val);
}
}
// =====================
// OLED STATIC FUNCTIONS
// =====================
void oledOverlay() {
oled.set1X();
horizontalLine (2);
horizontalLine (5);
verticalLine(63);
oled.setCursor(0, 0);
oled.print(F("ALARM"));
oled.setCursor(69, 0);
oled.print(F("TEST"));
oled.setCursor(0, 3);
oled.print(F("MONTH"));
oled.setCursor(69, 3);
oled.print(F("DATE"));
oled.setCursor(0, 6);
oled.print(F("TEMP"));
oled.setCursor(69, 6);
oled.print(F("HUMI"));
}
void horizontalLine(int row) { // draw horizontal line at row (range 0 to 7)
oled.set1X(); // font size
oled.setCursor(0, row);
for (int i = 0; i < 21; i++) {
oled.print(F("-"));
}
}
void verticalLine(byte col) { // draw vertical line at col (range 0 to 127)
oled.set1X(); // font size
oled.setCursor(col, 3); oled.print(F("|"));
oled.setCursor(col, 4); oled.print(F("|"));
oled.setCursor(col, 6); oled.print(F("|"));
oled.setCursor(col, 7); oled.print(F("|"));
}
// ==============
// TEST FUNCTIONS
// ==============
void serialtest() {
Serial.println(F("Hello, World!"));
}
void sr04test() {
for (int j = 0; j < 5; j++) {
for (int i = 0; i < 2; i++) {
digitalWrite(trigPin[i], HIGH); // start measurement:
delayMicroseconds(10);
digitalWrite(trigPin[i], LOW);
int duration = pulseIn(echoPin[i], HIGH); // read result
if (i)
Serial.print(F("RIGHT"));
else
Serial.print(F(" LEFT"));
Serial.print(F(" distance "));
Serial.print(duration / 58);
Serial.println(F("cm"));
delay(1000);
}
}
}
void oledtest() {
oledOverlay();
oledPlaceData(1, 1, 12); // rtc, mon
oledPlaceData(1, 0, 34); // rtc, date
oledPlaceData(0, 1, 56); // dht, temp
oledPlaceData(0, 0, 78); // dht, humi
}
void oled1306AsciiTest() {
oled.set1X();
for (byte i = 0; i < 21; i++)
oled.print(i % 10);
oled.setCursor(0, 0);
for (byte i = 0; i < 8; i++) {
oled.print(i);
if (i > 0)
for (byte i = 1; i < 21; i++)
oled.print(F("."));
oled.println();
}
delay(2000);
oled.clear();
oled.set2X();
for (byte i = 0; i < 11; i++)
oled.print(i % 10);
oled.setCursor(0, 0);
for (byte i = 0; i < 4; i++) {
oled.print(i);
if (i > 0)
for (byte i = 1; i < 111; i++)
oled.print(F("."));
oled.println();
}
delay(2000);
oled.clear();
}
void dhttest() {
delay(2000);
float h = dht.readHumidity();
float t = dht.readTemperature();
Serial.print(F("H: "));
Serial.print(h);
Serial.print(F(" "));
Serial.print(F("T: "));
Serial.print(t);
Serial.println();
}
void rtctest() {
char dotw[7][5] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}; // not used
DateTime now = rtc.now();
Serial.print(dotw[now.dayOfTheWeek()]);
Serial.print(F(" "));
Serial.print(now.year());
Serial.print(F("."));
zeropad(now.month());
Serial.print(F("."));
zeropad(now.day());
Serial.print(F(" "));
zeropad(now.hour());
Serial.print(F(":"));
zeropad(now.minute());
Serial.print(F(":"));
zeropad(now.second());
}
void zeropad (int val) {
if (val < 10)
Serial.print(F("0"));
Serial.print(val);
}
void ledtest() {
for (int i = 0; i < MATRIX_LEDS; i++) { // drawPixel (int16_t x, int16_t y, uint16_t color)
matrix.drawPixel(i * (MATRIX_LEDS % MATRIX_COLS), i * (MATRIX_LEDS / MATRIX_COLS), color[1]);
matrix.show();
delay(10);
}
delay(2000);
matrix.clear();
matrix.show();
}
void i2ctest() { // read I2C bus addresses
Wire.begin();
int address, deviceFound, error;
Serial.print(F("I2C bus device addresses:"));
for (address = 0; address < 128; address++) {
Wire.beginTransmission(address);
if (!Wire.endTransmission()) {
deviceFound++;
Serial.print(F(" 0x"));
Serial.print(address, HEX);
} else if (error == 4) {
Serial.print(F(" Error at"));
Serial.print(F(" 0x"));
Serial.print(address, HEX);
}
}
if (!deviceFound)
Serial.println(F(" No I2C devices found."));
}Internal H.U.D.
Left
Peripheral
warning
Right
Peripheral
warning
Temperature
Time/Date
1000uF
E-Cap
R330
THOMAS DAFT PUNK DISPLAY