Att jämföra sträng på rätt sätt?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Att jämföra sträng på rätt sätt?

Inlägg av newbadboy »

Har ett program där jag skickar ordet "Post" från en uart TX till en uart RX. I mottagar delen försöker jag kolla varje cell med if satser men jag förstår att detta inte är helt säkert att göra då jag alltid behöver sända en hel del ggr innan alla if satser går genom och jag får ut textet "du har ny post" på displayen. Och ibland missar den trigga helt faktiskt.

Rätt ofta får jag även konstiga tecken och hängningar oxå.

Signalen in på RX pinnen till Ic´n är verifierad med logikanalysator och det kommer inget skräp alls utan bara ordet "post" så hådvarumässigt är det ok!

Kod: Markera allt

if(uart_rd[0]=='P'){
               if(uart_rd[1]=='o')
                 if(uart_rd[2]=='s')
                   if(uart_rd[3]=='t'){
                                       delay_ms(100);
                                       BACKLIGHT=1;
                                       LCD_Cmd(_LCD_CLEAR);
                                       Lcd_out(1,1,"Du har ny post!");
                                       LOADSWITCH=1;
                                       BUZZER=1;
                                       delay_ms(200);
                                       BUZZER=0;
                                       delay_ms(200);
                                       BUZZER=1;
                                       delay_ms(200);
                                       BUZZER=0;
                                       delay_ms(200);

                                       while(SETRST==0){
                                            BACKLIGHT=1;
                                            }
                                      }


                }
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Att jämföra sträng på rätt sätt?

Inlägg av johano »

Vad är det för plattform & kompilator?
Kan du visa koden som läser in uart_rd?

Om uart_rd verkligen innehåller "Post" så kommer din kod fungera. Så det är alltså inte kontrollen som strular
utan att uart_rd inte innehåller det du tror att den gör.

/j
Användarvisningsbild
Synesthesia
Inlägg: 573
Blev medlem: 22 januari 2010, 19:14:10
Ort: Mellan Göteborg och Kungsbacka

Re: Att jämföra sträng på rätt sätt?

Inlägg av Synesthesia »

Är buffringen som den skall? Det är möjligen inte så att serie-data kommer in via interrupt och du läser av i main?
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43148
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Att jämföra sträng på rätt sätt?

Inlägg av sodjan »

Det skulle kanske vara effektivare (mindre kod och bättre prestanda)
genom att använda någon av de strängfunktioner som brukar finnas i C.
(Ja, jag vet att det rent formellt inte ligger i C i sig, utan i biblioteken...)

Sen är det ju frågan *när* koden ovan körs? Vad är det som triggar det?
Skickas det enbart "Post" eller skickas det även CR och/eller LF?

Det syns inte i den visade koden, men någonstans måste du ju även sätta
pekaren till bufferten till början igen för att ta emot nästa packet.

Det vanliga är nog att man fyller på en buffert (skulle kunna vara uart_rd)
och när en speciell avslutare ("terminator") kommer in, så analyserar man
vad som finns i bufferten. Eventuellt kopierar man först bufferten snabbt till
en ny area så att huvudbufferten direkt är tillgänglig för att ta emot nästa
packet under tiden som man analyserar och agerar på föregående paket.
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Att jämföra sträng på rätt sätt?

Inlägg av newbadboy »

johano skrev:Vad är det för plattform & kompilator?
Kan du visa koden som läser in uart_rd?

Om uart_rd verkligen innehåller "Post" så kommer din kod fungera. Så det är alltså inte kontrollen som strular
utan att uart_rd inte innehåller det du tror att den gör.

/j
Kompilatorn mikroC.

Med plattform menar du HW eller sw

Fullständig kod se nedan
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Att jämföra sträng på rätt sätt?

Inlägg av newbadboy »

Synesthesia skrev:Är buffringen som den skall? Det är möjligen inte så att serie-data kommer in via interrupt och du läser av i main?

Ojoj, vet inte vad som menas med buffringen i detta fall. Sorry för min okunskap
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Att jämföra sträng på rätt sätt?

Inlägg av newbadboy »

sodjan skrev:Det skulle kanske vara effektivare (mindre kod och bättre prestanda)
genom att använda någon av de strängfunktioner som brukar finnas i C.
(Ja, jag vet att det rent formellt inte ligger i C i sig, utan i biblioteken...)

Sen är det ju frågan *när* koden ovan körs? Vad är det som triggar det?
Skickas det enbart "Post" eller skickas det även CR och/eller LF?

Det syns inte i den visade koden, men någonstans måste du ju även sätta
pekaren till bufferten till början igen för att ta emot nästa packet.

Det vanliga är nog att man fyller på en buffert (skulle kunna vara uart_rd)
och när en speciell avslutare ("terminator") kommer in, så analyserar man
vad som finns i bufferten. Eventuellt kopierar man först bufferten snabbt till
en ny area så att huvudbufferten direkt är tillgänglig för att ta emot nästa
packet under tiden som man analyserar och agerar på föregående paket.
Som uart överföring använder jag tx/rx 433MHz modulerna från Swech och det är alltså pinnen som är rx kopplad till PICen som jag verifierat rena datasignaler!
Kod nedan.

Kod: Markera allt

char uart_rd[20];
int i;

// Defining IO name
#define LOADSWITCH PORTA.F3
#define BUZZER PORTA.F4
#define SETRST PORTB.F3
#define BACKLIGHT PORTA.F2

//LCD module connection
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RA6_bit;
sbit LCD_D5 at RA7_bit;
sbit LCD_D6 at RA0_bit;
sbit LCD_D7 at RA1_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISA6_bit;
sbit LCD_D5_Direction at TRISA7_bit;
sbit LCD_D6_Direction at TRISA0_bit;
sbit LCD_D7_Direction at TRISA1_bit;
//End LCD module connection


void Init_Main(){
APFCON0=0b00000000;
OSCCON=0b01101000;      //4Mhz
C1ON_bit=0;
SRLEN_bit=0;


TRISA=0b00000000;
TRISB=0b00001010;
ANSELA=0b00000000;
ANSELB=0b00000000;
ADCON0=0b00000000;
ADCON1=0b00000000;

UART1_Init(9600);

LOADSWITCH=0;
BUZZER=1;
BACKLIGHT=1;
LCD_Init();
LCD_Cmd(_LCD_CURSOR_OFF);
LCD_Cmd(_LCD_CLEAR);
Lcd_out(1,1,"HusDiag R1.0");
Lcd_out(2,1,"Karoly.S 2017");
BUZZER=0;
for(i=0; i<20; i++){
    delay_ms(100);
    }
LCD_Cmd(_LCD_CLEAR);
Lcd_out(1,1,"Sensorer OK");
Lcd_out(2,1,"inget larm");
BACKLIGHT=0;

}

void LightUp(){
    BACKLIGHT=1;
    BUZZER=1;
    delay_ms(100);
    BUZZER=0;
    delay_ms(2000);
    BACKLIGHT=0;
    }

void Recieve(){
 if(UART1_Data_Ready()==1){

       UART1_Read_Text(uart_rd,"\n",255);

       if(uart_rd[0]=='D'){
         if(uart_rd[1]=='r')
            if(uart_rd[2]=='a')
               if(uart_rd[3]=='n')
                  if(uart_rd[4]=='a')
                     if(uart_rd[5]=='g')
                        if(uart_rd[6]=='e'){
                                       LCD_Cmd(_LCD_CLEAR);
                                       Lcd_out(1,1,"Dränering full");
                                       Lcd_out(2,1,"pumpa ut vatten!");
                                       LOADSWITCH=1;
                                       }
                        }
                                       
        else if(uart_rd[0]=='P'){
               if(uart_rd[1]=='o')
                 if(uart_rd[2]=='s')
                   if(uart_rd[3]=='t'){
                                       delay_ms(100);
                                       BACKLIGHT=1;
                                       LCD_Cmd(_LCD_CLEAR);
                                       Lcd_out(1,1,"Du har ny post!");
                                       LOADSWITCH=1;
                                       BUZZER=1;
                                       delay_ms(200);
                                       BUZZER=0;
                                       delay_ms(200);
                                       BUZZER=1;
                                       delay_ms(200);
                                       BUZZER=0;
                                       delay_ms(200);

                                       while(SETRST==0){
                                            BACKLIGHT=1;
                                            }

                                        }

                }

    LCD_Cmd(_LCD_CLEAR);
    Lcd_out(1,1,"Sensorer OK");
    Lcd_out(2,1,"inget larm");
    BACKLIGHT=0;
    LOADSWITCH=0;


    }
 }




void main() {
   Init_Main();
   while (1){
        if(SETRST==1)
           LightUp();
        
        Recieve();
        }
   }

det som också gör mig lite mörkrädd är varifrån kommer alla hittepå tecken jag får ut i displayen. Display texten är ju satt på ett par rader och är alltså inte "dynamisk".
Senast redigerad av newbadboy 28 juni 2017, 18:17:24, redigerad totalt 2 gånger.
Användarvisningsbild
Jan Almqvist
Inlägg: 1580
Blev medlem: 1 oktober 2013, 20:48:26
Ort: Orust

Re: Att jämföra sträng på rätt sätt?

Inlägg av Jan Almqvist »

Att ta emot och tolka sådant som kommer på seriekanal är mycket svårare än man kan tro. I mitt tycke är t.ex. delay_ms() och liknande totalt bannlyst och man måste ha en riktig hantering av timeout så att telegrammottagaren kan hitta rätt igen när det kommer skräp eller bara delar av meddelanden.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43148
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Att jämföra sträng på rätt sätt?

Inlägg av sodjan »

Ah, OK. Jag har inte kollat dokumentationen, men jag antar att
"UART1_Read_Text(uart_rd,"\n",255);" läser upp till 255 tecken
eller till nästa LF. Sedan kollar du vad som har kommit in. Är väl
i princip OK, antar jag. Koden är alltså "fast" i UART1_Read_Text()
funktionen under hela mottagandet.

Det är ju viktigt att du skickar en "\n" efter varje kommando, annars
händer inget fören det har kommit 255 tecken och då kollas det första
kommandot i bufferten. Sedan behövs det 255 nya tecken innan nästa
koll sker. O.s.v...

"\n" motsvarar LF ("Line Feed") och det skickar du kanske aldrig. Om du
trycker "ENTER" så är det en CR ("Carriage Return"" som skickas och då
skulle det kunna fungera om du byter "\n" till "\r" (vilket betyder just CR)...

Jag är lite tveksam till om UART1_Data_Ready() behöver kollas, sannolikt
gör UART1_Read_Text() något motsvarande internt. Men jag tror inte
heller att det är just det som är problemet.

Prova att bara byta "\n" till "\r"...
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43148
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Att jämföra sträng på rätt sätt?

Inlägg av sodjan »

> I mitt tycke är t.ex. delay_ms() och liknande totalt bannlyst...

Ja, rent generellt och principiellt. :-)

I just detta fall så sker nog hela mottagandet i en och samma funktion,
så delay funktionerna körs inte under den tiden.
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Att jämföra sträng på rätt sätt?

Inlägg av newbadboy »

Jag håller med ang delays. Dock har jag ju medvetet inte använt den alls där uart läsning och sådant görs

edit: sodjan hann före
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Att jämföra sträng på rätt sätt?

Inlägg av newbadboy »

http://elektronikforumet.com/forum/view ... 46&t=87690


länken ovan hittar ni schema etc

Det är föressten pic16F1847 som använts med 4 Mhz intern oscilltor
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Att jämföra sträng på rätt sätt?

Inlägg av newbadboy »

sodjan skrev:Ah, OK. Jag har inte kollat dokumentationen, men jag antar att
"UART1_Read_Text(uart_rd,"\n",255);" läser upp till 255 tecken
eller till nästa LF. Sedan kollar du vad som har kommit in. Är väl
i princip OK, antar jag. Koden är alltså "fast" i UART1_Read_Text()
funktionen under hela mottagandet.

Det är ju viktigt att du skickar en "\n" efter varje kommando, annars
händer inget fören det har kommit 255 tecken och då kollas det första
kommandot i bufferten. Sedan behövs det 255 nya tecken innan nästa
koll sker. O.s.v...

"\n" motsvarar LF ("Line Feed") och det skickar du kanske aldrig. Om du
trycker "ENTER" så är det en CR ("Carriage Return"" som skickas och då
skulle det kunna fungera om du byter "\n" till "\r" (vilket betyder just CR)...

Jag är lite tveksam till om UART1_Data_Ready() behöver kollas, sannolikt
gör UART1_Read_Text() något motsvarande internt. Men jag tror inte
heller att det är just det som är problemet.

Prova att bara byta "\n" till "\r"...
Nixpix. Skickar varken \n eller \r. Ska prova och återkomma.
Användarvisningsbild
newbadboy
Inlägg: 2426
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Att jämföra sträng på rätt sätt?

Inlägg av newbadboy »

Med \n så funkar det oftare men oftast verkar det inte gå genom alla if satser. Men inga konstiga tecken i displayen

Med \r så fick jag inte en enda lyckad triggning däremot en massa skumma tecken och sådant
svanted
Inlägg: 5082
Blev medlem: 30 augusti 2010, 21:20:38
Ort: Umeå

Re: Att jämföra sträng på rätt sätt?

Inlägg av svanted »

char uart_rd[20];
//
UART1_Read_Text(uart_rd,"\n",255);

borde inte 20 vara 255 eller mer?

iom att du har "\n" som delimiter måste du skicka "\n" på slutet.
Skriv svar