Offline
Newbie
Karma: 0
Posts: 12
|
 |
« on: January 15, 2013, 12:38:27 pm » |
Hi, I am trying to port an automotive project I have been working on for a while (on Mega 2560 board) to my brand new Arduino Due board. Problem is that SoftwareSerial library is missing. I need it to sync with OBD 10400 baud since standard Serial is not accurate enough at this speed. I modified the original library to work at 10400 baud and it connected flawlessy. Unfortunately my version does not compile under Due board and no other version is available. Is there any port under way, of the library?
Thanks in advance, Luca
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 9
Posts: 251
|
 |
« Reply #1 on: January 15, 2013, 06:17:07 pm » |
Not sure what you mean by "missing", I don't think there are any problems using the Due with SoftSerial, can you post your code?
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 316
Posts: 35566
Seattle, WA USA
|
 |
« Reply #2 on: January 16, 2013, 06:32:08 am » |
Doesn't this belong in the DUE section?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #3 on: January 16, 2013, 01:05:20 pm » |
Doesn't this belong in the DUE section? You are right, this is my first post and I posted it in the wrong place, sorry  Is it possible to move it to the DUE section? I don't think there are any problems using the Due with SoftSerial The Software serial library is not present in the DUE tree. I tried to copy it to the libray folder but it won't compile (it links avr libs). And the reason was obvius once I looked inside: SoftwareSerial is tuned only for 8,16,20 MHZ (DUE is 84 MHz) and makes some use of inline assembly . Moreover DUE has (I think) a different approach to change interrupts. But I could be wrong, I have been using the 1.5.1 IDE only for two days.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 316
Posts: 35566
Seattle, WA USA
|
 |
« Reply #4 on: January 16, 2013, 01:10:03 pm » |
The DUE has 4 hardware serial port, doesn't it? Why are you needing software serial ports?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #5 on: January 16, 2013, 03:43:49 pm » |
The DUE has 4 hardware serial port, doesn't it? Why are you needing software serial ports? Because I am developing an automotive project which needs 10400 baud on the serial port. With Atmega328P and Mega2560 I tried to set the hardware serial port to 10400 but I could not connect to the ECU of the car. So I modified the SerialSoftware library in order to accept this connection speed and it worked like a charm. I have been testing the system for more than 6 months and it almost never dropped a frame. Now I fear to have the same problem on the new DUE so I would be very happy to have a SoftwareSerial library to modifiy to 10400 baud. Luca
|
|
|
|
|
Logged
|
|
|
|
|
Forum Administrator
Milano, Italy
Offline
Full Member
Karma: 19
Posts: 210
|
 |
« Reply #6 on: January 16, 2013, 06:38:42 pm » |
The Serial class uses the following formula to obtain the clock divider: _pUsart->US_BRGR = (SystemCoreClock / dwBaudRate) / 16 ;
in your case the perfect divisor would be 84000000 / 10400 / 16 = 504.8076 but the register will truncate to the integer 504. The error is under <0.2% IMHO you should give a try with Serial.
|
|
|
|
|
Logged
|
C.
|
|
|
|
Smithfield, Rhode Island
Offline
God Member
Karma: 2
Posts: 825
|
 |
« Reply #7 on: January 16, 2013, 06:51:43 pm » |
The Serial class uses the following formula to obtain the clock divider: _pUsart->US_BRGR = (SystemCoreClock / dwBaudRate) / 16 ;
in your case the perfect divisor would be 84000000 / 10400 / 16 = 504.8076 but the register will truncate to the integer 504. The error is under <0.2% IMHO you should give a try with Serial. I agree with this assessment. Failing that, perhaps the Multi Serial shield would work...
|
|
|
|
|
Logged
|
|
|
|
|
Greenville, IL
Offline
Edison Member
Karma: 11
Posts: 1287
Warning Novice on board! 0 to 1 chance of errors!
|
 |
« Reply #8 on: January 17, 2013, 09:37:11 am » |
Post your OBD2 initiation part of your code and maybe we can help adjust it to work with hardware serial.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #9 on: January 17, 2013, 01:18:39 pm » |
Thanks to you all for your answers. I think I will try again Hardware Serial. First time I tried it was with Atmega328p and it failed. Then when I upgraded to Mega2560 I did not try again because the software was very stable then. But since I have to rewrite half of the program (LCD panel is going to be replaced by a 5" TFT display so the whole HMI must be rewritten) there is space for many tests  However here is the software (for Atmega2560): http://luca72.xoom.it/td5mapsuiteweb/archive/td5opencom/td5opencom11q.zipOBD2 communication management is in file td5comm.cpp, this is the read/write part: boolean Td5Comm::read_byte(byte * b) { int readData; boolean success = true; byte t=0;
//digitalWrite(ledPin, HIGH); while(t != READ_ATTEMPTS && (readData=obdSerial.read())==-1) { delay(1); t++; } //digitalWrite(ledPin, LOW);
if (t >= READ_ATTEMPTS) { success = false; }
if (success) { *b = (byte) readData; }
return success; }
void Td5Comm::write_byte(byte b) { //digitalWrite(ledPin, HIGH); obdSerial.write(b); delay(Td5RequestByteDelay); // ISO requires 5-20 ms delay between bytes. //digitalWrite(ledPin, LOW); } If somebody can give me some suggestions they are very welcomed  Thanks again, Luca
|
|
|
|
|
Logged
|
|
|
|
|
Greenville, IL
Offline
Edison Member
Karma: 11
Posts: 1287
Warning Novice on board! 0 to 1 chance of errors!
|
 |
« Reply #10 on: January 17, 2013, 09:32:04 pm » |
You have a function that starts the communication process. I am showing the first part of it only as it is fairly long. I am assuming there is something in your code that help you get from case "1" and past the blank case "2" to continue to case "3" and so forth. void Td5Comm::initComm() { unsigned long currentTime = millis(); switch (initStep) { case 0: // setup ecuConnection = false; initTime = currentTime + 300; initStep++; break; case 1: if (currentTime >= initTime) { // drive K line high for 300ms digitalWrite(K_OUT, HIGH); digitalWrite(ledPin, HIGH); initTime = currentTime + 300; initStep++; } break; case 2: case 3: if (currentTime >= initTime) { // start or stop bit digitalWrite(K_OUT, (initStep == 2 ? LOW : HIGH)); digitalWrite(ledPin, (initStep == 2 ? LOW : HIGH)); initTime = currentTime + (initStep == 2 ? 25 : 25); initStep++; } break; case 4: if (currentTime >= initTime) { // switch now to 10400 bauds obdSerial.begin(10400);
// bit banging done, now verify connection at 10400 baud if (getPid(&pidInitFrame) <= 0) { digitalWrite(ledPin, LOW); initStep = 0; break; }
lastReceivedPidTime = currentTime; initTime = currentTime + Td5RequestDelay; initStep++; } I have a code that works for me for my initialization, it is not as elegant as yours but, it works for my situation. I am using a 1284 chip that has two hardware serial ports. Maybe you can adapt the code for your application. Here it is: digitalWrite (TX, HIGH); // makes K-line high pin 3 digitalWrite(ledPin,HIGH); delay(2000); // wait for K-line to be clear pin3 digitalWrite (TX, LOW); // makes K-line low pin3 delay(25); digitalWrite (TX, HIGH); // makes K-line high pin3 delay(25); //last delay before first message Serial1.begin(10400); //send package first message for (int i = 0; i < 5; i++){ Serial1.write(message[i]); byte inByte = Serial1.read(); delay(1); //inter byte delay for to match k-line spec. changed from 15ms to 1 }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #11 on: January 18, 2013, 12:32:50 pm » |
Hi, thank for sharing your experience. Before using a special version of SoftwareSerial (modified by me) tuned for 10400 baud, I tried for a while the Hardware Serial with no success. My initial code was similar to yours. It worked, but the problem was on long frames. It was reliable up until the first three or four bytes then it went out of sync starting loosing bits. At the beginning I used Atmega328p and the only solution I found was adapting the SoftwareSerial library. After few months I run out of RAM so I upgraded the controller to Atmega2560 but I did not try to go back to Hardware Serial (at that point communication was already very reliable). Maybe, as in your case, it worked with the Mega board. Now I am going to try it first on Atmega2560 then, if it works, I will try it on DUE.
In my code (I borrowed it from OBDuino project) states 2 and 3 share the same code, 25 ms LOW and 25ms HIGH.
Luca
|
|
|
|
|
Logged
|
|
|
|
|
Greenville, IL
Offline
Edison Member
Karma: 11
Posts: 1287
Warning Novice on board! 0 to 1 chance of errors!
|
 |
« Reply #12 on: January 18, 2013, 11:16:41 pm » |
I wrote a long reply and accidentally deleted it.  To summarize, if you want to pursue using hardware serial, you need to strip your code to the basics, and make sure that your problem is the Serial method and not something in your sketch causing the problem. I suspect that your button checking, and LCD printing, may be causing the serial to lag behind or have a buffer problem. Stripping your code to the basics and printing the OBD2 output to the serial monitor will help you troubleshoot the problem. Once the problem is found, you can optimize the other functions to work with your code. P.S. When I first started my project, I printed what mode I was in. I called the modes 1,2,3,4. For instance mode 1 = initialization. Using this method, I was able to determine how far my sketch went before problems arrived. I also printed my OBD2 messages to help me look for errors. Keep working at your sketch, it looks like it has a lot of nice features so far!
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #13 on: January 19, 2013, 01:13:33 am » |
At the very beginning the code was stripped to almost nothing, but on Atmega328p there was no way to receive long frames. Then I made some researches on the web and I found many people having the same problem at 10400 baud (how OBDuino works is a mistery to me...) so I switched to Software serial and everything worked OK. I never tried to do the same thing on Mega2560 (which is very similar to your 1280). Now I have three devices running with SoftwareSerial: the ECU emulator, a basic device with Atmega328p and LCD 20x4 and a full diagnostic device (see video below) running on Atmega2560. Yesterday I tried a very basic circuit and SW with Arduino DUE and MC33290 but I do not know how I got two chip (MC33290) burned  This is very strange because I tested them both on the ECU emulator prior to connect them to DUE and they worked. Once connected to TX/RX on the DUE they got burned  ....really strange (and SAD, since they are not very common and now I have only one left). Never happened before during the hundreds of test I did to have the project running.... I really have to learn many things about this DUE board!!!  Anyway here is the device (with Mega2560) running on my Land Rover Defender: http://luca72.xoom.it/td5mapsuiteweb/archive/td5opencom/td5oc_running.wmvThis video was taken last Summer and many functions were missing, now it is quite complete and it is able to save a log fuelling data on the SD card while running, reset errors, read settings and so on. Next step is to upgrade to Arduino DUE and 5" TFT touch display. It seems it will not be as easy as I though..... Luca
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #14 on: January 19, 2013, 05:25:01 am » |
Hardware Serial works at 10400 baud  I cannot explain the two chips burned but I should have done something wrong on the breadboard... probably my fault (I ordered five more MC33290 to be sure!!!). I had to make some minor changes to my code, but eventually communication was stable with DUE. No frames lost even under continuous writing/reading (I tested instrument mode, it exchanges a frame every 250 ms). Thanks to everybody for your suggestions!!! Luca
|
|
|
|
« Last Edit: January 19, 2013, 05:29:20 am by LucaV72 »
|
Logged
|
|
|
|
|
|