10 bits (value encoded in 8 high bit + 2 low bit) into decimal ?


    Sep 17 2019 | 1:39 pm
    Hi there, I'm stuck in the end of this My 8channels FlexVolt sensors (which are very nice) output data with 10bits precision like that (reference: https://github.com/CatabeeScienceAndDesign/FlexVolt) high8BitsFromChannel1 high8BitsFromChannel2 high8BitsFromChannel3 high8BitsFromChannel4 high8BitsFromChannel5 high8BitsFromChannel6 high8BitsFromChannel7 high8BitsFromChannel8 0b11223344 (where 11 is the lowest 2 bits from channel1, 22 is the lowest 2 bits from channel2, etc)
    Each channel represent a value coming from muscle contraction.
    For retrieving each value, I need to combine one of the first 8 ones and the last one.
    For instance, if I want the value coming from the channel 1, if I receive 128 0 0 0 0 0 0 150, it means: - 128 is the high 8bits from the channel 1, ok - 150 has to be decomposed/converted and combined to the previous one
    How can I retrieve my final value ...? I'm really stuck and this is ... easy, I know.
    I'd do: 128 << 2 + ????????
    (not sure about the thread title, I may improve this)

    • Sep 17 2019 | 2:14 pm
      You should do a binary AND with some masks : 00000011 (= 3) to get the 2 last bits for channel 4 00001100 (= 12) to get the 2 bits for channel 3 … 11000000 (= 192) to get the 2 bits from channel 1
      then shift the result to the right by the correct amount of bits. Something like this :
    • Sep 17 2019 | 2:18 pm
      Thanks for your answer, but I don't understand well as there are 8 channels. The documentation is not enough and I asked them more.
      Actually, their own application is working fine (graphes enough precision and nice smoothed data) https://github.com/CatabeeScienceAndDesign/FlexVolt/tree/master/www But as I bought their solution, I don't want to reverse engineering it myself to understand it and I'd prefer their answer...
    • Sep 17 2019 | 4:09 pm
      Looking quickly into their flexvolt.js code, it seems that 11 bytes are expected when the system is used with 8 channels and 10bits res. I guess 1 byte is 75, 8 bytes are the 8 MSB parts for the 8 channels, and 2 bytes are for the 8 LSB parts. You need to find the order of those 11 bytes. So you should check wether they first send the MSBs for channels 1-4, followed by 1 byte with the 4 LSB parts then MSB for ch 5-8 followed by LSB ; or if all 8 MSB are sent followed by 2 bytes for the LSBs.
    • Sep 17 2019 | 4:18 pm
      hello, sure for the first bytes. this is why I didn't mention it.
      first byte is, indeed, 75
      I think my problem is the order of them yes. as far as I observe: With no contraction (I mean nothing happening on all sensors), I receive: 128 128 128 128 128 128 128 128 <last> with <last> changing fast So I think the order is : channel1msb, channel2msb....., and the "number" the number is : 0b1122334455667788, according to FlexVolt nn being the 2 bits for lowest two bit
    • Sep 17 2019 | 5:41 pm
      Hello Julien,
      An aside before I answer this - you would most likely find 8-bit data sufficient, and it will make everything a bit easier. 8-Channels at 10-bits is pushing the limits of the Bluetooth bandwidth and the sensors processors. You are close! You are correct in most of your surmises so far. You expect 11 bytes, with the first byte being a signature.
      1. Signature (75 = 8channels, 10-bit) 2. Chan 1 MSB 3. Chan 2 MSB ... 8. Chan 7 MSB 9. Chan 8 MSB 10. Overflow LSB 11223344 11. Overflow LSB 55667788
      The relevant code is in flexvolt.js . You can see where I store the two overflow bytes, then for each channel, shift the MSB left by 2 and append relevant 2 bits from overflow.
      var readInd = 0, dataInd = 0;
      while(readInd < (dataIn.length-api.readParams.expectedBytes) ){
          var tmp = dataIn[readInd++];
          if (tmp === api.readParams.expectedChar){
              dataTimes.push(timestamp); 
              timestamp+=timestampInterval*hardwareLogic.settings.downSampleCount;
              if (!hardwareLogic.settings.bitDepth10) {
                  for (iChan = 0; iChan < hardwareLogic.settings.nChannels; iChan++){
                      dataParsed[iChan][dataInd] = factor8Bit*(dataIn[readInd++] - api.readParams.offset); // centering on 0!
                  }
                  dataInd++;
              } else if (hardwareLogic.settings.bitDepth10) {
                  tmpLow = dataIn[readInd+hardwareLogic.settings.nChannels];
                  if (hardwareLogic.settings.nChannels > 4) {
                    tmpLow2 = dataIn[readInd+hardwareLogic.settings.nChannels+1];
                  }
                  for (iChan = 0; iChan < Math.min(4, hardwareLogic.settings.nChannels); iChan++){
                      dataParsed[iChan][dataInd] = factor10Bit*((dataIn[readInd++]<<2) + ((tmpLow>>(2*(3-iChan))) & 3) - api.readParams.offset); // centering on 0!
                  }
                  for (iChan = 4; iChan < hardwareLogic.settings.nChannels; iChan++){
                      dataParsed[iChan][dataInd] = factor10Bit*((dataIn[readInd++]<<2) + ((tmpLow2>>(2*(3-iChan))) & 3) - api.readParams.offset); // centering on 0!
                  }
                  readInd++; // for the tmpLow read
                  if (hardwareLogic.settings.nChannels > 4) {
                    readInd++; // for the tmpLow2 read
                  }
                  dataInd++;
              }
      
          } else if (tmp === 116) { //'t' - voltage statement
              var batteryVoltage = dataIn[readInd++];
              console.log('INFO: Got Battery Level: ' + JSON.stringify(batteryVoltage));
              updateBatteryVoltage(batteryVoltage);
              break; // kick back out -
          } else {
              console.log('WARNING: unexpected Char '+tmp);
          }
      }
    • Sep 17 2019 | 5:49 pm
      Looks like a patch like Patrick posted should work, with an added conversion from "0 1 10 11" to "0 1 2 3" to add to your "128 << 2". For instance, like this - I'm sure we can implement more efficiently, but that's a first rough version:
    • Sep 18 2019 | 6:12 am
      Jean-François, there is no need for a conversion : it is the number's Display format that is set to binary. A number is a number…
    • Sep 18 2019 | 1:05 pm
      Indeed, I missed that! I don't know what I was doing when I played with the patch! Really, I see no reason why Julien's thing would not work now. Maybe to debug, starting with a four-channel configuration would be useful...