Go Down

Topic: NewSoftSerial not working under Arduino 016 (Read 1 time) previous topic - next topic

Ron C

Jun 05, 2009, 12:09 am Last Edit: Jun 05, 2009, 12:39 am by ronczap Reason: 1
I downloaded the new 016 IDE software and copied my libraries.

I have a sketch using Wire.H and NewSoftSerial (for a DS1307 RTC and serial LCD).  The code using NewSoftSerial is display garbage on the LCD when compiled and uploaded with version 016 but works perfectly with version 015.

Code: [Select]

#define LCD                 //compile NewSoftSerial LCD code
#define DEBUG            //compile serial monitor clock display
#define SETCLOCK     //compile clock setup code

#include "Wire.h"
#ifdef LCD
 #include <NewSoftSerial.h>
#endif

#define DS1307_I2C_ADDRESS 0x68       //seven bit address
#define MAXLINE 10
#define is12HR 0x40
#define isPM 0x20

#define homeCur  1  //Cursor home cntl-A
#define bigChar    2  //Begin big characters cntl-B
#define regChar    3  //End big characters cntl-C
#define noCurs      4  //Make cursor invisible cntl-D
#define ulCurs       5  //Show underline cursor cntl-E
#define blkCurs     6  //Show blinking block cursor
#define rngBell     7  //Bell output cntl-G
#define backSp     8  //Backspace cntl-H
#define hTab        9  //Horizontal tab (4 col) cntl-I
#define curLF     10  //Smart linefeed cntl-J
#define vTab      11 //cursor up one line cntl-K
#define clrLCD   12 //Clear entire LCD screen cntl-L
#define carRet   13  //Carriage return cntl-M
#define offBkLight 15 //Backlight off cntl-O
#define onBkLight 14 //Backlight on cntl-N
#define posCmd    16 //Position cursor cntl-P
#define clrCol        17 //Clear column cntl-Q ?
#define alignRight 18 //Accept right-alignment data cntl-R
#define Esc           27 //Escape sequences


static char *dayname[] =
{ "Sun",
"Mon",    
"Tue",  
"Wed",  
"Thu",
"Fri",
"Sat"
};

#ifdef LCD
 NewSoftSerial mySerial(255, 3);        //tx only
#endif

void setup()
{
 Wire.begin();

 Serial.begin(9600);

#ifdef LCD
 mySerial.begin(9600);
 mySerial.print(clrLCD, BYTE);
 mySerial.print(onBkLight , BYTE);
 delay(1000);
#endif

#ifdef SETCLOCK
 char ans[1];
 int serbytes=0;
 Serial.println("Enter 'y' to set clock");
 serbytes = getSerStrWait(ans, 1, 5000);
 if (strcmp(ans, "y") == 0) {
   setClock();
 }  
#endif

}

void loop()
{
 byte second, minute, hour, dayOfWeek, dayOfMonth, month, year, ampm;

 getClock(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year, &ampm);

#ifdef DEBUG
 leadzero(hour);
 Serial.print(hour, DEC);
 Serial.print(":");
 leadzero(minute);
 Serial.print(minute, DEC);
 Serial.print(":");
 leadzero(second);
 Serial.print(second, DEC);
 if (ampm != ' ') {                       //not space
   Serial.print(" ");
   Serial.print(ampm);
   Serial.print("M");
 }  
 Serial.print(" ");
 leadzero(month);
 Serial.print(month, DEC);
 Serial.print("/");
 leadzero(dayOfMonth);
 Serial.print(dayOfMonth, DEC);
 Serial.print("/");
 leadzero(year);
 Serial.print(year, DEC);
 Serial.print(" ");
 Serial.println(dayname[dayOfWeek-1]);
#endif

#ifdef LCD
 mySerial.print(posCmd, BYTE);
 mySerial.print(24+64, BYTE);
 lcdleadzero(hour);
 mySerial.print(hour, DEC);
 mySerial.print(":");
 lcdleadzero(minute);
 mySerial.print(minute, DEC);
 mySerial.print(":");
 lcdleadzero(second);
 mySerial.print(second, DEC);
 if (ampm != ' ') {                       //not space
   mySerial.print(" ");
   mySerial.print(ampm);
   mySerial.print("M");
 }  
 mySerial.print(posCmd, BYTE);
 mySerial.print(44+64, BYTE);
 lcdleadzero(month);
 mySerial.print(month, DEC);
 mySerial.print("/");
 lcdleadzero(dayOfMonth);
 mySerial.print(dayOfMonth, DEC);
 mySerial.print("/");
 lcdleadzero(year);
 mySerial.print(year, DEC);
 mySerial.print(" ");
 mySerial.println(dayname[dayOfWeek-1]);
#endif

 delay(1000);
}

void leadzero(byte val) {
 if (val < 10) {
   Serial.print("0");
 }  
}

#ifdef LCD
void lcdleadzero(byte val) {
 if (val < 10) {
   mySerial.print("0");
 }  
}
#endif

#ifdef SETCLOCK
void setClock() {
//prompt for time settings
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
byte mode = 0x00;
byte ampm = 0x00;
char ans[1];
char dig2[3];
int serbytes=0;

Serial.println("Enter 2 dig year");
serbytes = getSerStr(dig2, 2);
year = atoi(dig2);
Serial.println("Enter 2 dig month");
serbytes = getSerStr(dig2, 2);
month = atoi(dig2);
Serial.println("Enter 2 dig day of month (1-31)");
serbytes = getSerStr(dig2, 2);
dayOfMonth = atoi(dig2);

Serial.println("Enter day of week where 1=SUN 2=MON 3=TUE 4=WED 5=THU 6=FRI 7=SAT");
serbytes = getSerStr(dig2, 1);
dayOfWeek = atoi(dig2);

Serial.println("Enter clock mode - 12 or 24");
serbytes = getSerStr(dig2, 2);
if (strcmp(dig2, "12") == 0) {
  mode = is12HR;
  Serial.println("Enter 'a' or 'p' for AM or PM");
  serbytes = getSerStr(ans, 1);
  if (strcmp(ans, "p") == 0) {
    ampm = isPM;
  }
}  
Serial.print("Enter 2 dig hour ");
if (mode == is12HR) {
  Serial.println("(1-12)");
}else{
  Serial.println("(0-23)");
}  
serbytes = getSerStr(dig2, 2);
hour = atoi(dig2);

Serial.println("Enter 2 dig minute");
serbytes = getSerStr(dig2, 2);
minute = atoi(dig2);
second = 0;
if (mode == is12HR) {
  hour = hour | is12HR;
  if (ampm == isPM) {
    hour = hour | isPM;
  }  
}  
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(decToBcd(second));    // 0 to bit 7 starts the clock
Wire.send(decToBcd(minute));
Wire.send(hour);                                      //already formatted with bits 6 and 5
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();
}
#endif

// Gets the date and time from the ds1307
void getClock(byte *second,
         byte *minute,
         byte *hour,
         byte *dayOfWeek,
         byte *dayOfMonth,
         byte *month,
         byte *year,
         byte *ampm)
{
 byte work;
 byte mode;          //12 or 24 hour
 byte ap_ind;       //am or pm indicator
 
 // Reset the register pointer
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.send(0);
 Wire.endTransmission();

 Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

 // A few of these need masks because certain bits are control bits
 *second     = bcdToDec(Wire.receive() & 0x7f);      //mask CH bit (bit 7)
 *minute     = bcdToDec(Wire.receive());

//  *hour = bcdToDec(Wire.receive());
 work = Wire.receive();                                                // get hour byte
 mode = work & is12HR;                                                 // if bit  6  high,  running 12 hour mode
 if (mode == is12HR) {
   ap_ind =  work & isPM;                                           // if bit 5 high, it's P M
   *hour = bcdToDec(work & 0x1f);                             // mask bits 5 thru 7 for 12 hour clock
   if (ap_ind == isPM) {
     *ampm = 'P';
   }else{
     *ampm = 'A';
   }  
 }else{  
   *hour = bcdToDec(work & 0x3f);                             // mask bits 6 and 7 for 24 hour clock
   *ampm = ' ';  
 }  

 *dayOfWeek  = bcdToDec(Wire.receive());
 *dayOfMonth = bcdToDec(Wire.receive());
 *month      = bcdToDec(Wire.receive());
 *year       = bcdToDec(Wire.receive());
}

#ifdef SETCLOCK
int getSerStr(char line[], int lim) {
 int bytesread=0;
 int val=0;
 while(bytesread<lim) {              
   if( Serial.available() > 0) {
     val = Serial.read();
     if((val == 10) || (val == 13) || (val == '*')) {        
       break;                               // stop reading
     }
     line[bytesread] = val;             // add the digit          
     bytesread++;                     // ready to read next character  
   }
  }
  line[bytesread] = '\0';                              //terminate string  
  return(bytesread);
}

int getSerStrWait(char line[], int lim, int waitms) {
 int bytesread=0;
 int val=0;
 unsigned long start = millis();
 
 while(bytesread<lim) {              
   if( Serial.available() > 0) {
     val = Serial.read();
     if((val == 10) || (val == 13) || (val == '*')) {        
       break;                               // stop reading
     }
     line[bytesread] = val;             // add the digit          
     bytesread++;                     // ready to read next character  
   }
   if (millis() - start > waitms) {
     Serial.flush();
     line[0] = '\0';
     return(0);
   }  
  }
  line[bytesread] = '\0';                              //terminate string  
  return(bytesread);
}
#endif

//BCD to decimal conversion: decVal =(bcdVal.NIB1 * 10) + bcdVal.NIB0
//decimal to BCD conversion: bcdVal = (decVal / 10 <<4) + bcdVal // 10

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
 return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
 return ( (val/16*10) + (val%16) );
}

// Stops the DS1307, but it has the side effect of setting seconds to 0
// Probably only want to use this for testing
/*void stopDs1307()
{
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.send(0);
 Wire.send(0x80);
 Wire.endTransmission();
}*/

retrolefty

#1
Jun 05, 2009, 12:42 am Last Edit: Jun 05, 2009, 12:43 am by retrolefty Reason: 1
Probably not the last non-core library code that will break with a IDE version upgrade. It would be near impossible for the Arduino team to test and fix all user contributed non IDE core libraries with each version upgrade, it's just the nature of the beast I guess.

Lefty

macegr

But then, a lot of other projects will wait a while between freezing a release and actually shipping it to the public, to give developers a chance to catch up. You can see the readme.txt with 0016 was updated on May 30th, and most of the changes in 0016 were all dumped in at the same time on May 24th. Granted, the timer modification is probably what's messing with NewSoftSerial and that was checked in on the 12th. Not sure about that.

But it would not hurt to zip up everything that supposed to be the new release, and make an announcement in the forums here, about two weeks before the public release. It's called a beta, or release candidate...the publicly available code probably should not be stuff that's only been in SVN for 5 days.
Unique RGB LED Modules and Arduino shields: http://www.macetech.com/store

follower

Quote
It would be near impossible for the Arduino team to test and fix all user contributed non IDE core libraries with each version upgrade, it's just the nature of the beast I guess.

I'm working on some regression testing infrastructure that will hopefully improve this situation. My aim is to test (at least at the compilation stage initially) third-party libraries against SVN revisions of the IDE/core.

--Phil.

follower

Quote
But it would not hurt to zip up everything that supposed to be the new release, and make an announcement in the forums here, about two weeks before the public release. It's called a beta, or release candidate...

Actually, that does happen but it happens on the developer mailing list. e.g. [Developers] Arduino 0016 RC3 available.

--Phil.

macegr

Still...that was May 30th, only a few days before the public release. Maybe that is enough time, I don't know.
Unique RGB LED Modules and Arduino shields: http://www.macetech.com/store

madworm

The last time the openSUSE team decided to release a distribution to the public "just because" the 6 month schedule "had to be met" it was utterly bug ridden and a disgrace. It was V10.3, but that doesn't matter here.

Yes, there was a feature freeze date.
But the testing phase was just too short and done too sloppily, not even the rescue system on the DVD worked (takes 2 minutes to test that).

I feel we don't need that here.

• Upload doesn't work? Do a loop-back test.
• There's absolutely NO excuse for not having an ISP!
• Your AVR needs a brain surgery? Use the online FUSE calculator.
My projects: RGB LED matrix, RGB LED ring, various ATtiny gadgets...
• Microsoft is not the answer. It is the question, and the answer is NO!

mikalhart

#7
Jun 06, 2009, 08:36 am Last Edit: Jun 06, 2009, 08:49 am by mikalhart Reason: 1
Ron,

I am unable to reproduce the trouble you are seeing with 0016 and NewSoftSerial.  Actually, I had a lot of trouble when I first tried 0016, but then I realized that I hadn't deleted my library .o files when I copied them over from 0015.  Did you delete all the library binaries?

Could you try a simple test of, say, printing "Hello" to the LCD?  Does "regular" SoftSerial work?  That should be an easy test.

Is anyone else experiencing any unexplained behavior with NewSoftSerial?

Mikal

mikalhart

Ron, I just completed a run testing every baud rate from 300 to 115.2K with NewSoftSerial 9 under Arduino 0016 (Windows) and didn't see any TX problem.  TX is the easy part of soft serial and 9600 is pretty slow.  I'm starting to suspect something else is wrong.  What operating system are you developing with?

Mikal

Ron C

Mikal,
 I am using XP Pro.  I tried the program using 2 different LCDs - one using a MAX233A line driver and one using TTL input.
The same data is being sent to the serial monitor as well as the LCD.

The serial monitor is accurate but the LCD is messed up under version 016.


Ron C

I tried just a simple program to display my name on both the serial monitor and the LCD.
The the serial monitor text is affected by presense NewSoftSerial print.
It shows a question mark at the end of my name on the PC unless I comment out the NewSoftSerial print in the loop.
Code: [Select]


#include <NewSoftSerial.h>
#define lcdcmd        0xFE   //command prefix
#define lcdcmd2      0x7C   //special command prefix
#define clrLCD        0x01   //Clear entire LCD screen
#define displayOff   0x08   //Display off
#define displayOn   0x0C   //Display on
#define noCurs       0x0C   //Make cursor invisible
#define ulCurs        0x0E   //Show underline cursor
#define blkCurs      0x0D   //Show blinking block cursor
#define curpos       0x80   //set cursor  + position  (row 1=0 to 15, row 2 = 64 to 79)
#define scrollRight 0x1C
#define scrollLeft   0x18
#define curRight    0x14
#define curLeft      0x10

 NewSoftSerial mySerial(255, 3);        //tx only


void setup()
{
 Serial.begin(9600);
 mySerial.begin(9600);
 mySerial.print(lcdcmd, BYTE);
 mySerial.print(clrLCD, BYTE);
 
 mySerial.print(lcdcmd, BYTE);
 mySerial.print(displayOn , BYTE);

}

void loop()
{
Serial.println("Ron Czapala");

//Commenting this line affects the above println
  mySerial.print("Ron Czapala");    
 
delay(1000);
}

Ron C

Mikal,

Deleting the .o files in the library folder fixed the problem.

I am new to this development environment - are these object files?
If so, I assume they are recompiled the first time you compile a sketch that uses them.

Thanks for the tip!

- Ron :)

mikalhart

Yes, Ron, the .o files are the compiled versions of the source.  Unfortunately, I think the only time the libraries are recompiled is when you delete the .o files, or possibly if you select a different species of Arduino board.  In any case, I learned soon enough that an 0015 binary will not work in 0016.

I'm relieved that your problem is solved.  Thanks for sharing.

Mikal

capt.tagon

#13
Jun 09, 2009, 02:50 am Last Edit: Jun 09, 2009, 02:51 am by Sean Reason: 1
Heh, not the first time something like this has bunged me up.

We need fresh installs of the Arduino IDE to set a flag that clears after the fifth startup, its purpose, to shut off the following message displayed in flaming letters 30 feet high:
"DELETE ALL NON-CORE  LIBRARY OBJECT FILES (*.o)"  ;)

Ron C

#14
Jun 09, 2009, 04:45 am Last Edit: Jun 09, 2009, 04:45 am by ronczap Reason: 1
;D

Yeah - newbies like me have to learn the hard way!  I guess I should have just reinstalled the extra libraires rather than copying them into library folder for the new version.

Maybe a WARNING.txt readme file could explain the process.


Go Up