• So after a bit of fiddling, I've come up with the following that seems to work. I'm sure this has been done before and in a better and more reliable way, but this is what I have.

    PC Sound Generator:

    AudioContext = window.AudioContext || window.webkitAudioContext;
    audioContext = new AudioContext();
    
    gainNode = audioContext.createGain();
    gainNode.gain.value = 1;
    
    var buffer = audioContext.createBuffer(1, 44100, 44100);
    var b = buffer.getChannelData(0);
    
    function fillAt(arr, val, at, len) {
      arr.fill(val, at, at+len);
    }
    
    function charToBinary(char) {
      var bin = char.charCodeAt(0).toString(2);
      return new Array(9 - bin.length).join('0') + bin;
    }
    
    b.fill(-1.0);
    
    function writeBinary(offset, binary) {
      if (!binary) {
        binary = '00000000';
      }
      
      var data = binary.split('');
      // Bit preamble
      fillAt(b, 1.0, offset+4, 2);
      fillAt(b, 1.0, offset+300, 2);
      // Data
      data[0] === '1' && fillAt(b, 1.0, offset+304, 2);
      data[1] === '1' && fillAt(b, 1.0, offset+308, 2);
      data[2] === '1' && fillAt(b, 1.0, offset+312, 2);
      data[3] === '1' && fillAt(b, 1.0, offset+316, 2);
      data[4] === '1' && fillAt(b, 1.0, offset+320, 2);
      data[5] === '1' && fillAt(b, 1.0, offset+324, 2);
      data[6] === '1' && fillAt(b, 1.0, offset+328, 2);
      data[7] === '1' && fillAt(b, 1.0, offset+332, 2);
      // Bit postamble
      fillAt(b, 1.0, offset+336, 2);
      fillAt(b, 1.0, offset+632, 2);
      
      return offset+632;
    }
    
    function writeString(str) {
      var chars = str.split('');
      var lastOffset = 0;
      
      for(var i = 0; i < chars.length; i++) {
        var char = chars[i];
        var bin = charToBinary(char);
        lastOffset = writeBinary(lastOffset, bin);
      }
    }
    
    // Stream start
    fillAt(b, 1.0, 0, 2);
    
    writeString('abcdefghijklmnopqrstuvwxyz'­);
    
    
    source = audioContext.createBufferSource();
    source.buffer = buffer;
    source.connect(gainNode);
    gainNode.connect(audioContext.destinatio­n);
    source.start();
    
    

    Espruino Receiver:

    let readBits = false;
    let bits = [];
    
    function handlePulse(e) {
      const diff = e.time - e.lastTime;
    
      //console.log(diff);
      
      if (diff > 1.0 || isNaN(diff)) {
        if (readBits) {
          //console.log('stop reading bits');
          readBits = false;
        }
        return;
      }
    
      const zeroes = (diff.toFixed(4) * 10000).toFixed(1);
    
      if (zeroes > 50) {
        if (readBits) {
          //console.log('stop reading bits');
          readBits = false;
          bits.pop();
          
          //console.log(bits);
          var str = bits.join('');
          var num = parseInt(str, 2);
          var chr = String.fromCharCode(num);
          console.log(chr);
          bits = [];
        } else {
          //console.log('start reading bits');
          readBits = true;
        }
        
        return;
      }
    
      if (readBits) {
        //console.log(diff);
        //console.log(zeroes);
    
        for(var i = 0; i < zeroes; i++) {
          bits.push(0);
        }
    
        bits.push(1);
      }
    }
    
    function onInit() {
      pinMode(A5, 'input_pullup');
      setWatch(handlePulse, A5, { repeat: true, edge: 'rising' });
    }
    

    So now my question @Gordon, is how do I reverse this? i.e generate sound on Espruino. I'm guessing I want to just be doing digitalWrite to the pin I have wired to my headphone socket, can I reuse any of the code I have or should I start again?

About

Avatar for dave_irvine @dave_irvine started