Magic Picture of Storm at Sea
This "magic picture" features an animated sailing boat caught in a squall, rocking and pitching as lightning flashes and thunder rumbles.
Components and supplies
High Accuracy Pi RTC (DS3231)
MicroSD Card Module, SPI interface, ESP8266 ESP32
EK1236 audio amplifier module (based on LM386 chip)
Dual H-Bridge motor drivers L298
Tilt sensor SW-520D
WS2812 Addressable LED Strip
5 mm LED: Red
Rocker Switch, Non Illuminated
Arduino Nano R3
DC 12V worm gear box reduction electric motor, 20 RPM
12V DC switching power supply, 5 A
High Brightness LED, White
Shift Register- Serial to Parallel
Male and female barrel jack for power, 2.5 mm
Speaker: 0.25W, 8 ohms
Pushbutton Switch, Momentary
Female/Female Jumper Wires
Tools and machines
Table saw or handheld saw
Jigsaw or coping saw
Hot glue gun (generic)
Project description
Code
script.h
c_cpp
C++ include file containing storm script data structures and defines
1/* Copyright 2021 Lincoln D. Stein <lincoln.stein@gmail.com> */ 2 3#ifndef SCRIPT_H 4#define SCRIPT_H 5 6#define DEBUG 0 7 8static const char stormfile[] PROGMEM = "storm4.wav"; // was storm3.wav 9static const char bell1[] PROGMEM = "bell1.wav"; 10static const char bell2[] PROGMEM = "bells2-4.wav"; 11static const char gull1[] PROGMEM = "gull1.wav"; 12static const char gull2[] PROGMEM = "gull2.wav"; 13static const char gull3[] PROGMEM = "gull3.wav"; 14 15PGM_P const Gulls[] PROGMEM = {gull1,gull2,gull3}; 16PGM_P const Bells[] PROGMEM = {bell1,bell2}; 17 18// These are the lighting states 19// They are indexes into the LightingEffect[] array 20#define DAYLIGHT 0 21#define TWILIGHT 1 22#define STORMLIGHT 2 23#define NIGHTLIGHT 3 24 25#define OFF 0 26#define ON 1 27 28#define FALSE 0 29#define TRUE 1 30 31#define DAYLIGHT_COLOR CRGB(150,140,70) 32// #define DAYLIGHT_COLOR CRGB(200,200,150) 33#define TWILIGHT_COLOR CRGB(40,30,90) 34#define STORMLIGHT_COLOR CRGB(15,10,30) 35#define LIGHTNING_COLOR CRGB(250,250,250) 36#define NIGHTLIGHT_COLOR CRGB(0,0,10) 37 38// the gradient count defines the number of light transition steps between one 39// lighting effect and the next. The higher the count, the smoother the transition 40// will be 41#define GRADIENT_COUNT 40 42#define FADE_DURATION 3000 43 44// one hour between storms = 60 x 60 x 1000 45#define TIME_BETWEEN_STORMS 3600000 46// 10 minutes between storms 47// #define TIME_BETWEEN_STORMS 600000 48// after poweron, storm will start in 20s 49#define INITIAL_STORM_PAUSE 20000 50 51// gulls randomly call every 10 minutes, roughly 52#define AVERAGE_GULL_INTERVAL 600000 53// 3 minutes for testing 54//#define AVERAGE_GULL_INTERVAL 180000 55#define GULL_INTERVAL_RANGE AVERAGE_GULL_INTERVAL/2 56 57// Using the 24h clock, these define the intervals when the storm and other effects are muted 58// (i.e. bedtime!) 59#define SLEEP_START 22 60#define SLEEP_END 07 61 62// Check the RTC for sleep time every minute 63#define CHECK_RTC_INTERVAL 60000 64// Frequency of mast blink 65#define MAST_BLINK_INTERVAL 1000 66 67// The debounce delay for the tilt sensor 68#define DEBOUNCE_DELAY 10 69 70// prototype for the stop_when_horizontal() function 71void stop_when_horizontal (L298N m, int timeout = 25000); 72 73enum Lightning : byte { 74 left = 0, 75 right = 1, 76 center = 2 77}; 78 79enum Action : byte { 80 lightning, 81 mast_light_transition, 82 motor_speed, 83 light_transition, 84 ending, 85 stormsound 86}; 87 88struct Script { 89 long int millis; 90 Action action; 91 byte value; 92}; 93 94// note, times must be sorted in ascending order 95Script StormScript[] = { 96 {500, stormsound, 0}, 97 {5000, light_transition, TWILIGHT}, 98 {5000, lightning, left}, 99 {8000, mast_light_transition, ON}, 100 {9000, lightning, left}, 101 {15000, motor_speed, 60}, 102 {17250, lightning, left}, 103 {20000, light_transition, STORMLIGHT}, 104 {30105, lightning, left}, 105 {30105, lightning, center}, 106 {32742, motor_speed, 80}, 107 {42000, lightning, center}, 108 {43000, lightning, right}, 109 {46000, lightning, center}, 110 {61211, lightning, left}, 111 {61211, lightning, center}, 112 {61211, lightning, right}, 113 {61211, motor_speed, 120}, 114 {70539, lightning, center}, 115 {70539, lightning, right}, 116 {61211, motor_speed, 80}, 117 {80000, light_transition, TWILIGHT}, 118 {80000, motor_speed, 60}, 119 {90000, motor_speed, 0}, 120 {97238, lightning, right}, 121 {99545, light_transition, DAYLIGHT}, 122 {99545, mast_light_transition, OFF}, 123 {120000, ending, 0} 124}; 125 126CRGB LightingEffects[] = {DAYLIGHT_COLOR, TWILIGHT_COLOR, STORMLIGHT_COLOR, NIGHTLIGHT_COLOR}; 127 128#endif // SCRIPT_H 129
ship_pins.h
c_cpp
This is the include file that defines which Arduino pins are connected where
1/* Copyright 2021 Lincoln D. Stein <lincoln.stein@gmail.com> */ 2 3#ifndef 4 PINS_H 5#define PINS_H 6 7// location of the pin connected to the SD card 8#define 9 SD_Pin 10 10 11// Pin the tilt sensor is attached to 12#define TILT_PIN 13 A0 14 15// location of the PWM pin connected to the speaker amp 16#define 17 Speaker_Pin 9 18 19// Definitions for connections to the 74HC595 shift register 20 IC 21#define latchPin 5 22#define clockPin 6 23#define dataPin 4 24 25// 26 L298N motor pins 27#define M_EN 3 28#define M_IN1 7 29#define M_IN2 30 8 31 32// bit positions for independent LEDs driven by 74HCT595 33#define 34 MAST_LED 1 35#define LEFT_LED 2 36#define RIGHT_LED 3 37 38// definitions 39 for ARGB LED light strip 40#define LED_STRIP_PIN 2 41#define NUM_LEDS 29 42 43 44 45#endif 46
script.h
c_cpp
C++ include file containing storm script data structures and defines
1/* Copyright 2021 Lincoln D. Stein <lincoln.stein@gmail.com> */ 2 3#ifndef SCRIPT_H 4#define SCRIPT_H 5 6#define DEBUG 0 7 8static const char stormfile[] PROGMEM = "storm4.wav"; // was storm3.wav 9static const char bell1[] PROGMEM = "bell1.wav"; 10static const char bell2[] PROGMEM = "bells2-4.wav"; 11static const char gull1[] PROGMEM = "gull1.wav"; 12static const char gull2[] PROGMEM = "gull2.wav"; 13static const char gull3[] PROGMEM = "gull3.wav"; 14 15PGM_P const Gulls[] PROGMEM = {gull1,gull2,gull3}; 16PGM_P const Bells[] PROGMEM = {bell1,bell2}; 17 18// These are the lighting states 19// They are indexes into the LightingEffect[] array 20#define DAYLIGHT 0 21#define TWILIGHT 1 22#define STORMLIGHT 2 23#define NIGHTLIGHT 3 24 25#define OFF 0 26#define ON 1 27 28#define FALSE 0 29#define TRUE 1 30 31#define DAYLIGHT_COLOR CRGB(150,140,70) 32// #define DAYLIGHT_COLOR CRGB(200,200,150) 33#define TWILIGHT_COLOR CRGB(40,30,90) 34#define STORMLIGHT_COLOR CRGB(15,10,30) 35#define LIGHTNING_COLOR CRGB(250,250,250) 36#define NIGHTLIGHT_COLOR CRGB(0,0,10) 37 38// the gradient count defines the number of light transition steps between one 39// lighting effect and the next. The higher the count, the smoother the transition 40// will be 41#define GRADIENT_COUNT 40 42#define FADE_DURATION 3000 43 44// one hour between storms = 60 x 60 x 1000 45#define TIME_BETWEEN_STORMS 3600000 46// 10 minutes between storms 47// #define TIME_BETWEEN_STORMS 600000 48// after poweron, storm will start in 20s 49#define INITIAL_STORM_PAUSE 20000 50 51// gulls randomly call every 10 minutes, roughly 52#define AVERAGE_GULL_INTERVAL 600000 53// 3 minutes for testing 54//#define AVERAGE_GULL_INTERVAL 180000 55#define GULL_INTERVAL_RANGE AVERAGE_GULL_INTERVAL/2 56 57// Using the 24h clock, these define the intervals when the storm and other effects are muted 58// (i.e. bedtime!) 59#define SLEEP_START 22 60#define SLEEP_END 07 61 62// Check the RTC for sleep time every minute 63#define CHECK_RTC_INTERVAL 60000 64// Frequency of mast blink 65#define MAST_BLINK_INTERVAL 1000 66 67// The debounce delay for the tilt sensor 68#define DEBOUNCE_DELAY 10 69 70// prototype for the stop_when_horizontal() function 71void stop_when_horizontal (L298N m, int timeout = 25000); 72 73enum Lightning : byte { 74 left = 0, 75 right = 1, 76 center = 2 77}; 78 79enum Action : byte { 80 lightning, 81 mast_light_transition, 82 motor_speed, 83 light_transition, 84 ending, 85 stormsound 86}; 87 88struct Script { 89 long int millis; 90 Action action; 91 byte value; 92}; 93 94// note, times must be sorted in ascending order 95Script StormScript[] = { 96 {500, stormsound, 0}, 97 {5000, light_transition, TWILIGHT}, 98 {5000, lightning, left}, 99 {8000, mast_light_transition, ON}, 100 {9000, lightning, left}, 101 {15000, motor_speed, 60}, 102 {17250, lightning, left}, 103 {20000, light_transition, STORMLIGHT}, 104 {30105, lightning, left}, 105 {30105, lightning, center}, 106 {32742, motor_speed, 80}, 107 {42000, lightning, center}, 108 {43000, lightning, right}, 109 {46000, lightning, center}, 110 {61211, lightning, left}, 111 {61211, lightning, center}, 112 {61211, lightning, right}, 113 {61211, motor_speed, 120}, 114 {70539, lightning, center}, 115 {70539, lightning, right}, 116 {61211, motor_speed, 80}, 117 {80000, light_transition, TWILIGHT}, 118 {80000, motor_speed, 60}, 119 {90000, motor_speed, 0}, 120 {97238, lightning, right}, 121 {99545, light_transition, DAYLIGHT}, 122 {99545, mast_light_transition, OFF}, 123 {120000, ending, 0} 124}; 125 126CRGB LightingEffects[] = {DAYLIGHT_COLOR, TWILIGHT_COLOR, STORMLIGHT_COLOR, NIGHTLIGHT_COLOR}; 127 128#endif // SCRIPT_H 129
StormScript-v2.ino
c_cpp
This is the main loop
1/* Copyright 2021 Lincoln D. Stein <lincoln.stein@gmail.com> */ 2 3#include <pcmConfig.h> 4#include <TMRpcm.h> 5#include <pcmRF.h> 6#include <FastLED.h> 7 8#include <SPI.h> 9#include <SD.h> 10#include <L298N.h> 11 12// Date and time functions using a DS3231 RTC connected via I2C and Wire lib 13#include <RTClib.h> 14 15#include "script.h" 16#include "ship_pins.h" 17 18// this controls the granularity of lighting transitions - higher is more gradual 19#define GRADIENT_SIZE 20 20 21// Create one motor instance 22L298N motor(M_EN, M_IN1, M_IN2); 23 24// real time clock 25RTC_DS3231 Clock; 26 27// uncomment this to set the clock at compile time 28// #define SET_CLOCK 1 29 30// This is an array of leds. One item for each led in your strip. 31CRGB argb[NUM_LEDS]; 32 33// Audio 34TMRpcm audio; 35 36// state variables 37byte Leds = 0; 38byte Sleeping = 0; 39byte MastLightState = 0; 40unsigned long int StormTime = 0; 41unsigned long int GullTime = 0; 42unsigned long int RTCTime = 0; 43unsigned long int MastBlinkTime = 0; 44 45// tilt sensor state 46byte last_button_state = LOW; 47byte ButtonState = LOW; 48unsigned long int last_debounce_time = 0; 49 50void setup() { 51 char wavFile[15]; 52 Wire.begin(); 53 54 FastLED.addLeds<WS2812B, LED_STRIP_PIN, GRB>(argb, NUM_LEDS); 55 56 pinMode(SD_Pin, OUTPUT); 57 digitalWrite(SD_Pin, HIGH); 58 59 pinMode(latchPin, OUTPUT); 60 pinMode(dataPin, OUTPUT); 61 pinMode(clockPin, OUTPUT); 62 63 // use internal button pullup for tilt sensor 64 pinMode(TILT_PIN, INPUT_PULLUP); 65 66 Serial.begin(9600); 67 68 if (!SD.begin(SD_Pin)) { 69 Serial.println(F("SD fail")); 70 Serial.flush(); 71 abort(); 72 } 73 74 if (!Clock.begin()) { 75 Serial.println(F("Couldn't find RTC module")); 76 Serial.flush(); 77 abort(); 78 } 79 80 if (Clock.lostPower()) { 81 Serial.println(F("Clock lost power. Resetting time")); 82 Clock.adjust(DateTime(F(__DATE__), F(__TIME__))); 83 } 84#ifdef SET_CLOCK 85 Clock.adjust(DateTime(F(__DATE__), F(__TIME__))); 86#endif 87 88 Serial.println(); 89 90 audio.speakerPin = Speaker_Pin; 91 audio.quality(1); 92 audio.loop(0); 93 audio.setVolume(3); 94 audio.play(strcpy_P(wavFile, (char*)pgm_read_word(&(Bells[1])))); 95 96 // initial lighting 97 Leds = 0; 98 updateShiftRegister(); 99 change_lighting(DAYLIGHT); 100 101 StormTime = INITIAL_STORM_PAUSE - TIME_BETWEEN_STORMS; // this forces the storm to start 30 seconds after turning on 102 GullTime = millis(); 103 104#if DEBUG 105 Serial.print(F("StormTime = ")); 106 Serial.print(StormTime); 107 Serial.print(F(" millis() = ")); 108 Serial.println(millis()); 109#endif 110 111 randomSeed(analogRead(A1)); // analogRead on unconnected pin to give a random seed 112 113} 114 115void loop() { 116 char wavFile[15]; 117 118 byte sleeping = is_sleeping(); 119 120 if (millis() - MastBlinkTime > MAST_BLINK_INTERVAL) { 121 MastLightState = !MastLightState; 122 set_mast_light(MastLightState); 123 MastBlinkTime = millis(); 124 } 125 126 if (!sleeping) { 127 if (millis() - StormTime > TIME_BETWEEN_STORMS) { 128#if DEBUG 129 Serial.println(F("Storm starting")); 130#endif 131 do_storm(); 132 StormTime = millis(); 133 } 134 135 if (millis() - GullTime > random(AVERAGE_GULL_INTERVAL - GULL_INTERVAL_RANGE, AVERAGE_GULL_INTERVAL + GULL_INTERVAL_RANGE)) { 136#if DEBUG 137 Serial.println(F("Gulls squawking")); 138#endif 139 audio.setVolume(4); 140 audio.play(strcpy_P(wavFile, 141 (char*)pgm_read_word(&(Gulls[random(0, sizeof(Gulls) / sizeof(Gulls[0]))] 142 )))); 143 GullTime = millis(); 144 } 145 } 146} 147 148void do_storm() { 149 char wavFile[15]; 150 byte EventCounter = 0; 151 byte done = 0; 152 long int now = millis(); 153 154 while (!done) { 155 long int time_elapsed = millis() - now; 156 byte tilt = tilt_changed(); // have to keep monitoring this in order to update ButtonState 157#if DEBUG 158 if (tilt) { 159 Serial.print(F("Tilt state changed to ")); 160 Serial.println(ButtonState, DEC); 161 } 162#endif 163 164 if (StormScript[EventCounter].millis <= time_elapsed) { // time to do an event! 165#if DEBUG 166 Serial.print(F("** Event ")); 167 Serial.print(EventCounter); 168 Serial.println(F(" **")); 169 Serial.print(F("Relative Time = ")); 170 Serial.print(time_elapsed); 171 Serial.print(F("; Script time = ")); 172 Serial.println(StormScript[EventCounter].millis); 173 Serial.print(F("Action = ")); 174 Serial.println(StormScript[EventCounter].action); 175 Serial.print(F("Value = ")); 176 Serial.println(StormScript[EventCounter].value, DEC); 177#endif 178 179 int value = StormScript[EventCounter].value; 180 switch (StormScript[EventCounter].action) { 181 182 case stormsound : 183 while (audio.isPlaying()) { 184 delay(10); 185 } 186 audio.setVolume(5); 187 audio.play(strcpy_P(wavFile, stormfile)); 188 break; 189 190 case light_transition : 191 change_lighting(value); 192 break; 193 194 case lightning : 195 flash_lightning((Lightning)value); 196 break; 197 198 case motor_speed : 199 set_motor_speed(value); 200 break; 201 202 case mast_light_transition : 203 set_mast_light(value); 204 break; 205 206 case ending : 207 while (audio.isPlaying()) { 208 delay(10); 209 } 210 done++; 211 break; 212 } 213 EventCounter++; 214 } 215 } 216} 217 218void set_motor_speed (int value) { 219 if (value == 0) { 220 // motor.stop(); 221 stop_when_horizontal(motor); 222 } else { 223 motor.setSpeed(value); 224 motor.forward(); 225 } 226} 227 228void change_lighting (int v) { 229 byte arrSize = sizeof(LightingEffects) / sizeof(LightingEffects[0]); 230 if (v >= arrSize) { 231#if DEBUG 232 Serial.print(F("BUG: change_lighting called with value of ")); 233 Serial.print(v, DEC); 234 Serial.print(F(". But end of array is at ")); 235 Serial.println(arrSize - 1, DEC); 236#endif 237 return; 238 } 239 CRGB color = LightingEffects[v]; 240 fade_to_color(color); 241} 242 243void flash_lightning (Lightning v) { 244 int led, rgb; 245 int previous_color = argb[0]; 246 247 if (v == center) { 248 big_flash(); 249 return; 250 } 251 252 if (v == left) { 253 led = LEFT_LED; 254 rgb = 0; 255 } else if (v == right) { 256 led = RIGHT_LED; 257 rgb = NUM_LEDS - 1; 258 } else { 259 return; 260 } 261 262 for (uint8_t i = 0; i < 10; i++) { 263 bitSet(Leds, led); 264 updateShiftRegister(); 265 argb[rgb] = LIGHTNING_COLOR; 266 FastLED.show(); 267 268 delay(random(0, 10)); 269 270 bitClear(Leds, led); 271 updateShiftRegister(); 272 argb[rgb] = previous_color; 273 FastLED.show(); 274 275 delay(random(0, 50)); 276 } 277} 278 279void big_flash() { 280 CRGB current = argb[1]; 281 for (uint8_t i = 0; i < 10; i++) { 282 fill_solid(argb, NUM_LEDS, LIGHTNING_COLOR); 283 FastLED.show(); 284 delay(random(0, 10)); 285 fill_solid(argb, NUM_LEDS, current); 286 FastLED.show(); 287 delay(random(0, 50)); 288 } 289} 290 291 292void set_mast_light(int on) { 293 if (on) { 294 bitSet(Leds, MAST_LED); 295 } else { 296 bitClear(Leds, MAST_LED); 297 } 298 updateShiftRegister(); 299} 300 301void updateShiftRegister() 302{ 303 digitalWrite(latchPin, LOW); 304 shiftOut(dataPin, clockPin, MSBFIRST, Leds); 305 digitalWrite(latchPin, HIGH); 306} 307 308void fade_to_color(CRGB destination) { 309 CRGB CurrentSky = argb[1]; 310 CRGB gradient[GRADIENT_COUNT]; 311 int pause_time = FADE_DURATION / GRADIENT_COUNT; 312 fill_gradient_RGB(gradient, 0, CurrentSky, GRADIENT_COUNT - 1, destination); 313 for (int i = 0; i < GRADIENT_COUNT; i++) { 314 fill_solid(argb, NUM_LEDS, gradient[i]); 315 FastLED.show(); 316 delay(pause_time); 317 } 318 CurrentSky = destination; 319} 320 321// check for bedtime 322byte is_sleeping() { 323 char wavFile[15]; 324 325 if ((RTCTime == 0) || (millis() - RTCTime > CHECK_RTC_INTERVAL)) { 326 RTCTime = millis(); 327 byte hr = get_hour(); 328#if DEBUG 329 Serial.print(F("Checking clock...hr=")); 330 Serial.println(hr, DEC); 331#endif 332 333 if ((hr >= SLEEP_START) || (hr <= SLEEP_END)) { 334#if DEBUG 335 Serial.println(F("In sleep range")); 336#endif 337 if (!Sleeping) { 338#if DEBUG 339 Serial.println(F("It's late. Nighty night!")); 340#endif 341 audio.play(strcpy_P(wavFile, (char*)pgm_read_word(&(Bells[0])))); 342 change_lighting(NIGHTLIGHT); 343 Sleeping = TRUE; 344 } 345 } 346 347 else { // wake up! 348 if (Sleeping) { 349#if DEBUG 350 Serial.println(F("Good morning! Waking up")); 351#endif 352 change_lighting(DAYLIGHT); 353 audio.play(strcpy_P(wavFile, (char*)pgm_read_word(&(Bells[1])))); 354 Sleeping = FALSE; 355 StormTime = millis(); 356 GullTime = millis(); 357 } 358 } 359 } 360 361 return Sleeping; 362} 363 364/* method for calculating DST offset copied from here: https://forum.arduino.cc/t/ds3231-rtc-daylight-savings-time/410699/4 */ 365int get_hour () { 366 DateTime now = Clock.now(); 367 boolean DST = 0; 368 369 // ********************* Calculate offset for Sunday ********************* 370 byte y = now.year(); // DS3231 uses two digit year (required here) 371 byte x = (y + y / 4 + 2) % 7; // remainder will identify which day of month DST starts on 372 373 byte hour = now.hour(); 374 byte month = now.month(); 375 byte dom = now.day(); 376 377 // LS: this code is inelegant, but it purportedly works, so I'm not going to mess with it 378 // is Sunday by subtracting x from the one 379 // or two week window. First two weeks for March 380 // and first week for November 381 // *********** Test DST: BEGINS on 2nd Sunday of March @ 2:00 AM ********* 382 if (month == 3 && dom == (14 - x) && hour >= 2) { 383 DST = 1; 384 } 385 if ((month == 3 && dom > (14 - x)) || month > 3) { 386 DST = 1; 387 } 388 // ************* Test DST: ENDS on 1st Sunday of Nov @ 2:00 AM ************ 389 if (month == 11 && dom == (7 - x) && hour >= 2) { 390 DST = 0; // daylight savings time is FALSE (Standard time) 391 } 392 if ((month == 11 && dom > (7 - x)) || month > 11 || month < 3) { 393 DST = 0; 394 } 395 396 if (DST) // Test DST and add one hour if = 1 (TRUE) 397 return hour + 1; 398 else 399 return hour; 400} 401 402/* Tilt sensor routines */ 403 404void stop_when_horizontal (L298N m, int timeout) { 405 unsigned long timestart = millis(); 406 boolean timedout = false; 407 408#if DEBUG 409 Serial.println(F("Waiting for horizontal before stopping")); 410#endif 411 while (!timedout) { 412 if (tilt_changed()) { 413 if (ButtonState == LOW) 414 break; 415 } 416 timedout = millis() - timestart > timeout; 417 } 418 if (timedout) 419 Serial.println(F("Timed out waiting for horizontal")); 420 else 421 Serial.println(F("Stopped normally")); 422 m.stop(); 423} 424 425boolean tilt_changed() { 426 byte reading = digitalRead(TILT_PIN); 427 boolean changed = false; 428 429 if (reading != last_button_state) { 430 last_debounce_time = millis(); 431 } 432 433 if (millis() - last_debounce_time > DEBOUNCE_DELAY) { 434 if (reading != ButtonState) { 435 changed = true; 436 ButtonState = reading; 437 } 438 } 439 last_button_state = reading; 440 return changed; 441} 442
ship_pins.h
c_cpp
This is the include file that defines which Arduino pins are connected where
1/* Copyright 2021 Lincoln D. Stein <lincoln.stein@gmail.com> */ 2 3#ifndef PINS_H 4#define PINS_H 5 6// location of the pin connected to the SD card 7#define SD_Pin 10 8 9// Pin the tilt sensor is attached to 10#define TILT_PIN A0 11 12// location of the PWM pin connected to the speaker amp 13#define Speaker_Pin 9 14 15// Definitions for connections to the 74HC595 shift register IC 16#define latchPin 5 17#define clockPin 6 18#define dataPin 4 19 20// L298N motor pins 21#define M_EN 3 22#define M_IN1 7 23#define M_IN2 8 24 25// bit positions for independent LEDs driven by 74HCT595 26#define MAST_LED 1 27#define LEFT_LED 2 28#define RIGHT_LED 3 29 30// definitions for ARGB LED light strip 31#define LED_STRIP_PIN 2 32#define NUM_LEDS 29 33 34 35 36#endif 37
Downloadable files
Shadowbox circuit diagram - storm at sea
This is a schematic of the shadowbox wiring.
Shadowbox circuit diagram - storm at sea
Shadowbox circuit diagram - storm at sea
This is a schematic of the shadowbox wiring.
Shadowbox circuit diagram - storm at sea
Comments
Only logged in users can leave comments