• Watch out when you use Uint8Array and Uint8ClampedArray.

    First of all, regarding memory efficiency / consummation, they are absolutely the same.

    Second, they have the same protocol (state and behavioral properties / protocol).

    Third, they construct all from a plain array or from an array view. Former looks at the values of each source element where latter looks at the bytes the the source array is stored.

    Where they differ is handling the values of the source array when constructed, as code and output below show. A plain array with integers of different values is passed in the constructors of an Uint8Array and an Uint8ClampedArray:

    • Uint8Array just takes the least significant 8 bits
    • Uint8ClampedArray looks at the value and applies min/max function to be 0 or 255.

    If you need to transmit just 8 bits and the source elements are values up to 8 bits unsigned or 8-bit characters or 8-bit chars subset of 16-bit (or more) char set, you are just fine - you can think of 0..255 range - 256 different values.

    If they are signed integer numbers, you can think of only 0..127 range - still 256 different values - but you have to process them differently when interpreting the bytes back to numbers: you have to check MSB - most significant bit - and then do some math or bit manipulation for getting back the original value (in the 8+ bit format).

    // ui8_vs_ui8Clamped_arrays.js
    // 2019-08-15 - allObjects
    var arr
      , ui8Arr
      , uiCArr
      ;
    
    function fmtI(n,l) {
      var s = "            "
            + ((typeof n == "number")
                ? n
                : (""+n).substr(0,l)
              );
      return s.substr(s.length - (l || 12));
    }
    function onInit() {
    
    arr =
        [    0
        ,    1
        ,   -1
        ,  127
        , -127
        , -128
        ,  128
        ,  255
        , -255
        , -256
        ,  256
        ];
    ui8Arr = new Uint8Array(arr);
    uiCArr = new Uint8ClampedArray(arr);
    fmtLen = 5;
    console.log(
        fmtI(" src"       ,fmtLen)
      , fmtI(" ui8"       ,fmtLen)
      , fmtI(" uiClampled",fmtLen)
      );
    arr.forEach(function(e,i,a) {
      console.log(
          fmtI(arr[i]   ,fmtLen)
        , fmtI(ui8Arr[i],fmtLen)
        , fmtI(uiCArr[i],fmtLen)
        );
    } );
      
    }
    
    setTimeout(onInit,500);
    

    And respective output ('packed' into a multiline string for legible color in forum css):

     `
     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
             |_| espruino.com
     2v04 (c) 2019 G.Williams
    >
      src   ui8  uiCl
        0     0     0
        1     1     1
       -1   255     0
      127   127   127
     -127   129     0
     -128   128     0
      128   128   128
      255   255   255
     -255     1     0
     -256     0     0
      256     0   255
    ><- Serial1
    `
    
  • Thanks for the awesome detail @allObjects. My data is MIDI data, so technically 7 bit, although the extended MIDI data is 8-bit. I switched between Uint8 and Uint8Clamped and my data doesn't look any different, so I think I'm safe. However, my 16-bit binary data on USART? Different animal altogether. Good ole' endianness.

About