Go Down

Topic: CAN line doesn't update: MCP2515, mcp_can.h (Read 196 times) previous topic - next topic

Henradrie

Hi All,

I'm experimenting with CAN and getting behavior I don't understand.

The package sent doesn't seem to be changing based on measurements from sensors. It repeats the same sequence over and over. I am also using a delay(1000) in my sketch so I'm thinking that it should only send 1 transmission per second but my scope shows otherwise. The package is sent multiple times.

I loaded up one of the example sketches called send and it had the same behavior.

Could this be a problem with code or not knowing how to use an oscilloscope? Is there something I am missing? My goal is to use CAN to transmit sensor values to a base node for logging from many different measurement nodes.

Equipment is:
Uno
seeed studio CAN shield
Owon oscilloscope VDS10221
<mcp_can.h>          //https://github.com/Seeed-Studio/CAN_BUS_Shield

Code: [Select]

#include <Adafruit_INA219.h>  //https://github.com/adafruit/Adafruit_INA219/archive/master.zip
#include <Adafruit_LIS3DH.h>  //https://github.com/adafruit/Adafruit_LIS3DH
#include <Adafruit_Sensor.h>  //https://github.com/adafruit/Adafruit_Sensor
#include <SPI.h>              //standard library
#include <mcp_can.h>          //https://github.com/Seeed-Studio/CAN_BUS_Shield
#include <Wire.h>             //standard library
#include <DHT.h>              //https://github.com/adafruit/DHT-sensor-library/archive/master.zip

//individual address
const int local  = 0x0a; // 2^11 combinations 0x00 to 0x09 reserved for master

const int SPI_CS_PIN = 9;
MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin for CAN board
unsigned char output[8] = {0, 0, 0, 0, 0, 0, 0, 0};  //buffer used to send information
 
Adafruit_INA219 ina219;

#define DHTPIN 7
#define DHTTYPE DHT22   // DHT 22
DHT dht(DHTPIN, DHTTYPE);

// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is (digital pin 7)
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor
float temp = 0;
float humidity = 0;

float z;
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//
// The setup() function runs once each time the micro-controller starts
void setup()
{
Serial.begin(19200);
ina219.begin();  // Initialize board (default address 0x40)

dht.begin(); //start dht sensor

if (! lis.begin(0x18)) {   // change this to 0x19 for alternative i2c address
    Serial.println("Couldn't start");
    while (1);
}
Serial.println("LIS3DH found!");
lis.setRange(LIS3DH_RANGE_2_G);

while (CAN_OK != CAN.begin(CAN_10KBPS))              // init can bus : baud rate = 500k
{
    Serial.println("CAN BUS Shield init fail");
    Serial.println(" Init CAN BUS Shield again");
    delay(100);
}
}

// Add the main program code into the continuous loop() function
void loop()
{
  // Voltage start
  float shuntvoltage = 0;
  float busvoltage = 0;
  float current_mA = 0;
  float loadvoltage = 0;
  unsigned char loadvoltageC= 0;
  unsigned char currentC= 0;
 
  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  loadvoltage = busvoltage + (shuntvoltage / 1000);
  loadvoltageC = char(2 * loadvoltage);
  currentC = char(current_mA / 10);
  Serial.print("load voltage "); Serial.print(loadvoltage);
  Serial.print(", load voltage out "); Serial.print(loadvoltageC);
  Serial.print(", current in mA "); Serial.print(current_mA);
  Serial.print(", current out "); Serial.print(currentC);
  //Voltage end
 
  //DHT start
  temp = readTemp();
  humidity = readHumidity();
  unsigned char tempC = 0;
  unsigned char humidityC = 0;
  tempC = char(2 * (temp +40));
  humidityC = char(humidity);
  Serial.print(", Temp celcius: "); Serial.print(temp);
  Serial.print(", Temp out "); Serial.print(tempC);
  Serial.print(", Humidity: ");   Serial.print(humidity);
  Serial.print(", Humidity out "); Serial.print(humidityC);
  //DHT end
   
  // Accelerometer start
  lis.read();
  unsigned char zC = 0;
  //Serial.print(lis.z);
  //Serial.print(", Z Acceleration in G ");
  z = lis.z / 16383.0; //scales output to G, where G is the force of gravity
  zC = char( 64 * z + 128);
  Serial.print(", acc z only "); Serial.print(z);
  Serial.print(", acc out "); Serial.println(zC);
  //Accelerometer end
 
  //send to base node start
  //output[0] = loadvoltageC;
  //output[1] = currentC;
  unsigned char output2[8];
  output2[2] = tempC;
  output2[3] = humidityC;
  //output[4] = zC;
  //output[5] future use
  //output[6] future use
  //output[7] future use
  CAN.sendMsgBuf(local, 0, 8, output2);
  delay(1000);
}

float readTemp(){
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float t = dht.readTemperature();
  float tf = t * 1.8 +32;  //Convert from C to F
  return   t;
}

float readHumidity(){
  float h = dht.readHumidity();
  return h;
}

mikb55

Replace the sensor values with dummy values that increment with each loop. Check that the CAN data changes as expected.

Are you packing all the measurements into one 8 byte message for a good reason?
The 'normal' way of sending CAN data is to use a single message ID per value which allows you to preserve the resolution of each measurement.

Henradrie

I did something similar to the test you mentioned.

I tested the below code in the main loop

unsigned char a[8] = {0, 0, 0, 0, 0, 0, 0, 0};
CAN.sendMsgBuf(local, 0, 8, a);
unsigned char b[8] = {255, 255, 255, 255, 255, 255, 255, 255};
CAN.sendMsgBuf(local, 0, 8, b);
delay(1000);

It should send all 0's then all 1's right after each other but instead it keeps sending 0's.

There are a few reasons why I'm packing the data into one message. The biggest is to get something completed right away even if it isn't fully correct. We also have over 100 identical sensors on the network.

Henradrie

I figured out a solution but it's not optimal.

I switched the Seeed studio library to this one
#include <CAN.h>              //https://github.com/sandeepmistry/arduino-CAN


Henradrie

I sent a support email to seeed studios though and this is the response I got back.

Here is the sending code i use and i use the receive code in library.

// demo: CAN-BUS Shield, send data
// loovee@seeed.cc

#include <mcp_can.h>
#include <SPI.h>

// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;

MCP_CAN CAN(SPI_CS_PIN);                                   // Set CS pin

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

    while (CAN_OK != CAN.begin(CAN_500KBPS))             // init can bus : baudrate = 500k
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println(" Init CAN BUS Shield again");
        delay(100);
    }
    Serial.println("CAN BUS Shield init ok!");
     unsigned char a[8] = {0, 0, 0, 0, 0, 0, 0, 0};
    CAN.sendMsgBuf(0x00, 0, 8, a);
    delay(1000);
    unsigned char b[8] = {255, 255, 255, 255, 255, 255, 255, 255};
    CAN.sendMsgBuf(0x00, 0, 8, b);
    delay(1000);
}


void loop()
{

}

Here is the output.

CAN BUS Shield init ok!
-----------------------------
Get data from ID: 0x0
0 0 0 0 0 0 0 0
-----------------------------
Get data from ID: 0x0
FF FF FF FF FF FF FF FF

dzid_

Same issue here.

It seems to me that it might be SPI communication interrupted. Because I am getting the same effect when I disconnect SPI cables - the MPC2515 still transmits the same constant.

Go Up