From e6fc8e8af4ff8bd2709eb4485ba1ba9beadd27a5 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Fri, 26 Nov 2021 22:19:07 +0100 Subject: first animation done - added variable length animations - added readme to software subdirectory - implemented first animation --- software/animation.h | 3 +++ software/animation.ino | 6 ++++++ software/effects.h | 8 ++++++-- software/effects.ino | 52 +++++++++++++++++++++++++++++++++++++------------- software/readme.md | 47 +++++++++++++++++++++++++++++++++++++++++++++ software/scan.ino | 4 ++-- software/software.ino | 21 +++++++++++++++++++- 7 files changed, 123 insertions(+), 18 deletions(-) create mode 100644 software/readme.md (limited to 'software') 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(); -- cgit v1.2.3