|
|
View previous topic :: View next topic |
Author |
Message |
Mark Logan
Joined: 21 Oct 2009 Posts: 10
|
Sending command via SW_UART |
Posted: Tue Jan 05, 2010 9:38 am |
|
|
Hello again everyone,
I am sending the command "?PRE\r" via software UART to a digital pressure gauge, which is supposed to return the pressure from the gauge and display it on a touchscreen LCD. I have the data reception code pretty much worked out, I am just having trouble actually getting data from the gauge. I have connected the gauge to my computer's serial port and sent this command via hyperterminal and it worked just fine. I hooked the MCU up to the serial port on my computer and used PICC's serial port monitor to see what the MCU was sending and I think I have found out the problem. For some reason the MCU is sending this hex line:
34 3F 50 52 45 0D
(4)(?)(P)(R)(E)(\r)
sometimes it also sends this:
34 04 3F 50 52 45 0D
(4)(EOT)(?)(P)(R)(E)(\r)
unless I am mistaken the end of transmission character is otherwise harmless, but I have no idea why the MCU is sending a 4 before the command. I am fairly certain this is confusing the gauge and this is why I am not getting any data back from it. I have looked through my code and nowhere am I sending any other characters via the UART than the ?PRE command. Any ideas?
Here is all pertinent code:
Code: |
//VARS
short LCDrcvd=false; //rcvd from LCD
short btnpress=false; //button pressed
short reading=true; //analog reading
char gaugedat[]; //ASCII reading from Crystal Digital Gauge
char gaugecmd[5]={'?','P','R','E',0x0d};
//PROCESSES RPC COMMANDS FROM LCD
void PSIRPC(void)
{
set_ERR(2);
setup_wdt(WDT_ON);
switch ( buffer[0] )
{
case INVOKERPCREQUEST: //RPC COMMAND
switch ( buffer[2] )
{
case 0x31: //"1" SEND TO PC
testdl();
break;
case 0x32: //"2" CLEAR MEMORY EEPROM
clear_mem();
break;
case 0x33: //"3" INITIALIZE
setInit();
break;
case 0x34: //"4" refresh stored location
refresh_LCD();
break;
case 0x37: //"7" slot +
incslot();
refresh_LCD();
break;
case 0x38: //"8" slot -
decslot();
refresh_LCD();
break;
case 0x39: //"9" pipe +
dblstate = get_LCD(0x30,0x39);//getnine();
incpipe();
refresh_LCD();
break;
case 0x41: //"10" pipe -
dblstate = get_LCD(0x30,0x39);//getnine();
decpipe();
refresh_LCD();
break;
case 0x42: //"11" change upper/lower on LCD
if (dblstate == 1)
dblstate = 0;
else
dblstate = 1;
refresh_LCD();
break;
}
break;
}
setup_wdt(WDT_OFF);
}
//INITIALIZES PIC
void initPSI(void)
{
set_ERR(1);
setup_wdt(WDT_ON);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_low_volt_detect(FALSE);
setup_oscillator(False);
output_float(EXT_BUTTON);
ext_int_edge(0,H_TO_L);
ext_int_edge(2,L_TO_H);
set_timer1(0);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_RDA);
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT2);
enable_interrupts(GLOBAL);
setup_wdt(WDT_OFF);
}
void PSI(void)
{
int parta,partb,partc;
int32 temp32;
tubetype=0;
TUBETEST=0;
initPSI();
fprintf(LCD_UART,"%C%C%C%C%C%X",LCD_SET_WORD,0x30,0x39,0x30,0x30,PSI_VER); //version number
delay_ms(dt);
dblval = get_LCD(0x36,0x38);//getdouble();
fprintf(LCD_UART,"%C%C%C%C%C",LCD_SET_STRING,0x30,0x31,0x57,0x00);
fprintf(LCD_UART,"%C%C%C%C%C",LCD_SET_STRING,0x30,0x34,'A',0x00);
while(!input(EXT_BUTTON)); //pause at boot when button is down
delay_ms(500);
setinit();//debug 2nd time fixes it????
fprintf(LCD_UART,"%C%C%C%C%C",0xA0,0x02,0x00,0x38,0x26); //goto 'index.html'
flag12=false;
fprintf(LCD_UART,"%C%C%C%C%C%X",LCD_SET_WORD,0x30,0x39,0x30,0x30,1); //clears version number
while(1)
{
if (batlow==0)
{
Battery();
}
if(LCDrcvd)
{
set_ERR(19);
setup_wdt(WDT_ON);
fprintf(LCD_UART,"%C%C%C",0xE8,buffer[1],buffer[2]);
delay_ms(dt);
PSIRPC();
fprintf(LCD_UART,"%C%C%C%C%C",LCD_SET_BYTE,0x36,0x36,0x32,0x30); //var 102
buffer[0]=0x00;
LCDrcvd=false;
setup_wdt(WDT_OFF);
}
if(flag11)
{
delay_ms(50); //debug (random reset to pipe 1-2)
set_ERR(20);
setup_wdt(WDT_ON);
if(flag11) //debug (same)
{
setInit();
}
flag11=false;
setup_wdt(WDT_OFF);
}
if(btnpress)//store value in EEPROM
{
//delay_ms(200);
set_ERR(21);
setup_wdt(WDT_ON);
delay_ms(5);
if (input(EXT_BUTTON))//debounce
{
fprintf(LCD_UART,"%C%C%C%C%C",LCD_SET_BYTE,0x36,0x36,0x32,0x30); //flag11 timeout
output_bit(WRTLED,1);
delay_ms(100); //delay added to ensure eeprom read/write
getmem();
parta=make8(temp32,0);
partb=make8(temp32,1);
partc=make8(temp32,2);
ext_write(address1,partc,EEPROM_PSI );
ext_write(address1+1,partb,EEPROM_PSI );
ext_write(address1+2,parta,EEPROM_PSI );
getmatrix();
ext_write(address1,PSI_LOADED,EEPROM_PSI);
delay_ms(150);//lets EEPROM store correct data (10/7/09 increased delay time to ensure eeprom write)
dblstate = get_LCD(0x30,0x39);//getnine();
delay_ms(5);
incpipe();
delay_ms(5); //delay to ensure incpipePSI
refresh_LCD();
btnpress=false;
output_bit(WRTLED,0);
}
//btnpress=false;
setup_wdt(WDT_OFF);
}
if (reading)//read&output converted data (reading)
{
set_ERR(22);//add serial command
setup_wdt(WDT_ON);
fprintf(SW_UART,gaugecmd);//sends command ?PRE\r to gauge
delay_ms(5);//5 bytes at 9600 BAUD = 4.1ms
//fgets(gaugedat,SW_UART);
fprintf(LCD_UART,"%C%C%C%S%C",LCD_SET_STRING,0x31,0x38,gaugedat,0x00);
delay_ms(dt);
reading=false;
setup_wdt(WDT_OFF);
}
}
}
|
All code is working except for the command being sent via the UART (if(reading) loop), I keep getting the rogue ASCII 04 in there for some reason. Here is my INT_EXT:
Code: |
#int_EXT//ISR for receiving a character from digital pressure gauge, triggered on falling edge (start bit)
void isr_ext0_isr(void)
{
output_bit(PWRLED,0);
output_bit(BATLED,1);//LED indicator to alert when ISR is triggered
fgets(gaugedat,SW_UART);
}
|
When I use my computer hooked up to the MCU via serial, I type a string, press enter, and the LED indicator turns on, and the string I typed is displayed. When the pressure gauge is connected though, the LED indicator does not even change, meaning I am not managing to get a rise (or a fall), so to speak, from the gauge. I am assuming it is because I am getting that weird 4 in the command line. Anyone have any ideas why this 4 is appearing? I thank you in advance for your help.
Mark |
|
|
Mark Logan
Joined: 21 Oct 2009 Posts: 10
|
|
Posted: Tue Jan 05, 2010 10:15 am |
|
|
I forgot to mention the format of the pressure gauge's returned value. It is as follows:
[newline] 0.00, inH20\r
The carriage return at the end means fgets SHOULD work, but it is not even sending a line of ASCII back to trigger the ISR so I am assuming it's because that 4 is in the beginning of the command.
Mark |
|
|
Mark Logan
Joined: 21 Oct 2009 Posts: 10
|
|
Posted: Tue Jan 05, 2010 1:17 pm |
|
|
Anybody? Or am I just being thick and can't see the answer right in front of me, it wouldn't surprise me. |
|
|
Ttelmah Guest
|
|
Posted: Tue Jan 05, 2010 1:59 pm |
|
|
Remember the software UART, does it's timings, by simple instruction counting. If an interrupt occurs while a character is being sent, it will be corrupted.....
You have several interrupts enabled, whose code you don't show, but as shown, INT_EXT, could stay inside the interrupt code for ever....
Best Wishes |
|
|
Mark Logan
Joined: 21 Oct 2009 Posts: 10
|
|
Posted: Tue Jan 05, 2010 2:13 pm |
|
|
Thanks Ttelmah,
I am aware that INT_EXT could hang if not receiving a carriage return, this is kind of what I was going for. The problem is, nothing is being sent from the gauge as the indicator that I am in INT_EXT is not even being triggered. Upon receiving the command, the gauge should start sending data, which it does not even do. I am thinking this is because of the 4 that is showing up in my UART. There is nothing in my code that sends a 4 over the UART, yet this is happening for anything I send over the UART. This is more than likely causing an invalid command, thus rendering the interrupt useless as no data is even being sent. I'm more concerned about why my UART keeps getting a 4 in it than the timing for getting strings, I think this will work once I have actual data coming in over the UART. Could this be a result of something in my #USE RS232 statement? I changed
Code: |
fprintf(SW_UART,gaugecmd);//sends command ?PRE\r to gauge |
to
Code: |
fputs(gaugecmd,SW_UART);
|
in order to ensure nothing is happening while the command is being sent, and now I'm getting this on the serial port monitor:
21 53 50 31 0D
34 04 0D
So for some reason I'm still getting that 4 before the EOT, the only difference is that a line feed is being used after the command because of the fputs(). I guess my question is why?
Thanks again,
Mark |
|
|
Mark Logan
Joined: 21 Oct 2009 Posts: 10
|
|
Posted: Tue Jan 05, 2010 2:20 pm |
|
|
I just realized that was for another serial command I was sending as a test. It's not going to match up with the ASCII for ?PRE\r, but it is the same idea. Still getting a 34 04 at the end which doesn't seem right to me.
Mark |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 05, 2010 3:37 pm |
|
|
Then temporarily substitute the hardware UART for the software UART.
See if you still get the problem. |
|
|
Mark Logan
Joined: 21 Oct 2009 Posts: 10
|
|
Posted: Tue Jan 05, 2010 3:45 pm |
|
|
Thanks PCM,
Unfortunately the HW UART is dedicated to sending/receiving the data buffer from the LCD touchscreen so using it is not an option. It seems like SW UART is the most attractive option here, if I can't get it to work I have some external HW UART chips with serial interface, I can try to use those but I consider that a last resort...
Mark |
|
|
Ttelmah Guest
|
|
Posted: Tue Jan 05, 2010 3:47 pm |
|
|
Remember, when I am talking about the timings being interfered with, this affects every character _sent_, as well as giving receive problems. You have timer interrupts enabled. If one of these occurs 'mid character', on the transmission, you _will_ get an elongated character, whose interpretation will depend on where in the character the elongation occurs....
Try adding the 'DISABLE_INTS' option to the software RS232 setup, and see if this changes things....
Best Wishes |
|
|
Mark Logan
Joined: 21 Oct 2009 Posts: 10
|
|
Posted: Tue Jan 05, 2010 4:07 pm |
|
|
Thanks for your replies,
I added 'DISABLE_INTS' to the stream definition, didn't seem to do much. I changed the command to a simple "HELLO" to see what would happen, and I didn't get the 34 04 0D at the end of the transmission so I'm assuming something is happening when I put the carriage return at the end of the array. I'm going to look into alternatives for the
Code: |
char gaugecmd[5]={'?','P','R','E',0x0d};
|
Maybe putting '\r' instead will solve the problem.
Thanks again,
Mark |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 05, 2010 4:31 pm |
|
|
Create a small dedicated test program to test this problem.
This program should only contain the software UART code,
to receive the characters, and some method to display them.
This program will not contain a lot of useless "Wizard" code.
Don't use any interrupts in this test program. Disable Global interrupts.
Capture an entire incoming message, and then display the message.
i.e. operate in half-duplex mode.
If you still have problems, then post the complete test program
and your compiler version. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|