MCP2515 debug

Ciao a tutti!
Ho qualche problema con un modulo MCP2515 utilizzato con il chip della termocoppia MAX31855.
Tutti i circuiti integrati funzionano tramite SPI, ma senza il modulo CAN sono in grado di leggere correttamente la temperatura, non appena inserisco il modulo CAN, tutto va a 0.
La libreria mcp_can_dfs.h ha una funzione di debug, che dovrebbe riportare su monitor seriale il log degli errori, ma così non fà.

LInk libreria

Vorrei eseguire il debug del CAN e ho scritto questo codice:

#include "MAX31855.h"
#include <mcp_can.h>
#include <mcp_can_dfs.h>
#define DEBUG_EN 1
const int doPin = 12;
const int csPin = 10;
const int clPin = 13;
MCP_CAN   CAN0(14);
byte data[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
MAX31855 tc(clPin, csPin, doPin);
SPISettings   max31855_spi(1000000, MSBFIRST, SPI_MODE1);

void setup() 
{
  Serial.begin(115200);
  int rv = CAN0.begin(CAN_500KBPS);   /// <<<<<<<<<<<<<<<<<<<<  does it init properly?
  Serial.println(rv);
  tc.begin();
}

void loop() 
{
  tc.read();
  float value = tc.getTemperature();
  data[1] = round(value/256);
  //data[2] = (fmod(value%256));
  CAN0.sendMsgBuf(0x80, 0, 8, data);
  Serial.println(value, 2);
  delay(100);
}

Purtroppo l’unica cosa che riesco a vedere sul monitor seriale è:

0
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00

Avete qualche consiglio?

Guardando nella libreria (a parte che mcp_can_dfs.h viene incluso già dalla mcp_can.h quindi non serve reincluderla) mi pare che il problema del debug sia nel fatto che tu dovresti definire DEBUG_EN prima di includere la libreria:

#include "MAX31855.h"
#define DEBUG_EN 1
#include <mcp_can.h>
const int doPin = 12;
...

Altrimenti quando compila mcp_can.h non “vede” il simbolo.
Prova e fammi sapere.

Oltre a questo, credo che il problema principale sia nel fatto che per il MAX tu usi i pin 10. 12 e 13, e se stai usando uno shield (non hai specificato esattamente quale CANBUS shield usi, magari con link e come è connesso/configurato) posso immaginare che poiché i pin SPI sono proprio 11, 12 e 13, vanno a “pestarsi i piedi”. Devi verificare i pin usati dal CAN e nel caso cambiare quelli per il MAX.

Breve riassunto di cosa è successo nel frattempo…

Innanzi tutto lavoro con un Arduino Nano V3.3

Il problema principale è la comunicazione SPI.
La board CAN ha un quarzo a 8MHz mentre il Nano lavora a 16MHz.
Con questo topic ho pensato di aver trovato la soluzione invece nulla…

Allora sono andato per step.
Ho configurato la sola lettura della temperatura e funziona.
Non appena inserisco il CAN smette di funzionare.

Ho provato con questo codice:

#include <mcp_can.h>
#include <SPI.h>
#include "MAX31855.h"
const int dataPin = 12;
const int sckPin = 13;
const int csPin = 10;

MAX31855 thermocouple(sckPin,csPin,dataPin);
MCP_CAN CAN0(14);                                      // Set CS to pin 14

byte stmp[8] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

void setup()
{
  Serial.begin(115200);
  // init can bus, baudrate: 500k
  
  thermocouple.begin();
}

  
void loop()
{
  thermocouple.read();
  float value=thermocouple.getTemperature();
  stmp[0]=(round(value/256));  
  if(CAN0.begin(CAN_500KBPS, MCP_8MHz) == CAN_OK) Serial.print("can init ok!!\r\n");
  else Serial.print("Can init fail!!\r\n");
  // send data:  id = 0x00, standrad flame, data len = 8, stmp: data buf
  CAN0.sendMsgBuf(0x80, 0, 8, stmp);  
  Serial.println(value, 2);
  delay(100);                       // send data per 100ms
}

La prima lettura tutto parrebbe funzionare, dopo di che il buio.

La cosa “divertente” è che sembra addirittura che non sovrascriva le impostazioni SPI ogni ciclo del loop!!

Quello che ottengo in output è questo:

Le uniche “linee rosse” che riporta il compilatore sono le seguenti, e soprattutto le riporta solo la prima volta. Nonostante questo compila correttamente.
Le compilazioni successive non danno alcun problema.

C:\Users\fabio\Documents\Arduino\libraries\MCP2515_lib-master\mcp_can.cpp: In member function 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)':
C:\Users\fabio\Documents\Arduino\libraries\MCP2515_lib-master\mcp_can.cpp:828:1: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
C:\Users\fabio\Documents\Arduino\libraries\MCP2515_lib-master\mcp_can.cpp: In member function 'byte MCP_CAN::readMsgBuf(byte*, byte*)':
C:\Users\fabio\Documents\Arduino\libraries\MCP2515_lib-master\mcp_can.cpp:871:1: warning: no return statement in function returning non-void [-Wreturn-type]
}
^

Avete qualche idea sul perchè non sovrascriva le impostazioni dell’SPI ad ogni ciclo?

Banfotech:
Avete qualche idea sul perchè non sovrascriva le impostazioni dell'SPI ad ogni ciclo?

Ma scusa, ma tu hai letto quello che ti ho scritto?

Ossia che i pin SPI sono 11 (MOSI), 12 (MISO) e 13 (SCK), e forse pure il 10 (SS), e che tu stai usando proprio quei pin per il sensore?

E hai provato anche ad attivare il debug mettendo la #define prima della #include o no?

PS: a parte che fare CAN.init() nel loop non è mai una buona idea...

Ho provato ad attivare il debug ma non mi da nulla.
L'output è quello riportato nel monitor seriale precedente.

Inoltre questo è lo shield che sto usando per il CAN:

Se non ai pin MISO, MOSI, SCK e CS dove dovrei collegarlo?

La board termocoppia è:

MISO ed SCK sono in comune tra le schede

Fare CAN.init() nel loop mi ha consentito di sovrascrivere il valori del Setup SPI che fa ogni volta la funzione _read della libreria MAX31855.h

Era un test, se lo inserisco nel loop l'output è sempre 0.

Il dubbio nasce proprio da qui.
Fa questa sovrascrittura della configurazione SPI una volta soltanto.

Banfotech:
Ho provato ad attivare il debug ma non mi da nulla.
L'output è quello riportato nel monitor seriale precedente.

Si ma ti avevo detto di provare a mettere la #define prima della #include, mentre l'output precedente era riferito al codice iniziale se ho capito bene.

Inoltre questo è lo shield che sto usando per il CAN:
Se non ai pin MISO, MOSI, SCK e CS dove dovrei collegarlo?
MISO ed SCK sono in comune tra le schede

Ma anche no, la board con la termocoppia mica ha interfaccia SPI!
il problema è secondo me quello che sto cercando di farti capire: se hai un device SPI che usa i pin 10,11,12 e 13, tu NON puoi usare alcun altro device su quei pin (a meno che non sia SPI anche lui, in tal caso avrai MISO, MOSI e CLK in comune ma SS diverso).

Quindi devi semplicemente spostare la termocoppia per usare i suoi 3 pin di comunicazione (DO, CS, CLK) tra quelli che hai liberi, tutto qui.

Ma come sarebbe che non ha l’interfaccia SPI? :o

Ti riporto il datasheet per chiarezza:

Datasheet

Pagina 1, “Simple SPI-Compatible Interface (Read-Only)”

Se fosse che non hanno l’interfaccia SPI come potrebbe funzionare questo codice?

#include "MAX31855.h"

// note: pins are slightly different than other examples!
const int dataPin  = 12;
const int clockPin = 13.;

MAX31855 sensors[] =
{
  MAX31855(clockPin, 10, dataPin),
  MAX31855(clockPin, 9, dataPin),
  MAX31855(clockPin, 3, dataPin)
};

const uint8_t sensorCount = sizeof(sensors) / sizeof(MAX31855);

void setup()
{
  Serial.begin(115200);
  Serial.print("Start max31855_array.ino : ");
  Serial.println(MAX31855_VERSION);
  Serial.println();

  Serial.println(sensorCount);

  for (int i = 0; i < sensorCount; i++)
  {
    sensors[i].begin();
  }
}

void loop()
{
  Serial.print("\tTime:\t");
  Serial.println(millis());

  for (int i = 0; i < sensorCount; i++)
  {
    int status = sensors[i].read();
    if (status != STATUS_OK)
    {
      Serial.print(i);
      Serial.print("\tstatus:\t");
      Serial.println(status);
    }
    else
    {
      float temp = sensors[i].getTemperature();
      Serial.print(i);
      Serial.print("\ttemp:\t");
      Serial.println(temp);
    }
  }
  Serial.println();

  delay(1000);
}

Invece la lettura viene effettuata correttamente su entrambi i sensori!

Forse non ci stiamo capendo o mi sono spiegato male… Riesci a farmi un esempio di codice, partendo da quello postato qui sopra su come configureresti tu i pin?

Diciamo che hai almeno in parte ragione, nel senso che essendo una comunicazione seriale (in sola lettura in questo caso) è “SPI-compatibile” visto che è citato nel datasheet, ma non ho mai fatto collegamenti di questo tipo per cui se hai anche un altro device SPI da collgare insieme, tanto più se attualmente non ti funzionano correttamente insieme significa che c’è qualcosa che va in conflitto, quindi io inizierei ad usare altri pin.

Ad esempio collegando DO, CS e CLK ai pin D3, D4 e D5, come vedi nell’esempio “serialthermocouple” che trovi nella libreria stessa.

/***************************************************
  This is an example for the Adafruit Thermocouple Sensor w/MAX31855K
  Designed specifically to work with the Adafruit Thermocouple Sensor
  ----> https://www.adafruit.com/products/269
  These displays use SPI to communicate, 3 pins are required to
  interface
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!
  Written by Limor Fried/Ladyada for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include <SPI.h>
#include "Adafruit_MAX31855.h"

// Default connection is using software SPI, but comment and uncomment one of
// the two examples below to switch between software SPI and hardware SPI:

// Example creating a thermocouple instance with software SPI on any three
// digital IO pins.
#define MAXDO   3
#define MAXCS   4
#define MAXCLK  5

// initialize the Thermocouple
Adafruit_MAX31855 thermocouple(MAXCLK, MAXCS, MAXDO);

// Example creating a thermocouple instance with hardware SPI
// on a given CS pin.
//#define MAXCS   10
//Adafruit_MAX31855 thermocouple(MAXCS);

void setup() {
  Serial.begin(9600);

  while (!Serial) delay(1); // wait for Serial on Leonardo/Zero, etc

  Serial.println("MAX31855 test");
  // wait for MAX chip to stabilize
  delay(500);
  Serial.print("Initializing sensor...");
  if (!thermocouple.begin()) {
    Serial.println("ERROR.");
    while (1) delay(10);
  }
  Serial.println("DONE.");
}

void loop() {
  // basic readout test, just print the current temp
   Serial.print("Internal Temp = ");
   Serial.println(thermocouple.readInternal());

   double c = thermocouple.readCelsius();
   if (isnan(c)) {
     Serial.println("Something wrong with thermocouple!");
   } else {
     Serial.print("C = ");
     Serial.println(c);
   }
   //Serial.print("F = ");
   //Serial.println(thermocouple.readFahrenheit());

   delay(1000);
}

Quando questo ti funziona, usi quei tre pin nel tuo programma e vedi se stavolta ti funziona tutto (come penso):

const int doPin = 3;
const int csPin = 4;
const int clPin = 5;
...
MAX31855 tc(clPin, csPin, doPin);

Sono d’accordo con @docdoc, infatti si trovano anche esempi di uso di quel modulo (o simile) che non usa i pin spi hw
https://www.electroschematics.com/handheld-digital-thermometer-using-arduino/

Grazie a tutti, problema risolto utilizzando pin diversi.

Bene, lo immaginavo.. :wink:
Io sospetto che la causa sia in questa istruzione:

SPISettings max31855_spi(1000000, MSBFIRST, SPI_MODE1);

Mi pare probabile che MAX31855 abbia impostazioni diverse per almeno uno di questi tre parametri, per cui non possono stare sullo stesso bus perché "parlano" lingue diverse.