• Trill
  • Trill Craft: Spikes in raw data using a Raspberry Pi

Hi,
I have three Trill Craft boards connected to a Raspberry Pi 3.
When I read the raw data continously I get some spikes from time to time - see attachment.
One value is for example normally around 852 and the spike goes up to 884. The values are scaled to have their maximum at 1023, so they are not in the limit.
Any idea what could cause this?

Furthermore I tried to change the prescaler withtouchSensor.setPrescaler(4) but the raw values does not change.
touchSensor.printDetails(); gives the the correct prescaler value.
Any idea about his? I am using the library from https://github.com/BelaPlatform/Trill-Linux/tree/master/

    3.3 V from the Raspberry Pi connector.

    can you try adding a 10u or more electrolytic capacitor and a 100n ceramic capacitor between 3.3V and GND and see if this improves at all?

    • hans replied to this.

      hans Furthermore I tried to change the prescaler withtouchSensor.setPrescaler(4) but the raw values does not change.

      can you show your code? I suspect you are not sleeping between commands

      My code is basically this:

      #define VERBOSE
      
      
      int main(int argc, char** argv)
      {
        
          // Button (GPIO)
          if (gpioInitialise() < 0) {
              return 1;
          }
          gpioSetMode(GPIO_START_BUTTON, PI_INPUT);
          gpioSetPullUpDown(GPIO_START_BUTTON, PI_PUD_UP);
      
          gpioSetMode(GPIO_TRILL_RESET, PI_OUTPUT);
          gpioWrite(GPIO_TRILL_RESET, 1);
          usleep(1000);
          gpioWrite(GPIO_TRILL_RESET, 0);
          // Wait until Trill has finished booting
          usleep(600000);
      
          // Trill
          trill_Init(trillSensorTop,    0x30, 4); // is not applied. why??
          trill_Init(trillSensorBottom, 0x36, 3);
          trill_Init(trillSensorBase,   0x33, 3);
      
      
          while(!gShouldStop) 
          {
              trillSensorTop.readI2C();
              trillSensorBottom.readI2C();
              trillSensorBase.readI2C();
              
          }
          return 0;
      }
      
      
      
      
      int trill_Init(Trill& touchSensor, uint8_t address = 0x33, uint8_t prescaler = 3)
      {
          std::string deviceName;
          int i2cBus = 1;
          Trill::Device device = Trill::CRAFT;
          Trill::Mode mode = Trill::RAW;
          unsigned int speed = 3;
          // unsigned int prescaler = 3;
          float threshold = 0.0;
      
          printf("Opening device %s on bus %d ", Trill::getNameFromDevice(device).c_str(), i2cBus);
          if(255 != address)
              printf("at address: %#4x(%d)", address, address);
          printf("\n");
      
          if(touchSensor.setup(i2cBus, device, address))
          {
              fprintf(stderr, "Error while initialising device\n");
              return 1;
          }
      
      
          if(touchSensor.setMode(mode) == 0) {
              #ifdef VERBOSE
              printf("Operation mode set to RAW.\n");
              #endif
          } else {
              fprintf(stderr, "Communication error\n");
              return 1;
          }
      
          if(touchSensor.setScanSettings(speed) == 0) {
              #ifdef VERBOSE
              printf("Scan speed set to %d.\n", speed);
              #endif
          } else {
              fprintf(stderr, "Communication error\n");
              return 1;
          }
          usleep(10000);
          if(touchSensor.setPrescaler(prescaler) == 0) {
              #ifdef VERBOSE
              printf("Prescaler set to %d.\n", prescaler);
              #endif
          } else {
              fprintf(stderr, "Communication error\n");
              return 1;
          }
          usleep(10000);
          if(touchSensor.setNoiseThreshold(threshold) == 0) {
              #ifdef VERBOSE
              printf("Threshold set to %d.\n", threshold);
              #endif
          } else {
              fprintf(stderr, "Communication error\n");
              return 1;
          }
      
          usleep(10000);
          if(touchSensor.updateBaseline() != 0) {
              fprintf(stderr, "Communication error\n");
              return 1;
          }
      
          #ifdef VERBOSE
          usleep(10000);
          touchSensor.printDetails();
          #endif
      
          return 0;
      }

      hmm the code looks mostly OK, but as you are setting the speed to 3 (SLOW_SPEED), you may have to increase your sleep times in between calls or they may not get processed. This is because scan time - and thus time between reading incoming I2C messages - increases drastically (see here).

      I just updated the library so that if you are using a rev C sensor it will automatically wait for acknowledgement and so sleeps may become unnecessary.

      Thanks so far. I can test that unfortunately first on monday.

      5 days later

      Thanks for the fix in the library. Now the setting of the prescaler works. The setting has never worked, so the Trills ran always at a prescaler=1.

      For the problem with the spikes, I did several tests.

      1. Adding capacitors to VCC at the Trill didn't help, adding 100 Ohm series resisitors to the data and clock line not either.
      2. I replaced the RasperryPi by an Arduino: There everything works fine. I noticed a little bit different clock speed so I tied in with that.
      3. The Arduino runs at a clock around 80-90 kHz (I don't remember the exact value, but slightly below 100 kHz). So I checked the Raspi clock. Setting 100 kHz results in 67 kHz. So I set 150 kHz with gives 100 kHz and set also 200 kHz with gives 150 kHz. 100 kHz (real value) resolves my problem as there are no errorneous readouts. 150 kHz works fine with one Trill connected, but it failed with three Trills connected to the bus.
        So I have actually no idea which timing is at the limit - the Raspi or the Trill - but 100 kHz clock works fine now 🙂

      Hmm that's an interesting finding... do you have any pull up resistors on the scl and sda lines? The lack of those may be the reason you can't reach higher speed or use multiple devices at the same time

      The Raspberry Pi has some on chip and on the Arduino I added external ones.
      But it's weird that it works at higher speeds but not at slower. Normally you would assume the opposite.

      Who knows what happens when things are out of spec ... I2C specs are either 100kHz or 400kHz. Any other frequency is not guaranteed by specs to work. Do you know the size of the pullups on the Pi? You'll need something like 2k2 if you want to use several devices at once on the bus.

      AFAIK these are the maximum frequencies for the appropriate modes.

      From https://www.i2c-bus.org/speed/:

      The speed grades (standard mode: 100 kbit/s, full speed: 400 kbit/s, fast mode: 1 mbit/s, high speed: 3,2 Mbit/s) are maximum ratings. Compliant hardware guaranties that it can handle transmission speed up to the maximum clock rate specified by the mode.

      So all in the specs in my opinion. However, still strage that the clock frequency of the Pi is that much slower than set.

      Do you know the size of the pullups on the Pi?

      Yes it is something around 2k

        hans So all in the specs in my opinion

        You may well be right then, it makes sense.

        But the thing is Trill is full speed and so should handle up to 400kHz no problem. If you have a scope, you can look at the signal with one or several units connected and see if the edges become excessively smoothed in the latter case, and/or if you see any unexpected ringing.