Jump to content

dashboard arduino


cruz177

Recommended Posts

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();

}

1.png

2.png

Link to comment
Share on other sites

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 :-) 

 

 

Link to comment
Share on other sites

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)?
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

1.png

2.png

Link to comment
Share on other sites

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:

 SjsfkDp.png

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:

q26M2vc.png

 

Link to comment
Share on other sites

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:

 SjsfkDp.png

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:

q26M2vc.png

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?

Link to comment
Share on other sites

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.
 

Capture.PNG

Link to comment
Share on other sites

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.
 

Capture.PNG

 

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

Link to comment
Share on other sites

  • 2 months later...
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

Link to comment
Share on other sites

 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]));

    }


  }
}
 

1.png

2.png

Link to comment
Share on other sites

 

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

Link to comment
Share on other sites

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.

zVu6iKz.png

 

Link to comment
Share on other sites

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.

zVu6iKz.png

 

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

  • 2 weeks later...
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
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...