nopnop2002 / Arduino-STM32-CAN

Can Example for Arduino Core STM32
210 stars 53 forks source link

Sending CAN fails #19

Closed maxkr2 closed 4 years ago

maxkr2 commented 4 years ago

Hi, great work! I successful can receive can-messages but if I send a message I get the error "Send fail" on serial interface and nothing seems to be sent. I am working on STM32F103/ SN65HVD230. Do have an idea why? Termination resistor seems not the reason. Same can-bus with ESP32 is also working.

Kind regards, Max

nopnop2002 commented 4 years ago
  1. Change the transceiver to 5V. You need to drive STM32 at 5V.

  2. Make the STAB cable as short as possible.

  3. Change terminator register value.

   +----------+ +----------+ +----------+ 
   |STM32F103 | |STM32F103 | |   ESP32  | 
   |          | |          | |          | 
   |          | |          | | 21    22 | 
   +----------+ +----------+ +----------+ 
     |      |     |      |     |      |----->as short as possible 
     |      |     |      |     |      |   
   +----------+ +----------+ +----------+ 
   | D      R | | D      R | | D      R | 
   |  VP230   | |  MCP2551 | |  VP230   | 
   | H      L | | H      L | | H      L | 
   +----------+ +----------+ +----------+ 
     |      |     |      |     |      |   
     |      |     |      |     |      |----->STAB cable
     |      |     |      |     |      |   
 |-+-+------|-----+------|-----+------|-+-| BackBorn H
   >        |            |            | >
   >        |            |            | >
   >        |            |            | >
 |-+--------+------------+------------+-+-| BackBorn L

      -^^^-:Terminaror register

You may know the cause.

In my environment, I get an error when the terminating resistor is 120 ohms.

The solution was to change the terminating resistance from 120 ohms to 150 ohms.

maxkr2 commented 4 years ago

Thanks a lot for the quick reply! I guess there is a dependency between serial (on PA9/PA10) and CANInit(CAN_100KBPS, 0); (i.e. on PA11/PA12): Yesterday in my setup() I first initialized CANInit as mentioned above and then serial with Serial.begin(115200). Sending and receiving via serial was possible. Today I modified code and Serial.begin() is now above CANInit. And I got no reaction on Serial.available() / Serial.read() if I send data to the STM32 - but I still get data from STM32 via serial. Might this the reason of the initial problem sending data via CAN fails, because something is overwritten by initializing the serial? I sent data only triggered by Serial.read()-events, so I will try to send can-messages with a delay automatically, but I guess it will work if I change init-order again.

Additional comment on May, 4th: I had no luck with automated sending can-messages. I get still the same error. Because of USB there is a pullup resistor at PA12, is this a problem for the can-driver?

nopnop2002 commented 4 years ago

If you change to 5V transceiver, you may know the cause.

In my experience, 3.3V transceivers require very accurate termination resistors.

maxkr2 commented 4 years ago

Thank you! I connected SN65HVD230 to 5V because according datasheet's max ratings it seems to be allowed - PA11/12 are 5V tolerant, STM32 is already running at 5V: But still had no luck. As I told in the beginning, I had no problems with the same configuration @3V3 with an ESP32 at the same CAN bus (with around 30 other nodes) - but its not the same SN65HVD230. Maybe I will additionally try it with the same (good known) device.

But this does not explain why I get no events on serial if I initialize Serial.begin before CANInit. Do you have an idea?

nopnop2002 commented 4 years ago

I have several F405 boards. Some of them work with the SN65HVD230(3.3V), but some of them only work with the MCP2551(5V). I don't know why. The internal resistance of the port may be affecting.

But this does not explain why I get no events on serial if I initialize Serial.begin before CANInit. Do you have an idea?

Does the serial event occur if the CAN port is remapped? By default, PA11 is CTS and PA12 is RTS. May be related to serial events.

  bool ret = CANInit(CAN_1000KBPS, 0);  // CAN_RX mapped to PA11, CAN_TX mapped to PA12
  //bool ret = CANInit(CAN_1000KBPS, 2);  // CAN_RX mapped to PB8, CAN_TX mapped to PB9
  //bool ret = CANInit(CAN_1000KBPS, 3);  // CAN_RX mapped to PD0, CAN_TX mapped to PD1
maxkr2 commented 4 years ago

Weird, ok I'll try a MCP2551.

Not sure what you mean, but with: Serial.begin(115200); bool ret = CANInit(CAN_100KBPS, 0); ...I get no event if data is sent from computer to serial. In this case I get events: bool ret = CANInit(CAN_100KBPS, 0); if (!ret) while(true); Serial.begin(115200);

Neither receving CAN-message nor sending serial data to my computer is a problem.

nopnop2002 commented 4 years ago

Try this about the Serial event.

Serial.begin(115200);
bool ret = CANInit(CAN_100KBPS, 2);

CAN_RX is PB8 of STM32F103. CAN_TX is PB9 of STM32F103.

maxkr2 commented 4 years ago

This is great! Thank you! Serial issue is solved by changing setting as shown above. Still the other problem persists. After sending a CAN-message by pressing a key on my console receving of CAN-messages fails until reset of the STM32F103. But this might the problem as described from you according the 3V3 device. I will have to find a MCP2551.

nopnop2002 commented 4 years ago

Serial issue is solved by changing setting as shown above.

It's a good news.

Please show me picture of your SN65HVD230.

maxkr2 commented 4 years ago

Thank you for your patience and help. I will send an additional picture. But it seems it is indeed a problem of my SN65HVD230: I tried another one and could not send data. So I tried them on another ESP32, but these devices are only able to receive. Same stub length, same code (of the two ESP32s). But only my older "reference"-ESP32 is working fine at the same stub.

Update (added picture): SN65HVD230_VP230 Resistor R2 unsoldered because device is connected via a stub. I also tried to tie Rs directly to ground but on one chip I neither can send nor receive now (damaged?), the other one still receives data from CAN but does not send in any combination (ESP32/ STM32)...

I will try to get some MCP2562 @5V with IO-level to 3V3.

nopnop2002 commented 4 years ago

Thank you for the photo.

I own the same one. Try External 150Ω as the termination resistor. (Between CAN-H and CAN-L)


You can use 5V transceiver without level shift.

Because these pins are all 5V tolerant. PA11 PA12 PB8 PB9

http://www.handsonembedded.com/stm32f103-spl-tutorial-3/

maxkr2 commented 4 years ago

You are right. For STM32 MCP2561 would be ok, but for general purpose (i.e. ESP32) I will use MCP2562. Hm, I am on a stub line so I shouldn't need a termination? As I told it is an already existing (and working) CAN-bus with around 30 nodes and around 250m length. Replacing the two resistors is the last thing I want to do.

Sorry, I have another question: Both SN65HVD230 and MCP256x have a standby/ low power function by Rs/ standby-pin. Is it supported by your lib? Receving (incoming CAN-messages) seems to be possible in standby-mode.

nopnop2002 commented 4 years ago

Both SN65HVD230 and MCP256x have a standby/ low power function by Rs/ standby-pin. Is it supported by your lib?

No

maxkr2 commented 4 years ago

Hi again, I got my MCP2562 today and tried it right now. Unbelievable but sending works fine.

Now I have some kind of bit flapping in data: extended messageid is ok at any time but data flaps between: 00 02 00 20 00 00 00 00 and 01 02 00 20 00 00 00 00 in most cases alternating in some case 2-3 times wrong (first byte always 00) and one time ok. Still a termination issue? But why are the other bits never affected?

nopnop2002 commented 4 years ago

Still a termination issue?

How many ohms do you use?

What if you change the ohme?

maxkr2 commented 4 years ago

Will have to find the both termination resistors first, I guess 120Ohms. This will take some days... As I told all other nodes are working fine (for more than 13 years). And messageid is also ok if I send from STM32/ MCP2562 at any time, only first data byte (maybe bit) changes unexpected - the 7 other bytes are always correct. Also no issue with ESP32 at the same stub.

nopnop2002 commented 4 years ago

I guess 120Ohms. This will take some days..

This is my experience, at 120 ohm I got Send Fail, but at 150 ohm it didn't

I don't know why only first data byte (maybe bit) changes unexpected.

maxkr2 commented 4 years ago

Hi, I added serial.print to CAN send function: Message is sent in the right way but flapping occours already in CAN_tx_msg->data[0] before sending to bus. Not sure if it is important but I use extendend CAN-IDs.

Sorry, my fault! I found problem now: data[0] was uninitialized in my function that prepares CAN-messages because it was not set (due to an error in my code I used data[1] twice). Everything is ok now! Thank you again for you support! You can close this issue!

nopnop2002 commented 4 years ago

Everything is ok now! Thank you again for you support! You can close this issue!

It's a good news.