Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 16 of 16

Thread: sending data over CAN from teensy

  1. #1

    sending data over CAN from teensy

    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!

  2. #2
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    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

  3. #3
    Quote Originally Posted by tonton81 View Post
    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?

  4. #4
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    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 by tonton81; 02-26-2020 at 05:57 PM.

  5. #5
    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.

  6. #6
    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

  7. #7
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    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

  8. #8
    Quote Originally Posted by tonton81 View Post
    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 Ill 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?

  9. #9
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    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();
    }

  10. #10
    Quote Originally Posted by tonton81 View Post
    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,

  11. #11
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    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]

  12. #12
    Quote Originally Posted by tonton81 View Post
    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.

  13. #13
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    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

  14. #14
    Quote Originally Posted by tonton81 View Post
    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!

  15. #15
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    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;

  16. #16
    Quote Originally Posted by tonton81 View Post
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •