sending data over CAN from teensy

slythy

Active member
I am using the improved flex can library and I have it reading Messages fine using

Code:
   FRWJCAN =msg.buf[2]*256 +msg.buf[3];
      if (FRWJCAN> 32768)
        {
         FRP = (FRWJCAN- 65536)*1.00;
        }
      else
        {
         FRP = FRWJCAN*1.00;
        }

to read a specific can message and wrapping it if it goes negative.

What i want to do is send internal temp ( of the teensy3.6 on any CAN id)

any ideas of how i can do that? I am using SN65HVD230D transceivers.

Thank you!
 
You mean like the sending struct?

Code:
CAN_message_t msg;
msg.id = 0x123;
msg.flags.extended = 0;
msg.len = 8;
msg.buf[0] = myTemperature;
Can0.write(msg);

As for keeping a value positive, you can use abs()

Code:
abs(-10.6);
abs(18);

Output:
Code:
10.6
18
 
You mean like the sending struct?

Code:
CAN_message_t msg;
msg.id = 0x123;
msg.flags.extended = 0;
msg.len = 8;
msg.buf[0] = myTemperature;
Can0.write(msg);

As for keeping a value positive, you can use abs()

Code:
abs(-10.6);
abs(18);

Output:
Code:
10.6
18

Hey i have copy and pasted that code and i dont get any value at all im assuming its big endian which means the start bit is 8

Do i need the CAN_message_t msg; if its called up earlier in the packet? I dont get any errors or anything but I just dont get anything on my logger side.

Any ideas?
 
It should be sent fine. What does mailboxStatus() display?
Are you using IFCT or FlexCAN_T4?
You have proper terminations on the CAN endpoints?
 
Last edited:
I dont have any idea on the mailbox status as i cant currently send to it because we are using it for testing over the next couple days and its working fine for the test as is.

I am using IFCT

The thing i am trying to do is send teensy cpu temp over CAN to monitor temp as it has overheated in the past.

I have the termination correct because I am able to see values on the teensy that I send over CAN too it I just dont know how to send it or its not sending properly.

I will try and post code tonight to try and show you what i got going on. It compiles fine and its exactly what you wrote so im unsure as to why its not working.
 
Code:
#include <IFCT.h>
#define qBlink() (digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) ))
#include <InternalTemperature.h>
InternalTemperature temperature;

// variable declaration ************************
int TempCount = 0;


void setup() {
 Serial.begin(9600);
  //**** Setting pin outputs

  delay(10000);



  //******* CAN SETUP *****************
  pinMode(28, OUTPUT); // for the transceiver enable pin
  digitalWrite(28, LOW); // Low for HIGH speed
  Can0.setTX(ALT); // for pin 29
  Can0.setRX(ALT); // for pin 30
  Can0.setBaudRate(1000000); // matches PI System
  Can0.enableFIFO(); // First in first out CAN style


}

void loop() 
{

  CAN_message_t msg;
  if ( Can0.read(msg))
  {
    digitalWrite(LED_BUILTIN, HIGH);


    if (msg.id == 613) // 265 HEX 
    {
      FCAN = msg.buf[0] * 256 + msg.buf[1];
      if (FCAN > 32768)
      {
        F = (FCAN - 65536) / 100.00;
      }
      else
      {
        F = FCAN / 100.00;
      }
   }
  

    // Displays internal temp of Teensy
    
    if (TempCount >= 1000)
    {
      Serial.print("Temperature: ");
      Serial.print(temperature.readTemperatureC(), 1);
      Serial.println("°C");
      CAN_message_t msg;
      msg.id = 0x617;
      msg.flags.extended = 0;
      msg.len = 8;
      msg.buf[0] = temperature.readTemperatureC();
      Can0.write(msg);
      TempCount = 0;
    }

    TempCount++;
    
  }
  else
  {
    digitalWrite(LED_BUILTIN, LOW);
  }

So I just relized in my If can read is my can send, do I need to do that in my else outside of that loop? or can i do it how I have it?

@tonton81
 
Yes that means it will never send unless you keep receiving that frame until tempcount hits target, intentionaly? If not, take it out of the read statement
 
Yes that means it will never send unless you keep receiving that frame until tempcount hits target, intentionaly? If not, take it out of the read statement

Ok so I’ll pop that out of that read statement and do another statement that if the counter get too 1000 then do that write. I just dont want it to send at 10khz for a temp signal so making it update at 1hz is more than enough.

So hopefully that will work. If i just copy your statement it should just be plug and play correct?
 
You can use millis() to time it at once per second:

Code:
static uint32_t resend = millis();
if ( millis() - resend > 1000 ) {
  // send CAN frame code here
  resend = millis();
}
 
You can use millis() to time it at once per second:

Code:
static uint32_t resend = millis();
if ( millis() - resend > 1000 ) {
  // send CAN frame code here
  resend = millis();
}

Thanks for this, I have been trying to figure out how to send a 16bit message. I need to change the buffer to 0 and 1 correct and then go from there? any chance you have an example of what i would do there? is it buffer [0]*256+ [1]? or something like that?

Code:
      Serial.print("Temperature: ");
      Serial.print(temperature.readTemperatureC(), 1);
      Serial.println("°C");
      CAN_message_t msg;
      msg.id = 0x617;
      msg.flags.extended = 0;
      msg.len = 8;
      msg.buf[0] = temperature.readTemperatureC();
      Can0.write(msg);
      TempCount = 0;
Thanks,
 
16 to 8:
uint16_t buffer16 = 0x1234;
buffer8[0] = (uint8_t)(buffer16 >> 8)
buffer8[1] = (uint8_t) (buffer16)
8 to 16
(uint16_t)buffer8[0] << 8 | buffer8[1]
 
16 to 8:
uint16_t buffer16 = 0x1234;
buffer8[0] = (uint8_t)(buffer16 >> 8)
buffer8[1] = (uint8_t) (buffer16)
8 to 16
(uint16_t)buffer8[0] << 8 | buffer8[1]


Code:
      CAN_message_t msg;
      msg.id = 0x617;
      msg.flags.extended = 0;
      msg.len = 16;
      (uint16_t)buffer8[0] << 8 | buffer8[1] = temperature.readTemperatureC();
      Can0.write(msg);

So is that what I would do? sorry i kinda need spoon fed, I really appreciate all the help.

Basically with the temp I am trying to get decimal places and currently the 8bit works but limited to data size.
 
no temperature is 16 bits i gather so, save it first:
Code:
uint16_t temp = temperature.readTemperatureC();

then store it in the CAN frame, example, the first 2 bytes

Code:
msg.buf[0] = temp >> 8;
msg.buf[1] = temp

now itll send your temperature over CAN
 
no temperature is 16 bits i gather so, save it first:
Code:
uint16_t temp = temperature.readTemperatureC();

then store it in the CAN frame, example, the first 2 bytes

Code:
msg.buf[0] = temp >> 8;
msg.buf[1] = temp

now itll send your temperature over CAN


ok so

Code:
uint16_t temp = temperature.readTemperatureC();

      CAN_message_t msg;
      msg.id = 0x617;
      msg.flags.extended = 0;
      msg.len = 8;
      msg.buf[0] = temp >> 8
      Can0.write(msg);

      CAN_message_t msg;
      msg.id = 0x617;
      msg.flags.extended = 0;
      msg.len = 8;
      msg.buf[1] = temp 8
      Can0.write(msg);

Is there a way to send is as one like

Code:
      CAN_message_t msg;
      msg.id = 0x617;
      msg.flags.extended = 0;
      msg.len = 16;
      msg.buf[0] = temp >> 8
      msg.buf[1] = temp 8
      Can0.write(msg);

?


again thanks for all the help!
 
yeah but i realized you are using floats. the buf is correct for 16 bits but floats are 32 bits. msg.len should be 8 bytes max, 16 is wrong. you are using 2 bytes for 16 bits, so you'll need 4 bytes for 32bits float

Code:
msg.len = 4;
float temp = temperature.readTemperatureC();
msg.buf[0] = temp >> 24;
msg.buf[1] = temp >> 16;
msg.buf[2] = temp >> 8;
msg.buf[3] = temp;
 
yeah but i realized you are using floats. the buf is correct for 16 bits but floats are 32 bits. msg.len should be 8 bytes max, 16 is wrong. you are using 2 bytes for 16 bits, so you'll need 4 bytes for 32bits float

Code:
msg.len = 4;
float temp = temperature.readTemperatureC();
msg.buf[0] = temp >> 24;
msg.buf[1] = temp >> 16;
msg.buf[2] = temp >> 8;
msg.buf[3] = temp;



ahhhhh i was under the empression length was bits..... that makes more sense.....

I will turn the float into a 16bit message after it gets the value. since I will want to just multiply it by 100 or something.

Again thanks for all the help.
 
Back
Top