Googla på Xon & XoffAl_Bundy skrev:
Fram och tillbaka, fram och tillbaka...
Är det en loop som läser av värdet på COMporten?
Re: Är det en loop som läser av värdet på COMporten?
Re: Är det en loop som läser av värdet på COMporten?
Utveckla vidare. Handskakningen är till för kommunikation för att....?sodjan skrev:> Men kan man verkligen ha handskakning på USB som AVR:en kan kontrollera?
Hårdvaruhandskakning kan vara pyssligt.
Programvaruhandskakning är självklart inget som helst problem,
det är helt oberoende av hur "linjen" ser ut mellan de två parterna
och du har 100% kontroll i din egen kod över det.
> Handskakningen är väll till för att anropa/förvarna att något kommer och motsidan måste vara beredd?
Nej, det skulle jag inte säga. Det är som att ropa till någon och kasta en boll samtidigt
utan att kontrollera att mottagaran är beredd. Det är ingen handskakning. Du måste
vänta tills ("skaka hand" med) mottagaren faktiskt säger att han *är* beredd.
- Jan Almqvist
- Inlägg: 1655
- Blev medlem: 1 oktober 2013, 20:48:26
- Ort: Orust
Re: Är det en loop som läser av värdet på COMporten?
Jag tror nog att TS skulle spara mycket jobb på att göra så här:
Välj ett riktigt protokoll.
Låt PC:n vara master som pollar Arduino som är slav.
Provkör varje del för sej mot en beprövad simulator, eller annan enhet som kan vara både master och slav, dvs PC mot simulator och simulator mot Arduino.
Först när detta fungerar provar man PC mot Arduino.
Välj ett riktigt protokoll.
Låt PC:n vara master som pollar Arduino som är slav.
Provkör varje del för sej mot en beprövad simulator, eller annan enhet som kan vara både master och slav, dvs PC mot simulator och simulator mot Arduino.
Först när detta fungerar provar man PC mot Arduino.
Re: Är det en loop som läser av värdet på COMporten?
Det är väl inga problem att köra data från uC till PC utan protokoll.
Har själv kört i veckor med 115kbit kontinuerlig bit-ström utan handskakning mot Realterm som loggar detta i textfil (filerna blir dock rätt stora
)
Det beror ju naturligtvis vad PC'n gör mer, om det skall fungera, denna gjorde inget annat än just logga.
Så Bundy, funkar det inte så är det du som gör fel (eller dina kompisar på PC-sidan).
Har själv kört i veckor med 115kbit kontinuerlig bit-ström utan handskakning mot Realterm som loggar detta i textfil (filerna blir dock rätt stora

Det beror ju naturligtvis vad PC'n gör mer, om det skall fungera, denna gjorde inget annat än just logga.
Så Bundy, funkar det inte så är det du som gör fel (eller dina kompisar på PC-sidan).
Re: Är det en loop som läser av värdet på COMporten?
Med tanke på Al's generella förklaringar och sätt anser jag fortfarande att Al är källan till det mesta onda.
Men det är i grunden så att båda parter gör fel!
* Al gör fel vid att bara fläska ut data utan att ha koll på om det behövs och utan att ha kommunikation med "de andra".
* "De andra" gör fel vid att inte ha avtalat protokoll osv, dels inbördes och dels med Al och andra "externa".
Att kommunicera och skapa delar av ett projekt fungerar inte(!!!) om det inte finns tydliga och klara riktlinjer först!
Alltså avtalar man (i detta fall) ett protokoll, det kan vara challenge-responce eller hårdvara-handskakning, uppbyggning av värdens representation och i grunden allt som har med kommunikationen att göra. Innan det är klart är det knappast orsak att jobba med programmeringen.
Men med Al's eminenta kommunikationsförmåga - som visat så ofta i detta forum - lär det nog finnas ett protokoll varav Al uppfyller dataformatet men inget annat, helt enkelt för att det var tråkigt att läsa.
Men det är i grunden så att båda parter gör fel!
* Al gör fel vid att bara fläska ut data utan att ha koll på om det behövs och utan att ha kommunikation med "de andra".
* "De andra" gör fel vid att inte ha avtalat protokoll osv, dels inbördes och dels med Al och andra "externa".
Att kommunicera och skapa delar av ett projekt fungerar inte(!!!) om det inte finns tydliga och klara riktlinjer först!
Alltså avtalar man (i detta fall) ett protokoll, det kan vara challenge-responce eller hårdvara-handskakning, uppbyggning av värdens representation och i grunden allt som har med kommunikationen att göra. Innan det är klart är det knappast orsak att jobba med programmeringen.
Men med Al's eminenta kommunikationsförmåga - som visat så ofta i detta forum - lär det nog finnas ett protokoll varav Al uppfyller dataformatet men inget annat, helt enkelt för att det var tråkigt att läsa.

Re: Är det en loop som läser av värdet på COMporten?
Förefaller väldigt märkligt att utbildningsledaren inte kan ge eleverna rätt förutsättningar, om jag fattat det hela rätt så är det en Universitetskurs TS går - kan tycka att det på den utbildningsnivån borde vara bättre kvalitet än vad vi ser i denna tråd. Det är ju defacto rena grunder i seriell kommunikation som går snett, handskakning (CTS/RTS eller XON/XOFF) - sånt fick man ju lära sig i gymnasiet på 80-talet och sedan koda rutinerna i assembler.
Re: Är det en loop som läser av värdet på COMporten?
> Utveckla vidare. Handskakningen är till för kommunikation för att....?
OK, jag måste försöka skita i denna tråd...
Antingen driver du med alla eller så är du hopplöst obildbar.
OK, jag måste försöka skita i denna tråd...
Antingen driver du med alla eller så är du hopplöst obildbar.
Re: Är det en loop som läser av värdet på COMporten?
Det är väl inte så enormt mycket data som ska in? några hundra tecken per sekund är ju inga problem, och det behövs knappast nån handskakning - kör på bara.
Jag vet att det är knepigt att skriva ett eget PC-program som tar emot data från COM-porten, men jag har faktiskt lyckats. Det är väldigt lite kodexempel (eller svårt att hitta) eller så är exemplen föråldrade (gamla Windows-95 API) eller helt enkelt dåliga...
Man måste kunna polla (= kolla väldigt ofta) ifall det finns data som vill in. Då MÅSTE man snarast läsa in dessa innan bufferten blir full. (Det finns alltid en buffert som operativsystemet tillhandahåller, som fylls på med data)
jag ska kolla om jag hittar någon kod jag har skrivit , så kan du titta... Tror jag försökt i både C, C++, Java och C#. C# var det som var enklast tror jag. Java var ett helvete, som vanligt (COM-porten stöds/stöddes inte i standard-Java, man måste skaffa obskyra bibliotek som inte går att installera)
EDIT: Har du Visual Studio så kan du få en zip-fil med ett C# projekt som läser in strömmande data från en COM-port (som kopplades till en AVR).
Formatet råkar vara NMEA i ASCII(HEX), men kan givetvis vara vad som helst, bara man kan identifiera strängens start och slut. Det är det enda program jag gjort i C# och kunde varit avsevärt bättre, den är delvis ofärdig, men själva kommunikationsbiten fungerar utmärkt!
Här kommer en "förhandsgranskning" på ett par bitar av koden:
Jag vet att det är knepigt att skriva ett eget PC-program som tar emot data från COM-porten, men jag har faktiskt lyckats. Det är väldigt lite kodexempel (eller svårt att hitta) eller så är exemplen föråldrade (gamla Windows-95 API) eller helt enkelt dåliga...
Man måste kunna polla (= kolla väldigt ofta) ifall det finns data som vill in. Då MÅSTE man snarast läsa in dessa innan bufferten blir full. (Det finns alltid en buffert som operativsystemet tillhandahåller, som fylls på med data)
jag ska kolla om jag hittar någon kod jag har skrivit , så kan du titta... Tror jag försökt i både C, C++, Java och C#. C# var det som var enklast tror jag. Java var ett helvete, som vanligt (COM-porten stöds/stöddes inte i standard-Java, man måste skaffa obskyra bibliotek som inte går att installera)
EDIT: Har du Visual Studio så kan du få en zip-fil med ett C# projekt som läser in strömmande data från en COM-port (som kopplades till en AVR).
Formatet råkar vara NMEA i ASCII(HEX), men kan givetvis vara vad som helst, bara man kan identifiera strängens start och slut. Det är det enda program jag gjort i C# och kunde varit avsevärt bättre, den är delvis ofärdig, men själva kommunikationsbiten fungerar utmärkt!
Här kommer en "förhandsgranskning" på ett par bitar av koden:

Kod: Markera allt
// denna metod måste anropas kontinuerligt för att ta emot data från porten.
// rekommenderas mellan 0.25 - 5 sekunders intervall beroende på behov.
public void Check_incoming()
{
if (connected > 0) connected--;
string text = port.Read();
if (text != null && text != "")
{
//Console.WriteLine(text);
// bearbeta inkommande text
char[] separator = { ':', ',', '*' };
// sträng-arrayen s innehåller alla argument i NMEA-meningen från 0="$IITXT" till checksumman
string[] s = text.Split(separator);
if (s.Length < 6) return; // error
connected = connection_timeout; // ställ timeout om meddelade kommer in
int start = 1;
string kommando = "";
if (s[0] == "$IITXT")
{
adress = toInt(s[1]);
code = toInt(s[3]);
checksum = toInt(s[s.Length - 1], 16);
start = 4;
kommando = s[start++];
}
switch (kommando)
{
case "v":
// läs in VV-parametrar
for (int i = 0; i < (VV.Length); i++)
{
if (i + start > s.Length) break;
VV[i] = toInt(s[i+start]);
}
VV_received = true;
numberOfCells = VV[20];
Console.WriteLine("VV received");
Console.WriteLine("Minibms {0} celler.", numberOfCells);
if (numberOfCells > MAXANTALCELLER) numberOfCells = MAXANTALCELLER;
if (numberOfCells < 0) numberOfCells = 0;
// skapa en cell-lista - behövs ej
break;
case "r":
// läs in celldata - millivolt
Vmedel = 0;
Vmax = 0;
Vmin = 10;
for (int i = 0; i < (numberOfCells); i++)
{
if (i + start > s.Length) break;
float v = toInt(s[i + start]) / 1000F;
celler[i].volt = v;
Console.Write("{0:0.000} ", v);
Vmedel += v;
if (v > Vmax) Vmax = v;
if (v < Vmin) Vmin = v;
}
totalVolt = (float)Math.Round(Vmedel, 1);
if (numberOfCells != 0)
Vmedel = Vmedel / numberOfCells;
Console.WriteLine("");
for (int i = 0; i < numberOfCells; i++)
{
celler[i].avvikelse = (celler[i].volt - Vmedel);
}
cellsUpdated = true;
break;
case "ta" :
// läs in temperaturer
break;
}
}
}
Kod: Markera allt
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
namespace seriell
{
class Sercomm
{
// klassvariabler = Fält
const int MAXBUFLEN = 1024; // antal inlästa tecken
byte[] inbuf = new byte[MAXBUFLEN];
int bufpos = 0;
public SerialPort port = new SerialPort();
public string[] ports = SerialPort.GetPortNames();
// konstruktor - letar upp alla lediga portar och skriver ut en lista
public Sercomm ()
{
// Skriv ut en lista med portar
Console.WriteLine("Existerande portar:");
foreach(string pname in ports)
{
port.PortName = pname;
try
{
port.RtsEnable = false;
port.Open();
Console.WriteLine("Port {0} är ledig.", port.PortName);
//Console.WriteLine((port.CDHolding) ? "DCD on" : "DCD off");
//Console.WriteLine((port.CtsHolding) ? "CTS on" : "CTS off");
port.Close();
}
catch (System.IO.IOException)
{
// inget
}
catch (System.UnauthorizedAccessException)
{
Console.WriteLine("Port {0} är upptagen.", port.PortName);
}
}
}
public void Open(string portnamn, int baudrate)
{
port.PortName = portnamn;
port.BaudRate = baudrate;
port.ReadTimeout = SerialPort.InfiniteTimeout;
port.Open();
port.RtsEnable = true;
Console.WriteLine("Port {0} öppnad, {1} BAUD.", port.PortName, port.BaudRate);
Console.Beep(440, 200);
}
public string Read ()
{
int nrOfBytes = port.BytesToRead;
for (int i = 0; i < nrOfBytes; i++ )
{
byte tkn = (byte)port.ReadChar();
if (tkn != 0x0a)
{
inbuf[bufpos++] = tkn;
if (bufpos >= MAXBUFLEN)
{
bufpos = 0;
return "";
}
if (tkn == 0x0d)
{
string textrad = "";
for (int j = 0; j < bufpos; j++)
{
char z = (char) inbuf[j];
textrad += z;
}
bufpos = 0;
return textrad;
}
//Console.Write(tkn);
}
}
return null;
}
public void Write (string text)
{
port.Write(text);
}
public void Close ()
{
// stäng porten
if (port.IsOpen)
{
port.Close();
Console.WriteLine("Port {0} stängd.", port.PortName);
Console.Beep(220, 200);
}
}
public void printBuff ()
{
for (int i = 0; i < bufpos; i++)
{
byte z = inbuf[i];
if (z > 31)
Console.Write((char)z);
//Console.Write("[{0:X}]", z);
//Console.Write(BitConverter.ToString(inbuf).Replace("-00",""));
}
Console.WriteLine("");
}
}
}
Re: Är det en loop som läser av värdet på COMporten?
En extremt enkel variant i C som läser från COM-port: Problemet här är att fgetc()-funktionen antagligen låser programmet tills ett tecken kommit in. Inte kul. Det ska finnas sätt att komma runt detta (tror det finns en funktion som talar om ifall det finns tecken att läsa. Då måste man anropa den först och använda fgetc() enbart när det verkligen finns data att hämta.
Dom som gör PC-programmet måste väl vara medvetna om hur detta fungerar och hur de ska ta emot data? Detta måste ju fungera innan man kan börja med att kommunicera. Det ska inte finnas frågetecken om hur mycket data som går att ta emot, etc... De ska specificera det och sen ser du till att din AVR skickar den data dom vill ha.
Dom som gör PC-programmet måste väl vara medvetna om hur detta fungerar och hur de ska ta emot data? Detta måste ju fungera innan man kan börja med att kommunicera. Det ska inte finnas frågetecken om hur mycket data som går att ta emot, etc... De ska specificera det och sen ser du till att din AVR skickar den data dom vill ha.
Kod: Markera allt
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <termios.h>
#define PATH "C:\\Documents and Settings\\Admin\\Mina dokument\\Avancerat\\ekg\\"
#define COMPORT "COM1"
#define UTFIL "bms_logg.txt"
FILE *s, *s1, *utfil;
char input[256];
int main() {
char ch;
printf("testar att kommunicera med serieporten\n");
printf("sizeof char = %i\n", sizeof(char));
printf("sizeof int = %i\n", sizeof(int));
printf("sizeof short int = %i\n", sizeof(short int));
printf("sizeof double = %i\n", sizeof(double));
if ((s = fopen(COMPORT, "r+b")) == NULL) {
printf ("Port OPEN error: ");
printf( COMPORT );
return 0;
}
printf("\n----- " COMPORT " open ------\n");
system( "mode com1: baud=38400 parity=n data=8 stop=1" ) ;
while (1) {
ch = fgetc(s); // ( input, sizeof( input ), s) ;
printf( "%c", ch ) ;
if (ch == '0') {
fprintf(s,"\n\r");
}
}
fclose(s);
printf("\nklart!");
return 0;
}
Re: Är det en loop som läser av värdet på COMporten?
Bundy är representativ för den moderna ingenjörsarbetskraft Svenska storföretag har att tillgå, är det så konstigt att allt mer av utveckling och produktion hamnar utomlands istället? Läsa på och tänka själv är för jobbigt, bättre att gissa, chansa, plagiera och sitta i möten och allmänblaja iställetsodjan skrev:> Utveckla vidare. Handskakningen är till för kommunikation för att....?
OK, jag måste försöka skita i denna tråd...
Antingen driver du med alla eller så är du hopplöst obildbar.

Re: Är det en loop som läser av värdet på COMporten?
Ja, istället för att ta reda på själv så frågar man nån som man tror vet, och sen när inget funkar så kan man klaga på den som gav rådet istället för att få stå för det själv.
Det är väl det som kallas outsourcing? :)
Det är väl det som kallas outsourcing? :)
Re: Är det en loop som läser av värdet på COMporten?
sällsynt puckade kommentarer ni kommer med...
Re: Är det en loop som läser av värdet på COMporten?
Bör väl snarare vara:Nerre skrev:Ja, istället för att ta reda på själv så frågar man nån som man tror vet...
"Ja, istället för att ta reda på själv så frågar man nån som tror sig veta"
/johan
Re: Är det en loop som läser av värdet på COMporten?
Nja, jag upplever tyvärr många gånger att när man ifrågasätter något som en kund hittat på så svarar de "vi frågade xxxxx och fick svaret att vi skulle göra si och så".
Re: Är det en loop som läser av värdet på COMporten?
Jag har gjort några program på jobbet som läser av mätinstrument på serieporten. Principen har oftast då varit att om instrumentet får en viss textsträng via serieporten från datorn som motsvarar kommandot "skicka mätvärde" så svarar instrumentet med mätvärdet som en textsträng enligt specifikation i instrumentets manual. Principen jag då använt har varit att först tömma läsbufferten på datorns serieport, skicka kommandot och sedan vänta en liten stund tillräckligt länge för att låta serieporten fylla sin läsbuffert med efterfrågad data och slutligen läsa av serieportens läsbuffert och scanna efter resultat i mottagen data. Detta sker i en loop (alltså töm buffert, skicka kommandot och lyssna) ett antal gånger tills giltigt värde mottagits.
Sedan hur inställningar för handskakning ska vara har jag fått läsa i instrumentets manual. Man får initiera datorns serieport på motsvarande sätt innan man börjar använda den. Nu har jag bara använt LabVIEW för detta och de inbyggda funktionerna där men det har fungerat så då har jag kört vidare på det. Kanske inte bästa eller snabbaste sättet men det funkar och då får det duga. Ofta har det ju varit ganska lite data i taget man behövt läsa så det har inte alltid varit noga med handskakningen.
Principen att instrumentet skickar data hela tiden har jag nog också använt någon gång. Vi har någon våg man kan ställa in att spotta ur sig aktuell uppmätt vikt varje sekund. Men principen då är densamma bara att man slipper skicka kommandot att den ska skicka data utan man läser in data från serieporten tillräckligt länge för att få minst ett mätvärde och konverterar texten till ett tal som motsvarar uppmätt värde (detta funkar eftersom den skickar nyradstecken efter varje mätvärde så det är bara att läsa innehållet mellan två nyradstecken). Denna procedur kör man varje gång man vill ha ett mätvärde och så struntar man i att den skickar data även när man inte behöver den. Genom att tömma läsbufferten inför varje läsning så får man nya färska värden.
Min princip funkar väl inte om man alltid måste ta emot allt som instrumentet skickar utan nöjer sig med att läsa värdet och upprepa inläsningen om det misslyckas.
Så hade jag gjort något program i Arduino eller någon annan MCU-lösning skulle jag troligen lägga in korta textkommandon som den lyssnar efter och svarar på utifrån någon given specifikation som sedan programmeraren för datorprogrammet kan anpassa sig efter. Där behövs det ingen loop som ständigt pollar utan man kanske hellre generar avbrottssignal (interrupt) när data tas emot. Är inte jättehaj på hur man gör där men det känns som det kanske går åt onödig prestanda om den ständigt ska ligga och polla kommunikationen.
Sedan hur inställningar för handskakning ska vara har jag fått läsa i instrumentets manual. Man får initiera datorns serieport på motsvarande sätt innan man börjar använda den. Nu har jag bara använt LabVIEW för detta och de inbyggda funktionerna där men det har fungerat så då har jag kört vidare på det. Kanske inte bästa eller snabbaste sättet men det funkar och då får det duga. Ofta har det ju varit ganska lite data i taget man behövt läsa så det har inte alltid varit noga med handskakningen.
Principen att instrumentet skickar data hela tiden har jag nog också använt någon gång. Vi har någon våg man kan ställa in att spotta ur sig aktuell uppmätt vikt varje sekund. Men principen då är densamma bara att man slipper skicka kommandot att den ska skicka data utan man läser in data från serieporten tillräckligt länge för att få minst ett mätvärde och konverterar texten till ett tal som motsvarar uppmätt värde (detta funkar eftersom den skickar nyradstecken efter varje mätvärde så det är bara att läsa innehållet mellan två nyradstecken). Denna procedur kör man varje gång man vill ha ett mätvärde och så struntar man i att den skickar data även när man inte behöver den. Genom att tömma läsbufferten inför varje läsning så får man nya färska värden.
Min princip funkar väl inte om man alltid måste ta emot allt som instrumentet skickar utan nöjer sig med att läsa värdet och upprepa inläsningen om det misslyckas.
Så hade jag gjort något program i Arduino eller någon annan MCU-lösning skulle jag troligen lägga in korta textkommandon som den lyssnar efter och svarar på utifrån någon given specifikation som sedan programmeraren för datorprogrammet kan anpassa sig efter. Där behövs det ingen loop som ständigt pollar utan man kanske hellre generar avbrottssignal (interrupt) när data tas emot. Är inte jättehaj på hur man gör där men det känns som det kanske går åt onödig prestanda om den ständigt ska ligga och polla kommunikationen.