@@ -86,10 +86,15 @@ uint8_t *linebuf = NULL; // Data for ALL images
8686#define RFM69_INT 21 // Interrupt pin
8787#define NETWORKID 1
8888#define NODEID 255
89+ #define INTERVAL 250000 // Broadcast interval, microseconds
8990
9091RH_RF69 *radio;
9192bool sender = false ; // Radio send vs receive
9293
94+ volatile uint16_t imgnum = 0 ;
95+ volatile uint32_t last_change = 0 ;
96+ uint32_t last_xmit = 0 ;
97+
9398// The PRIMARY CORE runs all the non-deterministic grunt work --
9499// Filesystem/config init, talking to the radio and infrared,
95100// keeping the CIRCUITPY filesystem alive.
@@ -247,6 +252,8 @@ void setup() { // Core 0 start-up code
247252 imglist[0 ].height = 1 ;
248253 imglist[0 ].reps_sec = 1.0 ;
249254 imglist[0 ].total_usec = 1000000 ;
255+ imgnum = 0 ;
256+ last_change = micros ();
250257
251258 core1_wait = false ; // Done reading config, core 1 can proceed
252259
@@ -270,48 +277,63 @@ void setup() { // Core 0 start-up code
270277 radio->setEncryptionKey ((uint8_t *)ENCRYPTKEY);
271278}
272279
280+ uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
273281
274282void loop () {
275- uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
276- uint8_t len = sizeof (buf);
277-
278- if (radio->waitAvailableTimeout (500 )) {
279- // Should be a reply message for us now
280- if (radio->recv (buf, &len)) {
281- Serial.print (" got reply: " );
282- Serial.println ((char *)buf);
283- } else {
284- Serial.println (" recv failed" );
283+ uint32_t now = micros ();
284+
285+ if (sender) {
286+ bool xmit = false ; // Will be set true if it's time to send
287+ uint32_t elapsed = now - last_change;
288+
289+ if (elapsed >= imglist[imgnum].total_usec ) {
290+ elapsed -= imglist[imgnum].total_usec ; // Partly into new image
291+ if (++imgnum >= num_images) imgnum = 1 ;
292+ last_change = now;
293+ xmit = true ;
294+ } else if ((now - last_xmit) >= INTERVAL) {
295+ xmit = true ;
296+ }
297+ if (xmit) {
298+ radio->waitPacketSent ();
299+ memcpy (&buf[0 ], (void *)&imgnum , 2 );
300+ memcpy (&buf[2 ], &elapsed, 2 );
301+ memcpy (&buf[6 ], &buf[0 ] , 6 ); // Rather than checksum, send data 2X
302+ last_xmit = now;
303+ radio->send ((uint8_t *)buf, 12 );
285304 }
286305 } else {
287- Serial.println (" No reply, is rf69_server running?" );
306+ if (radio->waitAvailableTimeout (250 )) {
307+ uint8_t len;
308+ if (radio->recv (buf, &len)) {
309+ Serial.print (" got reply: " );
310+ Serial.println ((char *)buf);
311+ if ((len == 12 ) && !memcmp (&buf[0 ], &buf[6 ], 6 )) {
312+ uint16_t n = *(uint16_t *)(&buf[0 ]);
313+ if (n != imgnum) {
314+ imgnum = n;
315+ last_change = now - *(uint32_t *)(&buf[2 ]);
316+ }
317+ }
318+ } else {
319+ Serial.println (" recv failed" );
320+ }
321+ } else {
322+ Serial.println (" No reply, is rf69_server running?" );
323+ }
288324 }
289- delay (1000 );
290325}
291326
292327// The SECOND CORE is then FULLY DEDICATED to keeping the LEDs
293328// continually refreshed, does not have to pause for other tasks.
294329
295- int imgnum;
296- uint32_t last_change;
297-
298330void setup1 () {
299331 while (core1_wait); // Wait for setup() to complete before going to loop1()
300- // Force initial rollover for first image, first line
301- imgnum = num_images;
302- last_change = -imglist[imgnum].total_usec ;
303332}
304333
305334
306335void loop1 () {
307- strip->show ();
308- uint32_t now = micros ();
309- uint32_t elapsed_usec = now - last_change;
310- if (elapsed_usec >= imglist[imgnum].total_usec ) {
311- elapsed_usec -= imglist[imgnum].total_usec ; // Partly into new image
312- if (++imgnum >= num_images) imgnum = 1 ;
313- last_change = now;
314- }
315- uint32_t row = (uint32_t )((float )elapsed_usec / 1000000.0 * imglist[imgnum].reps_sec * (float )imglist[imgnum].height ) % imglist[imgnum].height ;
336+ uint32_t row = (uint32_t )((float )(micros () - last_change) / 1000000.0 * imglist[imgnum].reps_sec * (float )imglist[imgnum].height ) % imglist[imgnum].height ;
316337 memcpy (strip->getPixels (), imglist[imgnum].data + row * dotstar_length * 3 , dotstar_length * 3 );
338+ strip->show ();
317339}
0 commit comments