cruz177 Posted May 28, 2020 Report Share Posted May 28, 2020 Hi i am designing arduino based racing dash (teensy) and nextion display I already have all the connection on, I have configured a link to show by can bus (I think I did it well) but I don't know very well how to start with arduino programming I know it is not something very difficult but my experience is quite small with programming Has anyone done something similar? I am currently trying to establish connection, would this be correct? #include <FlexCAN.h> #include <kinetis_flexcan.h> // Specify CAN baudrate FlexCAN CANbus(500000); static CAN_message_t rxmsg; // Link ECU data vars byte indicator[7]; // where to store indicator data float BATTV, AFR, KM/H ; // Números con punto decimal unsigned int MAP, TPS, OILPRESS, RPM, GEAR, OILTEMP, ECT, IAT ; // Números enteros int battvGraphValue = 0; //value for the BATTV progress bar int mapGraphValue = 0; //value for the MAP progress bar int afrGraphValue = 0; //value for the AFR progress bar int rpmGraphValue = 0; //value for the RPM progress bar int tpsGraphValue = 0; //value for the TPS progress bar int iatGraphValue = 0; //value for the IAT progress bar int oilpressGraphValue = 0; //value for the OILPRESS progress bar int oiltempGraphValue = 0; //value for the OILTEMP progress bar int ectGraphValue = 0; //value for the ECT progress bar void setup() { Serial2.begin(9600); Serial2.print("baud=115200"); Serial2.write(0xff); // We always have to send this three lines after each command sent to nextion. Serial2.write(0xff); Serial2.write(0xff); Serial2.end(); // End the serial comunication of baud=9600. Serial2.begin(115200); // Start serial comunication at baud=115200. CANbus.begin(); } Quote Link to comment Share on other sites More sharing options...
Tim D Posted May 28, 2020 Report Share Posted May 28, 2020 Hi, I made a simple dash using an MBED, so there's a lot of similarities I guess? I ended up getting a Picoscope to look at the CAN signals, great for debugging as it decodes the CAN data. Possible ideas you could look at... Can you receive and process the CAN data at 50 Hz? Maybe start at a lower rate ? Have you set the CAN ID in your code to match the Link ID of 1000? For some reason, I found that a CAN speed of 1 Mbps worked best (maybe an MBED timing thing!). During debugging, CAN data such as Gear postion could be useful as you already know what the result should be and it's static. Not sure if any of this helps :-) Quote Link to comment Share on other sites More sharing options...
cruz177 Posted May 28, 2020 Author Report Share Posted May 28, 2020 1 hour ago, Tim D said: Hi, I made a simple dash using an MBED, so there's a lot of similarities I guess? I ended up getting a Picoscope to look at the CAN signals, great for debugging as it decodes the CAN data. Possible ideas you could look at... Can you receive and process the CAN data at 50 Hz? Maybe start at a lower rate ? Have you set the CAN ID in your code to match the Link ID of 1000? For some reason, I found that a CAN speed of 1 Mbps worked best (maybe an MBED timing thing!). During debugging, CAN data such as Gear postion could be useful as you already know what the result should be and it's static. Not sure if any of this helps :-) Thanks for answering all help is good Where in the code do I have to put the canbus ID? (in this case 1000)? Quote Link to comment Share on other sites More sharing options...
Adamw Posted May 28, 2020 Report Share Posted May 28, 2020 You have 3 frames of data all being sent on the same ID, that will not work as the receiving device will have no way of identifying which frame is which. You can do multiple frames using compound ID's in one byte of each frame but that will make your coding more difficult as you wont find many examples of compound CAN frames in any ardruino examples. So I suggest you send just one frame per ID. So for instance Frame 1 = ID 1000. Frame 2 = ID 1010, Frame 3 = ID 1020. Also I suggest just get your code working with one ID/Frame to start with and only add more complexity once you have some data coming through. Quote Link to comment Share on other sites More sharing options...
cruz177 Posted May 28, 2020 Author Report Share Posted May 28, 2020 18 minutes ago, Adamw said: You have 3 frames of data all being sent on the same ID, that will not work as the receiving device will have no way of identifying which frame is which. You can do multiple frames using compound ID's in one byte of each frame but that will make your coding more difficult as you wont find many examples of compound CAN frames in any ardruino examples. So I suggest you send just one frame per ID. So for instance Frame 1 = ID 1000. Frame 2 = ID 1010, Frame 3 = ID 1020. Also I suggest just get your code working with one ID/Frame to start with and only add more complexity once you have some data coming through. Thanks so i will Does setting a value of Frame ID 50 or 1000 make any difference or is it only informative for CANBUS communication? CAN ID of the canbus settings menu that is currently at 1000 is correct or is a specific value recommended? Quote Link to comment Share on other sites More sharing options...
Adamw Posted May 29, 2020 Report Share Posted May 29, 2020 2 hours ago, cruz177 said: Does setting a value of Frame ID 50 or 1000 make any difference or is it only informative for CANBUS communication Dont use frame ID's for now, this will make what I called a compound message earlier and will make your life more difficult. 3 hours ago, cruz177 said: CAN ID of the canbus settings menu that is currently at 1000 is correct or is a specific value recommended? You can choose whatever you like. The main requirement is every message needs it's own ID and no two devices can be sending the same ID. Lower numbers get higher priority when there is a lot of data on a busy bus but that is not going to be a factor in your case. In OEM buses you will find safety critical devices like ABS and DSC will all be high priority ID's, like <100. cruz177 1 Quote Link to comment Share on other sites More sharing options...
Tim D Posted May 29, 2020 Report Share Posted May 29, 2020 There's lots of ways of achieving what you want and I am happy to share my approach which works well. I stream 56 bytes (7 frames) from ECU to dash, then broadcast this data over bluetooth (if laptop is running, the data is logged). I'm guessing you don't have other CAN devices on the same CAN bus as your dash? In this case, the concept of priorities is not that relevant (there won't be any other CAN traffic to contend with). In my MBED dash, I stream 7 frames all on the same CAN ID of 1300 (arbitrary ID). These byes are streamed 'end to end' (as observed on oscilloscope), leaving a lot of time after the last frame to do my processing. All that's required is to write your arduino firmware to recognise the stream. My dash also broadcasts the data wirelessly to my laptop, giving error free datalogging (I chose to stream this at 10 Hz). You are welcome to look at my CAN setup:https://drive.google.com/open?id=1pjCW7otZjlRO3j8JqtsJj-2yhvleHtnw cruz177 1 Quote Link to comment Share on other sites More sharing options...
cruz177 Posted May 29, 2020 Author Report Share Posted May 29, 2020 So this echoed would be correct? He put a 1000 id on steam 1 So I have 3 frames with an id of 110 -120 -130 respectively Each frame has a 7 bit message In the code I have something wrong? Should I report somewhere the ID I'm using? void loop(void) { // Gauge display function gauge_display(); //Look for CAN broadcasts if ( CANbus.read(rxmsg) ) { switch (rxmsg.id) { // Stream 1 case 110: // Frame 1 MAP = (float)(word(rxmsg.buf[1], rxmsg.buf[2])); IAT = (float)(word(rxmsg.buf[3], rxmsg.buf[4])); ECT = (float)(word(rxmsg.buf[5], rxmsg.buf[6])); OILPRESS = (float)(word(rxmsg.buf[7], rxmsg.buf[7])); break; case 120: // Frame 2 OILTEMP = (float)(word(rxmsg.buf[0], rxmsg.buf[0])); // KM/H = (float)(word(rxmsg.buf[1], rxmsg.buf[2])); // GEAR = (float)(word(rxmsg.buf[6], rxmsg.buf[6])); AFR = (float)(word(rxmsg.buf[3], rxmsg.buf[4])); break; case 130: // Frame 3 RPM = (float)(word(rxmsg.buf[0], rxmsg.buf[1])); TPS = (float)(word(rxmsg.buf[2], rxmsg.buf[3])); // BATTV = (float)(word(rxmsg.buf[4], rxmsg.buf[5])); } } } Thanks Quote Link to comment Share on other sites More sharing options...
Adamw Posted May 29, 2020 Report Share Posted May 29, 2020 I dont know what library you are using but with most you shouldnt need to specify the CAN ID if that is the only message that is going to be on the bus - if will just read every message. This bit here looks wrong to me: You want it to switch based on the frame ID which is the number in Byte 0. Based on how the rest of your code is written I suspect this should be something like: switch (rxmsg.buf[0]) Also your byte numbers are wrong in this section you cant have data in byte zero as that is your frame ID: Davidv 1 Quote Link to comment Share on other sites More sharing options...
cruz177 Posted May 31, 2020 Author Report Share Posted May 31, 2020 On 5/29/2020 at 11:41 PM, Adamw said: No sé qué biblioteca está utilizando, pero con la mayoría no debería especificar la ID de CAN si ese es el único mensaje que estará en el bus, si solo leerá cada mensaje. Este bit aquí me parece mal: Desea que cambie según la ID del cuadro, que es el número en el byte 0. Según la forma en que está escrito el resto de su código, sospecho que esto debería ser algo como: switch ( rxmsg.buf [0]) Además, sus números de bytes son incorrectos en esta sección, no puede tener datos en el byte cero, ya que esa es su ID de trama: Thanks a lot but I just don't understand the id thing 1000 I have it as id communication value of canbus in link this value. It should not be as it says switch (rxmsg.buf [1000]) ? On the other hand, I understand that the stream sends the canbus signal of the 3 frames always for this id 1000? So why does each frame (in my case 1,2 and 3) have to have another corresponding id that in this case is 110, 120 and 130? Why can't I use 0? I understand that the messages each frame are 8 bytes, so I have to send the information that is between 0 and 7 for each frame, right? Quote Link to comment Share on other sites More sharing options...
Davidv Posted May 31, 2020 Report Share Posted May 31, 2020 Forget about the CanID you really need to think about Frame ID instead. Your frame ID takes up one of the bytes in the message. So in this example below, it is Frame number 13 . When this can frame is received by your teensy, you need to look a that first byte to tell you which frame it is. If the number is 13, then you know that your values in the frame are Inj timing, Ign Angle, and Inlet / LH target. So you can update those values. cruz177 and Adamw 2 Quote Link to comment Share on other sites More sharing options...
cruz177 Posted June 1, 2020 Author Report Share Posted June 1, 2020 17 hours ago, Davidv said: Olvídate de CanID, realmente debes pensar en Frame ID. Su ID de trama ocupa uno de los bytes del mensaje. Entonces, en este ejemplo a continuación, es el número de fotograma 13. Cuando su adolescencia recibe este marco de lata, debe mirar ese primer byte para decirle qué marco es. Si el número es 13, entonces sabe que sus valores en el marco son Inj timing, Ign Angle y Inlet / LH target. Para que pueda actualizar esos valores. Thank you so much now i get it I will be testing and keep you informed If I have any other questions, I will ask them Quote Link to comment Share on other sites More sharing options...
cruz177 Posted August 19, 2020 Author Report Share Posted August 19, 2020 On 29/5/2020 at 8:46, Tim D said: Hay muchas formas de lograr lo que quieres y estoy feliz de compartir mi enfoque, que funciona bien. Transmito 56 bytes (7 cuadros) desde la ECU al tablero, luego transmito estos datos a través de bluetooth (si la computadora portátil está funcionando, los datos se registran). Supongo que no tiene otros dispositivos CAN en el mismo bus CAN que su tablero. En este caso, el concepto de prioridades no es tan relevante (no habrá ningún otro tráfico CAN con el que lidiar). En mi tablero MBED, transmito 7 cuadros todos en el mismo CAN ID de 1300 (ID arbitrario). Estos byes se transmiten 'de un extremo a otro' (como se observa en el osciloscopio), dejando mucho tiempo después del último cuadro para hacer mi procesamiento. Todo lo que se requiere es escribir su firmware arduino para reconocer la transmisión. Mi tablero también transmite los datos de forma inalámbrica a mi computadora portátil, lo que brinda un registro de datos sin errores (elegí transmitir esto a 10 Hz). Le invitamos a ver mi configuración de CAN: https://drive.google.com/open?id=1pjCW7otZjlRO3j8JqtsJj-2yhvleHtnw I've been trying to make it work for a while and I can't, I know the code is relatively simple but I can't find it Could you share how you are communicating with arduino and managing the IDs? Thanks Quote Link to comment Share on other sites More sharing options...
cruz177 Posted August 19, 2020 Author Report Share Posted August 19, 2020 This is my code for communication: void loop(void) { // Gauge display function gauge_display(); //Look for CAN broadcasts if ( CANbus.read(rxmsg) ) { switch (rxmsg.id) { // ID's CAN broadcast frames // Stream 1 case 110: // Frame 1 MAP = (float)(word(rxmsg.buf[0], rxmsg.buf[1])); IAT = (float)(word(rxmsg.buf[2], rxmsg.buf[3])); ECT = (float)(word(rxmsg.buf[4], rxmsg.buf[5])); OILTEMP = (float)(word(rxmsg.buf[6], rxmsg.buf[6])); break; case 120: // Frame 2 OILPRESS = (float)(word(rxmsg.buf[0], rxmsg.buf[1])); // GEAR = (float)(word(rxmsg.buf[4], rxmsg.buf[4])); AFR = (float)(word(rxmsg.buf[5], rxmsg.buf[6])); break; case 130: // Frame 3 RPM = (float)(word(rxmsg.buf[0], rxmsg.buf[1])); TPS = (float)(word(rxmsg.buf[2], rxmsg.buf[3])); BATTV = (float)(word(rxmsg.buf[4], rxmsg.buf[5])); } } } Quote Link to comment Share on other sites More sharing options...
cruz177 Posted August 25, 2020 Author Report Share Posted August 25, 2020 you already connected the display to the serial monitor. the serial monitor marks me the canbus ID in link ecu of 1000 as I have set I understand that I am correctly receiving the data to the display the problem is that I do not get differences in the frames, I have read that in other ecu if the base id is 1000 you have to add each frame id example 1000 + 1 (for the first frame) = 1001 for the first frame Is this correct or is it enough to simply put 1 of that frame? I have tried both ways and it does not work but I don't know which one is correct thanks Quote Link to comment Share on other sites More sharing options...
Adamw Posted August 27, 2020 Report Share Posted August 27, 2020 As I said earlier if you are using a compound message you need to do the switch based on the frame ID, you are switching based on the message ID. Since you have your frame ID in byte 7, I would expect the change below to be what is needed. Also, I dont think your oil temp will work, as you are converting the same byte into a word, but that is not important now, get it to receive the data sucessfully first. Quote Link to comment Share on other sites More sharing options...
cruz177 Posted August 28, 2020 Author Report Share Posted August 28, 2020 On 8/27/2020 at 6:26 AM, Adamw said: As I said earlier if you are using a compound message you need to do the switch based on the frame ID, you are switching based on the message ID. Since you have your frame ID in byte 7, I would expect the change below to be what is needed. Also, I dont think your oil temp will work, as you are converting the same byte into a word, but that is not important now, get it to receive the data sucessfully first. thanks i managed to make it work right now I'm just focusing on RPM to have a starting point and not do it all at once the problem I have is that it seems that it does not run all the time in command, in the serial port I see continuously id 1000 but the rpm of the screen is fixed the moment I enter the can settings of the ecu link and click apply if I give it all the time it refreshes me perfectly at the same time as the pc Do you know what it can be? Thank you Quote Link to comment Share on other sites More sharing options...
Adamw Posted August 28, 2020 Report Share Posted August 28, 2020 Looking at your code that you posted earlier, you will need a "break" at the end of case 130. If that still doesnt help, then to diagnose further I would start by commenting out all the other cases except RPM and you could try reducing bit rate to 250K to see if that helps. Many of the arduino CAN libraries are quite poorly written and dont loop fast enough or have enough buffer to work reliably especially with compound messages, which is why I said right at the start to send only one frame per ID. But generally if there is only 3 or 4 frames it should be ok. Quote Link to comment Share on other sites More sharing options...
cruz177 Posted September 10, 2020 Author Report Share Posted September 10, 2020 thanks at last I have made everything work my main problem was the canh and canl converter ic which was Chinese and was not able to read the IDs well. I had to replace it with a texas instruments and it worked Now I have the problem with some values such as water or oil temperature, I cannot find in the program any section that says by what value I have to multiply or divide to see the value correctly since according to what I understand in link ecu is to multiply by 1 and dividing by 1 the result should be the same but it doesn't work. values like tps, rpm if they work correctly Thank you Quote Link to comment Share on other sites More sharing options...
Vaughan Posted September 10, 2020 Report Share Posted September 10, 2020 Use the CAN Test calculator function in the CAN Setup window to see what to multipliers and offsets different runtimes have Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.