bitWrite help needed

I'm using a Teensy to read CAN messages and I'm wanting to then transmit the message on another CAN ID.

On 0x319 I'm reading bits 7,6,5 and 4 on Byte 0.

I'm then wanting to transmit this on 0x35C again on Byte 0 as the same bits. (I will also be wanting to change the bits to be written to so hence asking this way).

I've made an attempt but somehow I'm not writing it correctly. Help please.

#include <FlexCAN_T4.h>

FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2;

CAN_message_t msgcan1;
CAN_message_t msgcan2;

CAN_message_t txmsg1;
CAN_message_t txmsg2;



char msgString[128];                                            // Array to store serial string

long unsigned int rxId;

int ChgEn;
int DisEn;
int ReqForceChg1;
int ReqForceChg2;


void setup()
{

  Serial.begin(115200);                         // start serial for output

  can1.begin();                                 //CAN 1
  can1.setBaudRate(500000);
  can1.setMBFilter(ACCEPT_ALL);
  can1.distribute();
  can1.mailboxStatus();

  can2.begin();                                 //CAN 2
  can2.setBaudRate(500000);
  can2.setMBFilter(ACCEPT_ALL);
  can2.distribute();
  can2.mailboxStatus();

}

void loop()
{
  if (can1.read(msgcan1))
  {
    rxId = (msgcan1.id);
    {
      Serial.print ("CAN 1   ");
      Serial.print("MB: "); Serial.print(msgcan1.mb);
      Serial.print("  OVERRUN: "); Serial.print(msgcan1.flags.overrun);
      Serial.print("  ID: 0x"); Serial.print(msgcan1.id, HEX );
      Serial.print("  EXT: "); Serial.print(msgcan1.flags.extended );
      Serial.print("  LEN: "); Serial.print(msgcan1.len);
      Serial.print("  DATA: ");

      for ( uint8_t i = 0; i < msgcan1.len ; i++ )
      {
        sprintf(msgString, " 0x%.2X", msgcan1.buf[i]);
        Serial.print(msgString);
      }
      Serial.println();
    }


    if (rxId == 0x319)
    {
      ChgEn = bitRead(msgcan1.buf[0], 7);
      DisEn = bitRead(msgcan1.buf[0], 6);
      ReqForceChg1 = bitRead(msgcan1.buf[0], 5);
      ReqForceChg2 = bitRead(msgcan1.buf[0], 4);

      unsigned int value = 0xFFFF;

      txmsg2.buf[0] = bitWrite(value, 7, ChgEn) * 64 + bitWrite(value, 6, DisEn) * 32 + bitWrite(value, 5, ReqForceChg1) * 16 + bitWrite(value, 5, ReqForceChg2) * 8;
      txmsg2.buf[1] = 0x00;


      txmsg2.id = 0x35C;
      txmsg2.len = 2;
      can2.write( txmsg2);                                         // send message out on CAN2 interface to SMA

      //319
      Serial.println();
      Serial.print("Charge enable  = ");
      Serial.println(ChgEn);
      Serial.print("Discharge enable  = ");
      Serial.println(DisEn);
      Serial.print("Request Forced Charge 1  = ");
      Serial.println(ReqForceChg1);
      Serial.print("Request Forced Charge 2  = ");
      Serial.println(ReqForceChg2);
      Serial.println();

    }
  }
}
 txmsg2.buf[0] = bitWrite(value, 7, ChgEn) * 64 + bitWrite(value, 6, DisEn) * 32 + bitWrite(value, 5, ReqForceChg1) * 16 + bitWrite(value, 5, ReqForceChg2) * 8;

Please explain what you are trying to do with this line of code bearing in mind that bitWrite() does not return a value

That's what I need help with.

If you want help, explain what lines like this are supposed to do:

 txmsg2.buf[0] = bitWrite(value, 7, ChgEn) * 64 + bitWrite(value, 6, DisEn) * 32 + bitWrite(value, 5, ReqForceChg1) * 16 + bitWrite(value, 5, ReqForceChg2) * 8;
  

I find it much easier to use bitwise logic built into the language. Some examples

char c  = 0; 
c =  (1<<5);  //set bit five of c, the rest to zero
c |= (1<<2); // set bit 2, leaving the rest intact
c  &=  ~(1<<2);  //clear bit 2, leaving the rest intact
c = x & 0x0F; // set c equal to the lower four bits of x

if you want to update txmsg2.buf[0] then that's what you want to have as first parameter of bitWrite()

may be something like

txmsg2.buf[0] = 0xFFFF; // or whatever default value
bitWrite(txmsg2.buf[0], 7, ChgEn);           // set or clear bit 7 based on value of ChgEn
bitWrite(txmsg2.buf[0], 6, DisEn) ;          // set or clear bit 6 based on value of DisEn
bitWrite(txmsg2.buf[0], 5, ReqForceChg1);    // set or clear bit 5 based on value of ReqForceChg1
bitWrite(txmsg2.buf[0], 4, ReqForceChg2;     // set or clear bit 4 based on value of ReqForceChg2

bit numbering starts at 0 for LSb

2 Likes

I've written Bytes before over CAN but never had to write bits so was basing it on reading bits before in another sketch. I can't remember where it came from and I'm struggling to find a good description of how to write bits. I thought I had explained what I was trying to do.

SOH = bitRead(msgcan1.buf[7], 6) * 64 + bitRead(msgcan1.buf[7], 5) * 32 + bitRead(msgcan1.buf[7], 4) * 16 + bitRead(msgcan1.buf[7], 3) * 8 + bitRead(msgcan1.buf[7], 2) * 4 + bitRead(msgcan1.buf[7], 1) * 2 + bitRead(msgcan1.buf[7], 0);

J-M-L Thank you.

I asked

You replied

Sorry, but I don't know what you are trying to do. I thought you could explain

basically he explained that here

➜ he reads the value of 4 bits at position 7,6,5,4
➜ he wants to propagate the same bits and so he seeks to set/clear the bits 7,6,5,4 of another variable

at least that's how I understood it

1 Like

I'm reading data on one CAN bus as 0x319 and then want to transmit it on another CAN bus as 0x35C but want the ability to change individual bits.

I could have done;
txmsg2.buf[0] = msgcan1.buf[0];

but that doesn't give me the ability to change bits and with this particular case on 0x319 Byte 0, bit 0 and bit 1 contain data that I don't want to transmit on to 0x35C

That's working perfectly, many thanks.

glad it helped :slight_smile: