aboutsummaryrefslogtreecommitdiff
path: root/software
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2021-11-26 22:19:07 +0100
committerlonkaars <loek@pipeframe.xyz>2021-11-26 22:19:07 +0100
commite6fc8e8af4ff8bd2709eb4485ba1ba9beadd27a5 (patch)
tree9a70bd47b011304b270531a4d0f1e67cc622d8a4 /software
parentf9335ba20b0e950e9881749e9bc3006eacefc305 (diff)
first animation done
- added variable length animations - added readme to software subdirectory - implemented first animation
Diffstat (limited to 'software')
-rw-r--r--software/animation.h3
-rw-r--r--software/animation.ino6
-rw-r--r--software/effects.h8
-rw-r--r--software/effects.ino52
-rw-r--r--software/readme.md47
-rw-r--r--software/scan.ino4
-rw-r--r--software/software.ino21
7 files changed, 123 insertions, 18 deletions
diff --git a/software/animation.h b/software/animation.h
index feab14d..3e0d3a7 100644
--- a/software/animation.h
+++ b/software/animation.h
@@ -4,3 +4,6 @@
/** @brief round time to nearest frame */
unsigned long clamp_time(unsigned long unclamped_time);
+
+/** @brief 'zigzag' value between 0 and `size - 1`, like modulo (`%`) operator */
+unsigned int zigzag(unsigned int size, int index);
diff --git a/software/animation.ino b/software/animation.ino
index 547caaa..4c4976e 100644
--- a/software/animation.ino
+++ b/software/animation.ino
@@ -3,3 +3,9 @@
unsigned long clamp_time(unsigned long unclamped_time) {
return unclamped_time / frame_time_millis * frame_time_millis;
}
+
+unsigned int zigzag(unsigned int size, int index) {
+ unsigned int zigzag_size = 2 * size - 2;
+ unsigned int mod = index % zigzag_size;
+ return mod < size - 1 ? mod : zigzag_size - mod;
+}
diff --git a/software/effects.h b/software/effects.h
index cef66f2..9f7ec39 100644
--- a/software/effects.h
+++ b/software/effects.h
@@ -1,8 +1,9 @@
#pragma once
// slideshow config
-#define SLIDESHOW_SIZE (int) 2
-#define SLIDESHOW_DURATION (int) 5e3
+#define SLIDESHOW_SIZE (int) 3
+// uncomment for fixed slide length
+// #define SLIDESHOW_DURATION (int) 5e3
// definition of done sprint 3
void fx_roundabout (unsigned long relative_time, bool (*leds)[64]);
@@ -11,3 +12,6 @@ void fx_rainfall (unsigned long relative_time, bool (*leds)[64]);
// evil function pointer array
extern void ( * slideshow_effects [SLIDESHOW_SIZE] )( unsigned long relative_time, bool (*leds)[64] );
+#ifndef SLIDESHOW_DURATION
+extern unsigned long slideshow_lengths[SLIDESHOW_SIZE];
+#endif
diff --git a/software/effects.ino b/software/effects.ino
index c27179f..0768fb8 100644
--- a/software/effects.ino
+++ b/software/effects.ino
@@ -1,23 +1,32 @@
-#include "software.h"
+#include "const.h"
#include "effects.h"
+#include "animation.h"
+#define FX_LEN_ROUNDABOUT 5e3
void fx_roundabout (unsigned long relative_time, bool (*leds)[64]) {
- unsigned long segment_time = SLIDESHOW_DURATION / 64;
- #ifdef DEBUG
- Serial.print(segment_time, DEC);
- Serial.print(" ");
- Serial.print((relative_time / segment_time) % 64, DEC);
- Serial.print("\n\r");
- #endif
- memset(led_state, 1, sizeof(led_state));
- led_state[(relative_time / segment_time) % 64] = 0;
+ memset(leds, 0, sizeof(leds));
+ unsigned long tick = relative_time / 300;
+ unsigned int roundabout_coordinates[12] = {
+ 0x0, 0x1, 0x2, 0x3, 0x7, 0xb,
+ 0xf, 0xe, 0xd, 0xc, 0x8, 0x4
+ };
+
+ for(int trail = 0; trail < 4; trail++) {
+ unsigned int xy_coords = roundabout_coordinates[(tick + trail) % 12];
+ for(int z = 0; z < 4; z++) *leds[led_map[xy_coords + z * 0xf0]] = 1;
+ }
return;
}
+#define FX_LEN_WIPEXYZ 6e3
void fx_wipexyz (unsigned long relative_time, bool (*leds)[64]) {
- bool flip_state = (relative_time % 1000) > 500;
- for(int i = 0; i < 64; i++) led_state[i] = i % 2 == flip_state;
+
+ return;
+}
+
+#define FX_LEN_RAINFALL 7e3
+void fx_rainfall (unsigned long relative_time, bool (*leds)[64]) {
return;
}
@@ -25,5 +34,22 @@ void fx_wipexyz (unsigned long relative_time, bool (*leds)[64]) {
void ( * slideshow_effects [SLIDESHOW_SIZE] )( unsigned long relative_time, bool (*leds)[64] ) = {
fx_roundabout,
fx_wipexyz,
-// fx_rainfall
+ fx_rainfall
+};
+
+#ifndef SLIDESHOW_DURATION
+unsigned long slideshow_lengths[SLIDESHOW_SIZE] = {
+ FX_LEN_ROUNDABOUT,
+ FX_LEN_WIPEXYZ,
+ FX_LEN_RAINFALL
};
+#endif
+
+/* void test_leds_inorder (unsigned long relative_time, bool (*leds)[64]) {
+ unsigned long segment_time = SLIDESHOW_DURATION / 64;
+ memset(leds, 0, sizeof(leds));
+ *leds[(relative_time / segment_time) % 64] = 1;
+
+ return;
+} */
+
diff --git a/software/readme.md b/software/readme.md
new file mode 100644
index 0000000..dbe77d2
--- /dev/null
+++ b/software/readme.md
@@ -0,0 +1,47 @@
+# software readme
+
+onze ledcube is iets anders dan de gemiddelde ledcube. onze leds zijn
+aangesloten als een 8x8 matrix waarbij alle anodes in rijen, en alle cathodes
+in kolommen zijn verbonden. hierdoor gebruikt onze ledcube maar acht
+weerstanden inplaats van zestien, en geen transistoren of mosfets. ook worden
+maar drie uitgangen van de arduino gebruikt voor de seriële ingang, seriële
+klok, en de latch klok van het shiftregister.
+
+de software is als gevolg hierdoor ook anders ingericht. de atmega328p heeft
+ingebouwde pwm timers, die je zou kunnen gebruiken om snel door de vier lagen
+van de ledcube heen te schakelen. omdat deze timers los van je code draaien kun
+je de ingebouwde `delay()` gewoon gebruiken om de animaties makkelijker te
+implementeren, maar dit werkt alleen wanneer je transistoren gebruikt en ze
+direct op pwm uitgangen aansluit.
+
+daarom gebruikt onze software geen `delay()` of andere 'blokkerende' functies,
+maar timers. dit zorgt ervoor dat de ingebouwde `loop()` functie van de arduino
+vaak genoeg draait om het te laten lijken alsof alle led's van de ledcube
+tegelijkertijd aan zijn.
+
+het project is opgesplitst in losse bestanden om overzichtelijkheid te
+behouden. alle documentatie bevindt zich in de header (.h) bestanden, is in het
+engels, en is in doxygen formaat. hier is een beknopte beschrijving van de
+bestanden:
+
+```
+.
+├── animation.h --
+├── animation.ino helpfuncties voor animaties
+├── consts.h algemene constantes
+├── effects.h bevat ook opties voor de diavoorstelling van animaties
+├── effects.ino de animaties die weergeven worden
+├── readme.md dit bestand
+├── scan.h --
+├── scan.ino functies omtrent het schakelen van de rijen
+├── shift.h --
+├── shift.ino functies die het shiftregister besturen
+├── software.h --
+├── software.ino hoofdbestand/ingangspunt
+├── util.h --
+└── util.ino gereedschapsfuncties
+```
+
+ik (loek) heb de software voor het laatst op vrijdag getest, dus ik weet niet
+zeker of mijn code voor de animaties helemaal werkt, maar ik ga deze maandag
+testen en bijwerken. dit is dus nog geen afgewerkte code.
diff --git a/software/scan.ino b/software/scan.ino
index 9feba79..cc72e21 100644
--- a/software/scan.ino
+++ b/software/scan.ino
@@ -18,8 +18,8 @@ unsigned char get_state_row(unsigned char row, unsigned char direction) {
}
void scan() {
- shift_state[0] = (1 << scan_index);
- shift_state[1] = get_state_row(scan_index, scan_direction);
+ shift_state[0] = 0x00 ^ (1 << scan_index);
+ shift_state[1] = 0xff ^ get_state_row(scan_index, scan_direction);
update_shift_state();
diff --git a/software/software.ino b/software/software.ino
index 5bf0ac3..ca2b7c0 100644
--- a/software/software.ino
+++ b/software/software.ino
@@ -6,6 +6,9 @@
unsigned long frame_time_millis;
bool led_state[64];
bool scan_enable = true;
+#ifndef SLIDESHOW_DURATION
+unsigned long slideshow_length_total;
+#endif
void setup() {
pinMode(PINOUT_SER, OUTPUT);
@@ -16,15 +19,31 @@ void setup() {
Serial.begin(CONFIG_SERIAL_BAUD);
#endif
+ #ifndef SLIDESHOW_DURATION
+ for(int i = 0; i < SLIDESHOW_SIZE; i++)
+ slideshow_length_total += slideshow_lengths[i];
+ #endif
+
frame_time_millis = 1000 / CONFIG_FRAMERATE * CONFIG_FRAMERATE;
}
void loop() {
unsigned long current_time = millis();
+ #ifdef SLIDESHOW_DURATION
unsigned long slide_time = current_time % SLIDESHOW_DURATION;
unsigned int slide_index = (current_time / SLIDESHOW_DURATION) % SLIDESHOW_SIZE;
-
+ #else
+ unsigned long slide_time = current_time % slideshow_length_total;
+ unsigned int slide_index = 0;
+ unsigned long slide_sum = 0;
+ for(int i = 0; i < SLIDESHOW_SIZE; i++) {
+ slide_sum += slideshow_lengths[i];
+ if (slide_time >= slide_sum) continue;
+ slide_index = i;
+ break;
+ }
+ #endif
slideshow_effects[slide_index](slide_time, &led_state);
if (scan_enable) scan();