Skip to content

Internals: ev3dev stretch

David Lechner edited this page Jul 15, 2018 · 4 revisions

This page contains some information on some of the internal workings of ev3dev-stretch that might be of use to advanced users.

Analog polling rate

Note: This section only applies to EV3 and FatcatLab EVB, it does not apply to any Raspberry-Pi-based devices.

Background

The EV3 (and FatcatLab EVB) use a TI ADS7958 16-channel, 10-bit analog to digital converter chip. This chip communicates with the main processor via SPI. Eight of the channels are used for input ports (pins 1 and 6). Four channels are used for output ports (pin 5). Two of the ports are used to measure battery voltage and current. Two of the channels are unused.

Implementation

In ev3dev-stretch, we are using the Linux kernel's IIO framework to provide an interface to the analog/digital converter both inside and outside of the kernel. During normal usage in ev3dev-stretch, everything is done within the kernel. The power supply driver reads the voltage and current on demand (e.g. when brickd periodically checks to see if the battery is getting low). The input and output port values are polled every 10 milliseconds and push the data to the port drivers (which in turn can push data to sensor drivers).

Advanced Use

There are a couple of things you can do here.

Changing the Polling Rate

As mentioned already, the default polling rate is only 100Hz (the values are read every 10 milliseconds). There is an IIO trigger device that can be used to adjust this if needed. Just be aware that higher polling rate means higher CPU usage.

  • Make sure we have the right trigger by reading name attribute:

    $ cat /sys/bus/iio/devices/trigger0/name 
    spi0.3
    
  • Verify the current polling rate is 100Hz:

    $ cat /sys/bus/iio/devices/trigger0/sampling_frequency 
    100
    
  • Change the polling rate to 1000Hz (every 1 millisecond, like the official LEGO firmware):

    $ sudo sh -c 'echo 1000 > /sys/bus/iio/devices/trigger0/sampling_frequency'
    

Accessing the Raw Analog Values

The raw analog values can also be read directly via sysfs. As mentioned, this is a 10-bit analog/digital converter, so the values will be from 0 to 1023, where 1023 equals 5V.

  • Make sure we have the right IIO device:

      $ cat /sys/bus/iio/devices/iio\:device0/name 
      ti-ads7957
    
  • Read channel 0:

      $ cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw 
      36
    

The channel mapping can be found here or in the schematics of the official hardware developer kit from the LEGO MINDSTORMS website.

PRU Quadrature Encoder

Note: This section only applies to EV3 and FatcatLab EVB, it does not apply to any Raspberry-Pi-based devices.

Since the ev3dev-2.2.0 kernel release, the quadrature encoders (the thing that measures the position and speed of the motor) are now implemented using one of the Programmable Runtime Units (PRUs) on the EV3's CPU. This significantly reduces the number of interrupts to the CPU when motors are running and makes measuring the speed more accurate.

Similar to the analog inputs, the quadrature encoders use the IIO subsystem in the Linux kernel. They are currently polled every 2 milliseconds (even when no motors are connected). This can be changed via an IIO trigger as described in analog section above.

The "raw" values can also be read via sysfs. The values are quadrature encoder counts in 4x mode. This means each rising and falling edge of both the A and B lines. The old ev3dev motor driver and official LEGO firmware both only read the rising and falling edge of one pin (2x mode), which give 360 counts per rotation (which nicely coincides with 360 degrees in 1 rotation). The tacho-motor interface still gives this value in ev3dev-stretch (so that we don't break peoples' programs). The 4x mode values are available separately though. These will give 720 counts per rotation instead of 360.

  • Make sure we have the right IIO device:

      $ cat /sys/bus/iio/devices/iio\:device1/name 
      ev3-tacho
    
  • Read output port A:

      $ cat /sys/bus/iio/devices/iio\:device1/in_count0_raw 
      2852
    

Clone this wiki locally