logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATmega8][C#] problem z przesyłaniem danych na serialPort

webmortiz 17 Sty 2010 23:14 1939 2
REKLAMA
  • #1 7552210
    webmortiz
    Poziom 20  
    Mimo iż problem dość popularny zapytam bo nie znalazłem dogodnego mi rozwiązania.

    Mam do wysłania 2 liczby. Jedna z zakresu 0-10 druga 0-5000. Ta druga nie mieści się w jednym bajcie więc rozkładam ją na dwa bajty po stronie C#. Dodam że encoding na serialPorcie mam ustawiony na UTF8. A wygląda to tak:
    
    string amplituda = (Convert.ToChar(Int16.Parse(seAmpl.Value.ToString()))).ToString();
    int x = Convert.ToInt16(seFreq.Value);
    int low = (x & 0x00FF);
    int high = ((x & 0xFF00) >> 8);
    string freqLow = (Convert.ToChar(low).ToString());
    string freqHigh = (Convert.ToChar(high).ToString());
    string toSend = stale.UPLOAD_PARAMS + amplituda + freqLow + freqHigh + "\r\n";
    serialPort.Write(toSend);
    


    UPLOAD_PARAMS mówi mikrokontrolerowi "teraz dostaniesz 2 liczby w 3 bajtach, złów 2 ostatnie bajty w jedną liczbę i zapisz do epromu, a odbiór wygląda tak (pierwszy bajt to wlasnie ten UPLOAD_PARAMS):
    
    Diode(1);
    if (counter<4) 
    {
         params[counter]=returner;
         counter++;
    }
    else
    {
         counter=0;
         for (int i=1; i<4; i++) toEeprom((270+i), params[i]);
         amplituda = params[1];
         frequency = (params[3] << 8) | params[2];
         Diode(0);
         mode = 0;
    }
    


    a odsyłanie po stronie procka:

    
    Diode(1);
    send("n");
    sendbyte(fromEeprom(271));
    sendbyte(fromEeprom(272));
    sendbyte(fromEeprom(273));
    send("\r\n");
    mode = 0;
    Diode(0);
    


    Pierwsza jedno bajtowa liczba zawsze jest wysyłana w dwie strony dobrze, druga jeśli wyślę liczbę mniejszą niż 127 też jest dobrze, jeśli nieco większą nie wraca wogóle 3 bajt lub są przekłamania. Dla przykłądu wysyłam 3 i 12. Na quick watchu w Visual studio widzę 3 bajty do wysłania, 3, 12 i 0 i dokładnie to samo do mnie wraca. Jeśli wyślę 3 i 4566 3 przychodzi jak jest, a 4566 rozłożone na 2 bajty tylko jeden z nich jest prawidłowy a drugiego nie ma wcale lub też się zdarzało że pojawiała się zawsze wartość 112.
    Na pokładzie ATmegi leży kwarc 8 MHz a fusebity mam ustawione tak:
    [ATmega8][C#] problem z przesyłaniem danych na serialPort


    Gdzie może leżeć probem?
  • REKLAMA
  • Pomocny post
    #2 7552517
    serum
    Poziom 16  
    Nie znalazłem błędu w Twoim kodzie. Mogę tylko napisać jak ja robię konwersję Inta i przesyłam go przez RS'a
    
                Int32 i = 124578 ;
                byte[] a = BitConverter.GetBytes(i);
                Array.Reverse(a);
                serialPort1.Write(a, 0, a.Length);
    

    z Int16 też powinno działać

    PS. Ktoś mi kiedyś mówił, że char nie może przyjmować wartości większych od 127 chyba że się go zadeklaruje jako unsigned. Osobiście nigdy się z tym nie spotkałem ale może właśnie masz taki problem bo wszystko konwertujesz do charów.
  • #3 7556621
    webmortiz
    Poziom 20  
    Ok, okazało się że tak na prawdę są dwa problemy, pierwszy z tym char, więc powzorowałem się na propozycji kolegi serum. Drugi probelm dotyczył enkodowania na serialPorcie. Ani ASCII ani UTF8 nie pasowały do tego co chciałem zrobić tak więc udało mi się wygrzebać jak ustawić kodowanie. Co się zmieniło

    fragment
    
    string amplituda = (Convert.ToChar(Int16.Parse(seAmpl.Value.ToString()))).ToString();
    int x = Convert.ToInt16(seFreq.Value);
    int low = (x & 0x00FF);
    int high = ((x & 0xFF00) >> 8);
    string freqLow = (Convert.ToChar(low).ToString());
    string freqHigh = (Convert.ToChar(high).ToString());
    string toSend = stale.UPLOAD_PARAMS + amplituda + freqLow + freqHigh + "\r\n";
    serialPort.Write(toSend);
    


    zmienił się na
    
    int ampl = Convert.ToInt16(seAmpl.Value);
    int x = Convert.ToInt32(seFreq.Value);
    int low = (x & 0x00FF);
    int high = ((x & 0xFF00) >> 8);
    
    byte[] bytArray = new byte[4];
    bytArray[0] = (byte)stale.UPLOAD_PARAMS[0];
    bytArray[1] = (byte)seAmpl.Value;
    bytArray[2] = (byte)((int)(seFreq.Value) & 0x00FF);
    bytArray[3] = (byte)(((int)(seFreq.Value) & 0xFF00) >> 8);
    serialPort.Write(bytArray, 0, bytArray.Length);
    


    a kodowanie: serialPort.Encoding = Encoding.GetEncoding(28591);

    Mam nadzieję że to rozwiązanie będzie pomocne także innym. Temat zamykam i pozdrawiam.
REKLAMA