CANbus simulation for Automotive purpose - arduino

i explain a bit...
I repair Electric powered steering systems for cars, especially Fiat/Alfa/Lancya (Delphi manufacturers) and i'm in need of making some tool to test these reparations, i mean just turning it on for example.
I have researched during some time, and i figured i need Can-bus signals to be simulated as the eps ECU is receiving ignition packets from CAN, here i go..
I need to know what way i could Read/Send CAN packets from/to BUS, i mean what tool or anything else. I have been trying with Arduino UNO + Sparkfun Shield, but i dont get any results, when everything connected, my serial console isnt sniffing any packets, i have connected all correctly i think, tried different bitRates, changed Arduino boards and shield, tried many different examples, i invested lots of hours with no profit... i was using Seat Ibiza 2010 for I+D, connected CAN-H AND CAN-L on OBD PORT, in the CAN lines from radio,etc...
Any idea of what could be wrong is welcome, as new method to make my project.. Thanks in advance!!
Info:
https://dl.dropboxusercontent.com/u/47864432/arduino/IMG_9358.JPG
https://dl.dropboxusercontent.com/u/47864432/canbus/LIBRARYS_USED.rar

There are two potential issues here:
H/W problem
CAN bus library problem
The first step is try loopback test. If all is OK, try CAN bus from any car OBD port, the speed should be 500Kb.

This one tries a couple of bus speeds -- works with sparkfun canbus shield:
#include <SPI.h>
#include <SD.h>
#include <Canbus.h>
#include <defaults.h>
#include <global.h>
#include <mcp2515.h>
#include <mcp2515_defs.h>
const int chipSelect = 9;
File dataFile;
void setup() {
// put your setup code here, to run once:
pinMode(chipSelect, OUTPUT);
Serial.begin(115200); // For debug use
Serial.println("CAN Read - Testing receival of CAN Bus message");
delay(1000);
if (Canbus.init(CANSPEED_500)) //Initialise MCP2515 CAN controller at the specified speed
Serial.println("CAN Init ok: 500k");
else if (Canbus.init(CANSPEED_250)) //Initialise MCP2515 CAN controller at the specified speed
Serial.println("CAN Init ok: 250k");
else if (Canbus.init(CANSPEED_125)) //Initialise MCP2515 CAN controller at the specified speed
Serial.println("CAN Init ok: 125k");
else
Serial.println("Can't init CAN");
delay(1000);
if (!SD.begin(chipSelect)) {
Serial.println("uSD card failed to initialize, or is not present");
return;
}
else {
Serial.println("uSD card initialized.");
delay(1500);
}
dataFile = SD.open("caninfo.txt", FILE_WRITE);
}
void loop() {
tCAN message;
if (mcp2515_check_message())
{
if (mcp2515_get_message(&message))
{
if (dataFile) {
int timeStamp = millis();
//write to uSD card
dataFile.print(timeStamp);
dataFile.print("ID: ");
dataFile.print(message.id, HEX);
dataFile.print(", ");
dataFile.print("Data: ");
dataFile.print(message.header.length, DEC);
for (int i = 0; i < message.header.length; i++)
{
dataFile.print(message.data[i], HEX);
dataFile.print(" ");
}
dataFile.println("");
Serial.println("Writing to SD");
}
else
{
Serial.println("Problem writing to SD");
}
}
}
}

If you want to communicate via CAN with Steering controller for example for an OEM like Delhpi .. this is not possible as the ECU (ELectronic control units) in the communication network are secured and the CAN protocol software decides who can participate and who can't.
As a tester tool you can read the trouble codes but you can't hack it to simulate the Ignition signal etc...

Related

AT works at half for HC05

I am currently trying to send my sensor data from my Arduino to an android app made on android studio using an HC05 module for Arduino.
I tried to configure the HC05 as every tutorial on the internet says, but i meet some problems.
I am using the arduino code:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
int PotPin = A7;
int Vdata = 15;
void setup() {
Serial.begin(9600);
pinMode(9,OUTPUT); digitalWrite(9,HIGH);
Serial.println("Enter AT commands:");
mySerial.begin(38400);
}
void loop()
{
Vdata = analogRead(PotPin);
if (mySerial.available())
Serial.write(mySerial.read());
if (Serial.available())
mySerial.write(Serial.read());
}
When I type "AT" in the Serial monitor, it returns me "OK" (that is normal).
But when I try to see the name/the address/the password of the module, it returns me "Error:(0)". The strangest thing is that the command " AT+NAME="NameWanted" " or even " "AT+PWD="4321" " works since it correctly changes the name of the module.
I looked on the internet but I didn't see someone with the same problem as mine, I hope someone will lead me to the solution!
Thanks
I found out what's the problem. My mcu's bauderate was bigger (115200), then my hc05's bauderate (38400). With this bauderate, my MCU sent the messages faster, then hc05 could read it. So, I decreased the bauderate of my MCU and now it's working

Data are not sent between Arduino uno and NodeMcu esp8266 at all time

I am sending data from Arduino UNO R3 to nodeMcu esp8266. In that case sometime data are send properly but at sometime data are are not send by arduino or not get by nodemcu esp8266.Also tx light not blinks after i upload the code to the Arduiono.
enter code here
Code Uploaded to Arduino:
#include <SoftwareSerial.h>
#include <ArduinoJson.h>
SoftwareSerial s(10,11);
SoftwareSerial h(10,11);
int i=0;
void setup() {
// put your setup code here, to run once:
s.begin(9600);
Serial.begin(9600);
}
int f1=0;
int f2=0;
String st="sy";
void loop() {
f1=f1+1;
f2=f2+2;
// put your main code here, to run repeatedly:
StaticJsonBuffer <1000> bf;
StaticJsonBuffer <1000> rec;
JsonObject& root=bf.createObject();
JsonObject& receives=rec.parseObject(h);
if (receives==JsonObject::invalid())
{
Serial.println("no data from nodemcu");
root["data3"]="no data from nide";
}
else
{
root["data3"] = receives["data3"];
//st = (const char*)receive["data3"];
}
root["data1"]=f1;
root["data2"]=f2;
//root["data3"]=st;
if(s.available()>0)
{
root.printTo(s);
Serial.println("send");
}
else
{
Serial.println("NOt Available");}
//i=i+1;
//s.write(i);
delay(1000);
}
In your code thera are two reasons I can spot on the first look:
1 Never use delay in server client applications. Delay stops proccessing and inhibts communication. For more details how to avoid look at the blinkwithoutdelay built in Example in the Arduino IDE.
2. You use ArduinoJSON: This lib is absolute overkill for 99% of the applications it is used for. Don't get me wrong - the lib offers fantastic features, but if not needed this can be regarded as bloat-ware.
I wrote my own simple JSON coding/decoding (~250 lines of code) for a performant application using an Arduino as "Signal generator" and the ESP8266/ESP32 as a webserver. Communication between Arduino and ESPis time critical and so far it works over a year without problems,

Using rosserial to communicate with MX-64 DYNAMIXEL motor

When I try to use rosserial to communicate with an Arduino to control the MX-64 motor, every time I use rostopic pub to send a message, it will give me this error:
"Mismatched protocol version in packet: lost sync or rosserial_python is from different ros release than the rosserial client "
If I remove the Dynamixel.move(X_SERVO_ID,rollint); function in the code or don't send any information though ROS, there will be no error. I tried all the rosserial examples, all of them are working just fine without any error.
The weird thing is even if it gives me an error, the program is still working. Every time I send a message, the DYNAMIXEL motor will start moving.
#if (ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include <ros.h>
#include <std_msgs/Int8.h>
ros::NodeHandle nh;
#include <Dynamixel_Serial.h> // Library needed to control Dynamixal servo
#include <sensor_msgs/Imu.h>
#define X_SERVO_ID 0x01 // ID which we will be set in Dynamixel too
int rollint = 0;
void motor_cb(const std_msgs::Int8& cmd_msg) {
rollint = ((1.00*(90-cmd_msg.data))/360)*4095;
Dynamixel.move(X_SERVO_ID,rollint);
}
ros::Subscriber<std_msgs::Int8> sub("MX_Motor", motor_cb);
void setup() {
delay(100); // Give time for Dynamixel to start on power-up
nh.initNode();
nh.subscribe(sub);
}
void loop(){
nh.spinOnce();
delay(1);
}
It looks like your Dynamixel servo is hooked up to the same serial port that you use to communicate with the rosserial server. In many Arduino boards like the Uno the hardware serial port (where your Dynamixel is hooked up) is connected to a USB serial converter (which connects ROS via USB).
You need to connect your Dynamixel to a different hardware (or software) serial on your Arduino and initialize it with Dynamixel.begin(Stream&) (Dynamixel_Serial.h#L162), where Stream& is that hardware / software serial.

Arduino GSM GPS Shield doesn't do the GSM_READY check

Before you mark this question as duplicate, please note that I have already tried this, this & this
I bought an Arduino UNO R3 & a SIM808 GSM/GPS shield recently. The RX of the Shield is connected to Pin 11 of Arduino, TX to Pin 10 with both the GNDs connected to each other. I have connected my Arduino to my computer with the USB & the shield is connected to an external power supply with a 12V Adapter. Additionally, I have connected the 3.3V of the Arduino to Vcc of the shield.
Following is the sketch I have used:
// Include the GSM library
#include <GSM.h>
#define PINNUMBER ""
// initialize the library instance
GSM gsmAccess;
GSM_SMS sms;
void setup() {
// initialize serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("SMS Messages Sender");
// connection state
boolean notConnected = true;
// Start GSM shield
// If your SIM has PIN, pass it as a parameter of begin() in quotes
while (notConnected) {
if (gsmAccess.begin(PINNUMBER) == GSM_READY) {
notConnected = false;
} else {
Serial.println("Not connected");
delay(1000);
}
}
Serial.println("GSM initialized");
}
void loop() {
Serial.print("Enter a mobile number: ");
char remoteNum[20]; // telephone number to send sms
readSerial(remoteNum);
Serial.println(remoteNum);
// sms text
Serial.print("Now, enter SMS content: ");
char txtMsg[200];
readSerial(txtMsg);
Serial.println("SENDING");
Serial.println();
Serial.println("Message:");
Serial.println(txtMsg);
// send the message
sms.beginSMS(remoteNum);
sms.print(txtMsg);
sms.endSMS();
Serial.println("\nCOMPLETE!\n");
}
/*
Read input serial
*/
int readSerial(char result[]) {
int i = 0;
while (1) {
while (Serial.available() > 0) {
char inChar = Serial.read();
if (inChar == '\n') {
result[i] = '\0';
Serial.flush();
return 0;
}
if (inChar != '\r') {
result[i] = inChar;
i++;
}
}
}
}
Problem here is same as that mentioned in those linked posts.
The condition if (gsmAccess.begin(PINNUMBER) == GSM_READY) never gets executed. Neither does the else part execute.
Serial monitor never goes past SMS Messages Sender.
Please note that I am using AirTel India, I have a fully activated Data Plan & the PIN Number has been changed to 0000.
Would really appreciate if someone could suggest something helpful.
Thanks for your time!!
You cannot power a GSM module from the 3.3V of Arduino! a GSM needs peak currents of 3A (yes, Amps, not milli-amperes). You really need a LiPo battery to power the GSM. You could power a 3V Arduino from the same LiPo battery, actually, if you need a mobile solution, but not the other way around.
Please first check if the module responds with the next code Example Code
Other thing the Supply voltage range must be 3.4 ~ 4.4V, try not using less voltage .
The GSM library of the Arduino is for the Quectel M10 GSM/GPRS module and is not compatible with SimCom SIMxxx modules.
Here is the library that you can use for your SIM808 module https://github.com/MarcoMartines/GSM-GPRS-GPS-Shield (examples included in the repo). Note that this library uses the SIM900 library which allows low level interface with SimCom modules.
For further reading here two adafruit links:
http://wiki.iteadstudio.com/SIM808_GSM/GPRS/GPS_Module
https://www.adafruit.com/products/2637
the shield is connected to an external power supply with a 12V
Adapter. Additionally, I have connected the 3.3V of the Arduino to Vcc
of the shield.
What do you mean by that? You need to supply your shield with the required voltage that can deliver the required amps. And also you need to have a common ground with your arduino.
In addition, if your shield is a 3.3V you need to shift Tx line comming from arduino as well (because it's a 5V) using a voltage divider.
Note that these shields have also a soft power-up button that needs to be connected as well, to allow the code to power up your module.

Sending AT commands to a GSM/GPRS and displaying the reply on a Serial Monitor

I am quite rusty when it comes to Serial ports. I want to send an AT command to a GSM/ GPRS shield connected to my Arduino UNO. The AT command I want to pass in particular is the command to get a networks signal strength.
I am using the SIM900 and SoftwareSerial library to send the command as the GSM library does not compile correctly for me. Meaning I have to use the SoftwareSerial library.
I have this example code from the SIM900 library working that relies on reading inputs from the serial monitor to carry out commands but I need it to be automated and the command to be passed in hardcoded. In this example code, the place of interest is the simplehwread() method.
#include "SIM900.h"
#include <SoftwareSerial.h>
int numdata;
char inSerial[40];
int i=0;
void setup()
{
//Serial connection.
Serial.begin(9600);
Serial.println("GSM Shield testing.");
//Start configuration of shield with baudrate.
//For http uses is raccomanded to use 4800 or slower.
if (gsm.begin(9600))
Serial.println("\nstatus=READY");
else Serial.println("\nstatus=IDLE");
};
void loop()
{
//Read for new byte on serial hardware,
//and write them on NewSoftSerial.
serialhwread();
//Read for new byte on NewSoftSerial.
serialswread();
};
void serialhwread()
{
i=0;
if (Serial.available() > 0) {
while (Serial.available() > 0) {
inSerial[i]=(Serial.read());
delay(10);
i++;
}
inSerial[i]='\0';
if(!strcmp(inSerial,"/END")) {
Serial.println("_");
inSerial[0]=0x1a;
inSerial[1]='\0';
gsm.SimpleWriteln(inSerial);
}
//Send a saved AT command using serial port.
if(!strcmp(inSerial,"TEST")) {
Serial.println("SIGNAL QUALITY");
gsm.SimpleWriteln("AT+CSQ");
} else {
Serial.println(inSerial);
gsm.SimpleWriteln(inSerial);
}
inSerial[0]='\0';
}
}
void serialswread()
{
gsm.SimpleRead();
}
No matter how I modify this code, the command does not get passed in and response displayed while the method here does it but not the way I want it to be done. i.e Direct input. Could anyone assist here?
i have dealt with exactly this scenario at a company with a cellular radio on board. there are many status signals that come over and if not dealt with appropriately these status flags from the cell modem will be lost
you need to look at the data sheets associated with your cell modem and its protocol so you know what flags to watch for at the various steps taken along the way from configuration, to eventual connection to cellular service.
multi-threaded coding techniques must be followed as well.
keep in mind that the comm channel is not ideal and there WILL be failures. provided your coding techniques are sound and you follow protocol requirements, then it should work.
Ron
Boise, ID

Resources