Read and write terminal commands/messages.

Dear all,

I would like to ask for some advice. I'm trying to read data from a canbus system. For this I cross compiled some code on ubuntu 12.04.

What I trying to accomplish:

So on the canbus I connected a CANopen sensor. While this sensor is sending continiously data to my embedded system, I need to read settings from the sensor. To read and write this settings I use socketCAN.

So I tried the following:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sstream>
#include <iostream>
#include <stdlib.h>
#include <stdexcept>
#include <stdio.h>
#include <string>

using namespace std;

string IntToString(int number)
{
        stringstream temp;
        temp<<number;
        return temp.str();
}

string IntToHex(int data)
{
        stringstream ss;
        int sli;
        ss<< std::hex << data;
        string sdat = ss.str();
        sli= sdat.length();

         switch(sli){
                case 1: sdat = "0" + sdat;  break;
                default: sdat = sdat;
        }
        return sdat;
}


string GetCmdOutput(const char * cmd) // Function which returns the output of certain terminal command. In my case here I read a can message
{
        char buffer[128];
        string result = "";
        string different;
        FILE* pipe = popen(cmd,"r");
        int counter=0;
        if(!pipe) throw runtime_error("popen() failed!");
        try {
                if(fgets(buffer,128,pipe) !=NULL){
                        while(counter<1){
                                result +=buffer;
                                counter++;
                        }
                }
        }catch(...){
                pclose(pipe);
                throw;
        }

        pclose(pipe);
        return result;
}


void init_Can(int bus, int baudrate)             // Init of socket can. First make sure can is inactive, then set can settings after switch on "ip link set can0 type can bitrate 250000"
{ 
        string busnumber = IntToString(bus);
        string busbaudrate = IntToString(baudrate);

        const char *Reset;
        const char *Setup;
        const char *Conf;

        string reset = "ifconfig can" + busnumber + " down";
        string setup = "ip link set can" + busnumber + " up type can bitrate " + busbaudrate + "000";
        string conf = "ifconfig can" + busnumber + " up";
        cout<<reset + "\n";
        cout<<setup + "\n";
        cout<<conf + "\n";

        Reset=reset.c_str();
        Setup=setup.c_str();
        Conf=conf.c_str();

        system(Reset);
        system(Setup);
        system(Conf);

}

void canWrite(int busN, int baud, string id, int dlc, int dat0, int dat1, int dat2, int dat3, int dat4, int dat5, int dat6, int dat7)
{
        string busnumber = IntToString(busN);             // send a message onto the canbus. Here we can decide how many bytes you send, what data the id...
        string busbaudrate = IntToString(baud);

	cout<<"send data?\n";

        string message[8];
        message[0] = IntToHex(dat0);                         
        message[1] = IntToHex(dat1);
        message[2] = IntToHex(dat2);
        message[3] = IntToHex(dat3);
        message[4] = IntToHex(dat4);
        message[5] = IntToHex(dat5);
        message[6] = IntToHex(dat6);
        message[7] = IntToHex(dat7);

        string cansend;

        switch(dlc)
        {
                case(0): cansend = "cansend can" + busnumber + " " + id + "#";  break;
                case(1): cansend = "cansend can" + busnumber + " " + id + "#" + message[0];     break;
                case(2): cansend = "cansend can" + busnumber + " " + id + "#" + message[0] + "." + message[1];  break;
                case(3): cansend = "cansend can" + busnumber + " " + id + "#" + message[0] + "." + message[1] + "." + message[2];       break;
                case(4): cansend = "cansend can" + busnumber + " " + id + "#" + message[0] + "." + message[1] + "." + message[2] + "." + message[3];    break;
                case(5): cansend = "cansend can" + busnumber + " " + id + "#" + message[0] + "." + message[1] + "." + message[2] + "." + message[3] + "." + message[4]; break;
                case(6): cansend = "cansend can" + busnumber + " " + id + "#" + message[0] + "." + message[1] + "." + message[2] + "." + message[3] + "." + message[4] + "." + message[5];      break;
                case(7): cansend = "cansend can" + busnumber + " " + id + "#" + message[0] + "." + message[1] + "." + message[2] + "." + message[3] + "." + message[4] + "." + message[5] + "." + message[6];   break;
                case(8): cansend = "cansend can" + busnumber + " " + id + "#" + message[0] + "." + message[1] + "." + message[2] + "." + message[3] + "." + message[4] + "." + message[5] + "." + message[6] + "." + message[7];        break;
        }

	const char *canSender;
        canSender = cansend.c_str();
        system(canSender);
	cout<<cansend + "\n";
}


int main()
{
	int baudrate, dlc,i;
	int data[8];
	string id;
        init_Can(0,250);

	string value;
	cout<<"Do we wish to start;";
	cin>>value;

	if(value!="Y")
	{
		usleep(1000000);
		return 0;
	}



	data[0] = 64;
	data[1] = 00;
	data[2] = 02;
	data[3] = 00;
        data[4] = 00;
        data[5] = 00;
        data[6] = 00;
        data[7] = 00;
	i = 0;

	id = "612";
	dlc = 8;


        string dump = "candump can0,592:1FFFFFFF";
        const char *senddump;
        senddump = dump.c_str();
	string outp;

	while(i<1)
	{
		cout<<"start new loop\n";

		canWrite(0,250000, id, dlc, data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7]); // send question on canbus to sensor cansend can0 612#64.00.02.00.00.00.00.00 
		outp = GetCmdOutput(senddump);                                                                // catch the message with ID 592 on the canbus. Here I miss the message. Due to the latency of setting candump, the settings allready passed
		cout<<outp + "\n";
	}
}


So as you can see in the last steps I send a command onto the canbus (canwrite), straight after I initiate the candump.

The result of the dump should be "can0 592 [8] 80 00 02 00 00 00 02 06". The result is nothing. I think this is because the capture of the can signal is to slow. (Always starting a new dump)

Now it would work much better if could start the candump in one terminal and log this terminal continiously and then in a seperated terminal send the commands to onto the CANbus.(When I try this manually this works great.) I have no Idea on how to do this at all.

Can somebody point me in the correct direction? Or give me an explaination on how I could improve this?

Thanks in advance,
Kind regards,
TMJJ
Last edited on
Registered users can post here. Sign in or register to post.