• ( no enough space in one post .. )

    The debug code currently handling the logic is the following
    ( I'll post the Illustrator script below in this post, as well as a a 'dumb try to get the shortest path linking every dots' ( html5 canvas pathfinding stuff ) not quite working as expected .. but hey, it may get better if given time to dod so ? ;p )

    // -- AKALI MASK --
    // - array generated from an Illustrator script pushing either '0, 0, 0' or '255,255,255' depending on the presence of pathItems above dots at certain coords in the artboard
    var mouthsLedsArrays = [
      [0,0,0,0,0,0,255,255,255,255,255,255,255­,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255­,255,255,255,255,255,255,255,0,0,0,0,0,0­],
      [255,255,255,255,255,255,0,0,0,0,0,0,0,0­,0,255,255,255,255,255,255,255,255,255,2­55,255,255,0,0,0,0,0,0,0,0,0,255,255,255­,255,255,255]
    ];
    
    // - timings extracted from a video/audio analysis of a chunk from the LoL soundtrack
    var absTimeMouthsIdxsArray = [
      //[<ms_from_start>, <mouth_idx>]
      [37, 0],
      [38, 1],
      [40, 0],
      [45, 1],
      [45.2, 0],
      [45.5, 1]
    ];
    
    // - relative timings to be used with 'setTimeout' to schedule the mouth updates
    // R: to map abolute times to relative timing in ms:
    // relTime = (absTime * 1000) - (1stAbsTime * 1000)
    var reTimeMouthsIdxsArray = [];
    for(var i=0; i< absTimeMouthsIdxsArray.length; i++){
      var relTime = (i === 0) ? ((absTimeMouthsIdxsArray[i][0] * 1000) - (absTimeMouthsIdxsArray[i][0] * 1000)) : (absTimeMouthsIdxsArray[i][0] * 1000) - (absTimeMouthsIdxsArray[i-1][0] * 1000);
      reTimeMouthsIdxsArray[i] = [relTime, absTimeMouthsIdxsArray[i][1]];
    }
    console.log('reTimeMouthsIdxsArray : ' + reTimeMouthsIdxsArray);
    console.log('reTimeMouthsIdxsArray.lengt­h : ' + reTimeMouthsIdxsArray.length);
    
    // few vars
    var timr = -1;
    var currMouthAnimIdx = 0; // where we're at in the 'reTimeMouthsIdxsArray'
    //var currMouthIdx = 0;
    var currMouth = mouthsLedsArrays[reTimeMouthsIdxsArray[c­urrMouthAnimIdx][1]];
    console.log('currMouthAnimIdx : ' + currMouthAnimIdx);
    console.log('currMouth : ' + currMouth);
    
    // - to be replaced by spy calls to update the leds
    // display mouth ( via LEDS or pretty much anything ?)
    function displayCurrMouth(){
      console.log('NEW MOUTH: ' + currMouth);
      if(currMouthAnimIdx+1 < reTimeMouthsIdxsArray.length){
        console.log('next mouth in: ' + reTimeMouthsIdxsArray[currMouthAnimIdx+1­][0] );
        g.clear();
        g.drawString('mouth idx: ' + currMouthAnimIdx, 10, 10);
        g.drawString('next mouth in: ' + reTimeMouthsIdxsArray[currMouthAnimIdx+1­][0], 10, 20);
        g.flip();
      }
      /*
      g.clear();
      g.drawString('mouth idx: ' + currMouthAnimIdx, 10, 10);
      //g.drawString('mouth: ' + currMouth.join(','), 10, 20);
      g.drawString('next mouth in: ' + reTimeMouthsIdxsArray[currMouthAnimIdx][­0] + 'ms', 10, 20);
      //g.drawString('next mouth in: ' + reTimeMouthsIdxsArray[currMouthAnimIdx][­0] + 'ms', 10, 30);
      g.flip();
      */
    }
    
    // transition between mouths
    function nxtMouth(){
      if(currMouthAnimIdx+1 < reTimeMouthsIdxsArray.length){ // didn't reach end of array yet
        currMouthAnimIdx = currMouthAnimIdx+1;
        //console.log('next mouth in: ' + reTimeMouthsIdxsArray[currMouthAnimIdx][­0] );
        //if(currMouthAnimIdx+1 < reTimeMouthsIdxsArray.length){ console.log('next mouth in: ' + reTimeMouthsIdxsArray[currMouthAnimIdx+1­][0] ); }
        timr = setTimeout(function(){
          currMouth = mouthsLedsArrays[reTimeMouthsIdxsArray[c­urrMouthAnimIdx][1]];
          //console.log('NEW MOUTH: ' + currMouth);
          displayCurrMouth();
          nxtMouth(); // schedule next call
        }, reTimeMouthsIdxsArray[currMouthAnimIdx][­0]);
      } else {
        timr = -1;
        console.log('end of mouth timed array reached -> animation complete !');
        g.clear();
        g.drawString('ANIMATION COMPLETE !', 10, 10);
        g.drawString('press startBtn again ;)', 10, 20);
        g.flip();
      }
    }
    
    // start & reset
    function startAnim(){
      console.log('start !');
      g.clear();
      g.drawString('next mouth in: ' + reTimeMouthsIdxsArray[currMouthAnimIdx+1­][0], 10, 10);
      g.flip();
      nxtMouth();
    }
    function resetAnim(){
      console.log('reset !');
      if(timr !== -1){
        clearTimeout(timr);
        timr = -1;
      }
      currMouthAnimIdx = 0;
      //currMouth = mouthsLedsArrays[reTimeMouthsIdxsArray[c­urrMouthAnimIdx][1]];
      currMouth = mouthsLedsArrays[reTimeMouthsIdxsArray[c­urrMouthAnimIdx][1]];
      g.clear();
      g.drawString('RESET COMPLETE !', 10, 10);
        g.drawString('press startBtn again ;)', 10, 20);
      g.flip();
    }
    
    // uC-specific pins
    var startBtnPin = A0;
    var resetBtnPin = A1;
    // watches
    var startBtnW;
    var resetBtnW;
    
    function startOled(){
      g.clear();
      g.drawString('waiting startBtn press ..', 10, 10);
      g.flip();
      
      // setup btns
      pinMode(startBtnPin, 'input_pullup');
      startBtnW = setWatch(function(e) { /*console.log(e.time-e.lastTime);*/ startAnim(); }, startBtnPin, { repeat:true, edge:'falling' });
      pinMode(resetBtnPin, 'input_pullup');
      resetBtnW = setWatch(function(e) { /*console.log(e.time-e.lastTime);*/ resetAnim(); }, resetBtnPin, { repeat:true, edge:'falling' });
    }
    
    var g = undefined;
    function onInit(){
      // I2C
      I2C1.setup({scl:B6,sda:B7, bitrate:1000000});
      g = require("SSD1306").connect(I2C1, startOled, { height : 32, contrast : 255 });
    }
    
About

Avatar for stephaneAG @stephaneAG started