jueves, 31 de diciembre de 2015

Librería Max31855 para leer temperatura con termocuplas usando Machinekit

Este tutorial se centra en poder leer la temperatura con el amplificador MAX31855 a través de una termocupla. Lo primero que se necesita es copiar la librería modificada a la carpeta de drivers que maneja Machinekit, donde estan varias librerías para controlar otros dispositivos como el MCP23017, ADS7828,  PCA9685.

En el transcurso de este tutorial se dará una breve explicación de como usar estas librerías dentro del archivo .hal de machinekit para poder expandir los puertos de entradas y salidas en el caso del MCP23017, leer temperatura a través de los 8 canales del ADS7828 y poder generar señales PWM con el PCA9685.

La librería MAX31855 fue obtenida de PyBBIO y una pequeña porción de código de Adafruit se adapto por conflictos que se ha tenido con la librería de serbus originaría de PyBBIO; cambiando Serbus por Spidev.

nano MAX31855.py
 
"""
 MAX31855
 Copyright 2015 - Alexander Hiam <alex@graycat.io>
 A library for PyBBIO to interface with Maxim's MAX31855 thermocouple amplifier.
 MAX31855 is released as part of PyBBIO under its MIT license.
 See PyBBIO/LICENSE.txt
"""

# Copyright (c) 2014 Adafruit Industries
# Author: Tony DiCola
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import spidev


class MAX31855(object):

  SPI0 = 1
  SPI1 = 2

  OPEN_CIRCUIT   = 1
  SHORT_TO_GND   = 2
  SHORT_TO_VCC   = 4

  def __init__(self, bus, spi_cs=0, offset=0):
    self.spi_bus = spidev.SpiDev()
    self.bus = bus
    self.spi_cs = spi_cs
    self.spi_bus.open(bus,spi_cs)
    self.offset = offset
    self.error = None

  def readTempF(self):
    """ Reads temperature, converts to Fahrenheit and returns, or 
        returns None if error detected. """
    temp = self.readTempC() 
    return temp if not temp else temp * 9.0/5.0 + 32

  def readTempC(self):
    """ Reads and returns the temperature in Celsius, or returns None
        if error detected. """
    value = self.read()
    if value == None: return None
    # Extract 14-bit signed temperature value:
    temp = (value >> 18) & 0x3fff
    # Convert 2's complement:
    if temp >= 2**13: temp -= 2**14 
    return temp*0.25 + self.offset
    
  def readTempInternal(self):
    """ Reads and returns the MAX31855 reference junction temperature 
        in Celsius, or returns None if error detected. """
    value = self.read()
    if value == None: return None
    temp = (value >> 4) & 0xfff
    # Convert 2's complement:
    if temp >= 2**11: temp -= 2**12 
    return temp*0.0625

  def read(self):
    """ Receives and returns full 32-bit map from MAX31855, or sets
        self.error and returns None if fault detected. """
    self.error = None 

    # Configure SPI bus as required by the MAX31855:
    self.spi_bus.mode = 0
    self.spi_bus.max_speed_hz = 5000000
    self.spi_bus.lsbfirst = False
    raw = bytearray(self.spi_bus.readbytes(4))   
        
    value = raw[0] << 24 | raw[1] << 16 | raw[2] << 8 | raw[3] 

    if (value & (1<<16)):
      # Fault bit set, save error code and return None:
      self.error = value & 0b111
      return None

    return value

  def close(self):
    self.spi_bus.close()

En el siguiente tutorial se explicará como se usará la librería MAX31855 con Machinekit, creando un archivo que se usará como componente hal.

Para eso hay que escribir python -v e importar cualquier librería de Machinekit del siguiente link Machinekit Drivers.

python -v
from drivers import MCP23017
#saldrán varias rutas lo que interesa es que ha localizado la carpeta drivers,
#es ahi donde se debe copiar la librería MAX31855.py

sudo cp MAX31855.py /usr/lib/python2.7/dist-packages/drivers

Comprobamos la librería MAX31855.py

python
from drivers import MAX31855

Se ne se obtiene errores se a realizado de forma correcta los pasos. La siguiente parte es crear los archivos DTO para usar SPIDEV.

Para poder usar la librería Spidev se debe exportar el device tree overlay de SPI0 o SPI1, según el que se vaya a usar. En este caso se usará el SPI0 con do como entrada y d1 como salida. Para más información revisar el siguiente link BBB-SPIDEV.

Crear el archivo

nano BB-SPI0-01-00A0.dts

Pegar lo siguiente y guardar ctrl+o

/dts-v1/;
/plugin/;

/ {
    compatible = "ti,beaglebone", "ti,beaglebone-black";

    /* identification */
    part-number = "spi0pinmux";

    fragment@0 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            spi0_pins_s0: spi0_pins_s0 {
                pinctrl-single,pins = <
                  0x150 0x30  /* spi0_sclk, INPUT_PULLUP | MODE0 */
                  0x154 0x30  /* spi0_d0, INPUT_PULLUP | MODE0 */
                  0x158 0x10  /* spi0_d1, OUTPUT_PULLUP | MODE0 */
                  0x15c 0x10  /* spi0_cs0, OUTPUT_PULLUP | MODE0 */
                >;
            };
        };
    };

    fragment@1 {
        target = <&spi0>;
        __overlay__ {
             #address-cells = <1>;
             #size-cells = <0>;

             status = "okay";
             pinctrl-names = "default";
             pinctrl-0 = <&spi0_pins_s0>;

             spidev@0 {
                 spi-max-frequency = <24000000>;
                 reg = <0>;
                 compatible = "spidev";
             };
             spidev@1 {
                 spi-max-frequency = <24000000>;
                 reg = <1>;
                 compatible = "spidev";
             };            
        };
    };
};


spidev@0 permite usar cs (chip select) con 0
spidev@1 permite usar cs (chip select) con 1

Ahora hay que compilar el archivo usando dtc.

dtc -O dtb -o BB-SPI0-01-00A0.dtbo -b 0 -@ BB-SPI0-01-00A0.dts

Si no se ha obtenido ningún error, se procede a copiar el archivo a /lib/firmware

sudo cp BB-SPI0-01-00A0.dtbo /lib/firmware/

Para poder usar SPIDEV hay que habilitar el device tree overlay

sudo su
cd /lib/firmware
echo BB-SPI0-01 > /sys/devices/bone_capemgr.*/slots

Comprobar que se habilito SPI0

cat /sys/devices/bone_capemgr.*/slots
ls /dev/spidev*
ls /sys/bus/spi/devices/

Con el comando cat se obtiene lo siguiente:

 0: 54:PF---
 1: 55:PF---
 2: 56:PF---
 3: 57:PF---
 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
 5: ff:P-O-- Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
 6: ff:P-O-L Bone-Black-HDMIN,00A0,Texas Instrument,BB-BONELT-HDMIN
 7: ff:P-O-L Override Board Name,00A0,Override Manuf,BBB-LCNC-MF5
 8: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-SPI0-01

Usando ls en "/dev/spidev*":

/dev/spidev1.0  /dev/spidev1.1

Usando ls en "ls /sys/bus/spi/devices/":

spi1.0  spi1.1
   
Con lo anterior se verifica que SPI0 se puede usar con cs=0 y cs=1 y se ha cargado correctamente. Si se hubiese cargado SPI1 los valores serían spi2.0 y spi2.1.

El siguiente link facilita la información del dts de SPI0 y SPI1 -> Adafruit Overlays.

Para no repetir el paso anterior cada vez que se reinicia la Beaglebone Black, hay que habilitar SPI a través del script principal de Machinekit. Asi cuando se use Machinekit se exportará de forma automática.

# Make sure required device tree overlay(s) are loaded
for DTBO in BBB-LCNC-MF5 BB-SPI0-01; do

 if grep -q $DTBO $SLOTS ; then
  echo $DTBO overlay found
 else
  echo Loading $DTBO overlay
  sudo -A su -c "echo $DTBO > $SLOTS" || dtbo_err
  sleep 1
 fi
done;

BBB-LCNC-MF5 es mi device tree overlay personalizado para poder ejecutar Machinekit con pantallas LCD. Revisar el siguiente link para poder utilizar mi DTO personalizado BBB-LCNC-MF5.
   
Nota: Otra opción es hacer que reinicie la Beaglebone Black con el SPI que se necesite, revisar el siguiente link DTO LCD7, al final se explica. En futuros tutoriales se explicará como cargar toda la información de los device tree overlays desde una memoria EEPROM para que se configure los GPIO y demás funciones desde el arranque de la BBB.

No hay comentarios.:

Publicar un comentario