@@ -56,7 +56,8 @@ uint32_t lastLightReadTime = 0;
5656float lastLightValue = 0.5 ;
5757double irisValue = 0.5 ;
5858int iPupilFactor = 42 ;
59- uint32_t boopSum = 0 ;
59+ uint32_t boopSum = 0 ,
60+ boopSumFiltered = 0 ;
6061bool booped = false ;
6162int fixate = 7 ;
6263uint8_t lightSensorFailCount = 0 ;
@@ -106,6 +107,15 @@ SPISettings settings(DISPLAY_FREQ, MSBFIRST, SPI_MODE0);
106107// the affected DMA channel (DMAbuddy::fix()).
107108#define DMA_TIMEOUT ((240 * 16 * 4000 ) / (DISPLAY_FREQ / 1000 ))
108109
110+ static inline uint16_t readBoop (void ) {
111+ uint16_t counter = 0 ;
112+ pinMode (boopPin, OUTPUT);
113+ digitalWrite (boopPin, HIGH);
114+ pinMode (boopPin, INPUT);
115+ while (digitalRead (boopPin) && (++counter < 1000 ));
116+ return counter;
117+ }
118+
109119// Crude error handler. Prints message to Serial Monitor, blinks LED.
110120void fatal (char *message, uint16_t blinkDelay) {
111121 Serial.println (message);
@@ -330,6 +340,14 @@ void setup() {
330340 calcDisplacement ();
331341 Serial.printf (" Free RAM: %d\n " , availableRAM ());
332342
343+ if (boopPin >= 0 ) {
344+ boopThreshold = 0 ;
345+ for (i=0 ; i<240 ; i++) {
346+ boopThreshold += readBoop ();
347+ }
348+ boopThreshold = boopThreshold * 110 / 100 ; // 10% overhead
349+ }
350+
333351 randomSeed (SysTick->VAL + analogRead (A2));
334352 eyeOldX = eyeNewX = eyeOldY = eyeNewY = mapRadius; // Start in center
335353 for (e=0 ; e<NUM_EYES; e++) { // For each eye...
@@ -419,7 +437,7 @@ void loop() {
419437 }
420438
421439 // Eyes fixate (are slightly crossed) -- amount is filtered for boops
422- int nufix = booped ? 150 : 7 ;
440+ int nufix = booped ? 90 : 7 ;
423441 fixate = ((fixate * 15 ) + nufix) / 16 ;
424442 // save eye position to this eye's struct so it's same throughout render
425443 if (eyeNum & 1 ) eyeX += fixate; // Eyes converge slightly toward center
@@ -500,37 +518,39 @@ void loop() {
500518 int ix = (int )map2screen (mapRadius - eye[eyeNum].eyeX ) + 120 , // Pupil position
501519 iy = (int )map2screen (mapRadius - eye[eyeNum].eyeY ) + 120 ; // on screen
502520 iy += irisRadius / 2 ; // top edge of iris (ish) in screen pixels
503- float qqq ; // So many sloppy temp vars in here for now, sorry
521+ float uq, lq ; // So many sloppy temp vars in here for now, sorry
504522 if (eyeNum & 1 ) ix = 239 - ix; // Flip for right eye
505523 if (iy > upperOpen[ix]) {
506- qqq = 1.0 ;
524+ uq = 1.0 ;
507525 } else if (iy < upperClosed[ix]) {
508- qqq = 0.0 ;
526+ uq = 0.0 ;
527+ } else {
528+ uq = (float )(iy - upperClosed[ix]) / (float )(upperOpen[ix] - upperClosed[ix]);
529+ }
530+ if (booped) {
531+ uq = 0.9 ;
532+ lq = 0.7 ;
509533 } else {
510- qqq = ( float )(iy - upperClosed[ix]) / ( float )(upperOpen[ix] - upperClosed[ix]) ;
534+ lq = 1.0 - uq ;
511535 }
512536 // Dampen eyelid movements slightly
513537 // SAVE upper & lower lid factors per eye,
514538 // they need to stay consistent across frame
515- eye[eyeNum].upperLidFactor = (eye[eyeNum].upperLidFactor * 0.75 ) + (qqq * 0.25 );
516- eye[eyeNum].lowerLidFactor = 1.0 - eye[eyeNum].upperLidFactor ;
539+ eye[eyeNum].upperLidFactor = (eye[eyeNum].upperLidFactor * 0.6 ) + (uq * 0.4 );
540+ eye[eyeNum].lowerLidFactor = (eye[eyeNum].lowerLidFactor * 0.6 ) + (lq * 0.4 );
541+
517542
518543 // Process blinks
519544 if (eye[eyeNum].blink .state ) { // Eye currently blinking?
520545 // Check if current blink state time has elapsed
521546 if ((t - eye[eyeNum].blink .startTime ) >= eye[eyeNum].blink .duration ) {
522- if ((eye[eyeNum].blink .state == ENBLINK) && booped) {
523- // do nothing, don't advance blink state while booped
547+ if (++eye[eyeNum].blink .state > DEBLINK) { // Deblinking finished?
548+ eye[eyeNum].blink .state = NOBLINK; // No longer blinking
549+ eye[eyeNum].blinkFactor = 0.0 ;
550+ } else { // Advancing from ENBLINK to DEBLINK mode
551+ eye[eyeNum].blink .duration *= 2 ; // DEBLINK is 1/2 ENBLINK speed
552+ eye[eyeNum].blink .startTime = t;
524553 eye[eyeNum].blinkFactor = 1.0 ;
525- } else {
526- if (++eye[eyeNum].blink .state > DEBLINK) { // Deblinking finished?
527- eye[eyeNum].blink .state = NOBLINK; // No longer blinking
528- eye[eyeNum].blinkFactor = 0.0 ;
529- } else { // Advancing from ENBLINK to DEBLINK mode
530- eye[eyeNum].blink .duration *= 2 ; // DEBLINK is 1/2 ENBLINK speed
531- eye[eyeNum].blink .startTime = t;
532- eye[eyeNum].blinkFactor = 1.0 ;
533- }
534554 }
535555 } else {
536556 eye[eyeNum].blinkFactor = (float )(t - eye[eyeNum].blink .startTime ) / (float )eye[eyeNum].blink .duration ;
@@ -549,21 +569,9 @@ void loop() {
549569
550570 // Once per frame (of eye #0), reset boopSum...
551571 if ((eyeNum == 0 ) && (boopPin >= 0 )) {
552- if (boopSum > boopThreshold) {
572+ boopSumFiltered = ((boopSumFiltered * 3 ) + boopSum) / 4 ;
573+ if (boopSumFiltered > boopThreshold) {
553574 if (!booped) {
554- timeOfLastBlink = t;
555- // slow, intentional blink
556- uint32_t blinkDuration = random (60000 , 100000 );
557- // Set up durations for both eyes (if not already winking)
558- for (uint8_t e=0 ; e<NUM_EYES; e++) {
559- // if(eye[e].blink.state == NOBLINK) {
560- if (1 ) {
561- eye[e].blink .state = ENBLINK;
562- eye[e].blink .startTime = t;
563- eye[e].blink .duration = blinkDuration;
564- }
565- }
566- timeToNextBlink = blinkDuration * 3 + random (4000000 );
567575 Serial.println (" BOOP!" );
568576 }
569577 booped = true ;
@@ -815,6 +823,11 @@ void loop() {
815823 digitalWrite (eye[eyeNum].dc , HIGH); // Data mode
816824 } // end first-column check
817825
826+ // MUST read the booper when there’s no SPI traffic across the nose!
827+ if ((eyeNum == (NUM_EYES-1 )) && (boopPin >= 0 )) {
828+ boopSum += readBoop ();
829+ }
830+
818831 memcpy (eye[eyeNum].dptr , &eye[eyeNum].column [eye[eyeNum].colIdx ].descriptor [0 ], sizeof (DmacDescriptor));
819832 eye[eyeNum].dma_busy = true ;
820833 eye[eyeNum].dma .startJob ();
@@ -824,13 +837,4 @@ void loop() {
824837 }
825838 eye[eyeNum].colIdx ^= 1 ; // Alternate 0/1 line structs
826839 eye[eyeNum].column_ready = false ; // OK to render next line
827-
828- if ((eyeNum == 0 ) && (boopPin >= 0 )) {
829- uint16_t counter = 0 ;
830- pinMode (boopPin, OUTPUT);
831- digitalWrite (boopPin, HIGH);
832- pinMode (boopPin, INPUT);
833- while (digitalRead (boopPin) && (++counter < 1000 ));
834- boopSum += counter;
835- }
836840}
0 commit comments