För tung och klumpig batteriladdare

Tack för din strömrapport Thomas! :)

En besparing på 20 mA är faktiskt ganska mycket i sammanhanget. Som sagt 20 här och 10 där etc... Det är väl värt att prova att sänka klockfrekvensen.

Så som jag byggt ihop de olika korten i loggdatorn så är det inte helt lätt att komma åt och mäta strömmar i periferienheterna. Men det får snart göras så jag får ett bättre underlag.

Sovläget som redan testats fungerade bra med undantag för att det första tecknet missades när tangenten trycktes ned hypersnabbt - så som man skriver i verkligheten vid pile-up. Om tangenten hölls ner aningen längre verkade allt fungera. Så kunde man bara förlänga "knapptryckningen" elektroniskt på något sätt så kanske det är en godtagbar lösning. Sedan vill man ju att sovläget skall aktiveras bara någon sekund efter sista tangenten tryckts ner så att tiden som används till mottagning - runt 50% eller mer - blir sovläge.

Funderar vidare.
 
I processorns datablad ser det ut som att man kan försätta olika delar (eg. interna klockor) i sovläge separat. Vissa, t.ex. A/D och PWM, kan antagligen sova konstant utan att väckas. Det blir mest fråga om att säkerställa att de inställningarna gäller från uppstart. Det blir några få rader kod som körs sällan. Kanske bör seriekommunikationsklockan för USB ha längre timeout än andra klockor. På din beskrivning ser det ut som att det tappades tecken i samband med väckningen.
 
Eftersom det är jag som pillar med programvaran till loggdatorn kan jag också ge lite input. :)

Det är helt riktigt att processorn är arbetslös mesta delen av tiden. Så är det nog i de flesta system. Men när något väl skall göras så vill man ju att det skall gå undan. I loggdatorn så handlar det om loggning, inmatning via tangentbord, visning på display, lagring på minneskort och telegrafisändning - så datorn är i princip aktiv under hela QSO:t, samt när den sänder CQ.

USB är inte som "vanlig" seriekommunikation. När man ansluter ett USB tangentbord till en apparat måste det göras via en USB host controller. Det tråkiga är att en USB device inte kan ge ett interrupt till hosten, utan det är alltid hostens (loggdatorns) ansvar att polla devicen (tangentbordet). Detta måste då göras tillräckligt ofta för att man skall få acceptabel responstid och att man inte hinner skriva in ett andra tecken, så att det första går förlorat. På så sätt är det egentligen lite dumt att använda ett USB tangentbord - men det är nästan det enda som går att uppbringa idag, särskilt om det skall vara kompakt, trådlöst och billigt. Ett tangentbord med en vanlig hederlig UART hade varit mycket enklare.

Den metod som provades var alltså att sätta processorn i sovläge en kort stund, typ 50ms, och sedan väcka den, polla USB och om något hänt fortsätta processa det, annars åter i sovläge. I de flesta fall kunde den sova igen efter typ 10ms (siffror ej exakta). Det blev en kompromiss mellan att sova så mycket som möjligt och att vara vaken tillräckligt ofta för att kunna polla tangentbordet. Ju djupare sovläge man använder, desto längre tid tar processorn att väcka upp, så även det får det kompromissas med. Men det skall experimenteras mer med det när tid finnes.

Angående den andra frågeställningen skulle det säkert gå bra att lägga in batteriövervakning och laddningsfunktioner i loggdatorn också. Men på nåt sätt blir det nog enklare och bättre om det kan lösas separat med lite hårdvara, så kan jag lägga tiden på att få klart de huvudsakliga funktionerna i stället ... ;)

F.ö är det ATMEGA2560 processorn (Arduino MEGA ADK) som används i loggdatorn eftersom det behövdes mer minne än det finns i ATMEGA328 (Arduino UNO), så den drar nog några mA mer. Troligen skulle en ARM-processor, t.ex Teensy, dra lite mindre. Så det är också något som skall utvärderas.

Greger / SM7JKW
 
Eftersom det är jag som pillar med programvaran till loggdatorn kan jag också ge lite input. :)

Hej Greger, kul med din input :)

USB är inte som "vanlig" seriekommunikation. När man ansluter ett USB tangentbord till en apparat måste det göras via en USB host controller. Det tråkiga är att en USB device inte kan ge ett interrupt till hosten, utan det är alltid hostens (loggdatorns) ansvar att polla devicen (tangentbordet).

Ja, i Arduino Megas schema ser man tydligt att det bara finns RX- och TX-tåtar mellan processorn (ATmega2530) och USB-kontrollern/coprocessorn (ATmega 8U2). Varken interrupt eller flödeskontroll finns i hårdvara, tyvärr. Som du säger blir det svårt att planera in processorns tupplurar då. Kanske har arduinogänget kodat in mjukvarumässig flödeskontroll? På något sätt måste koden hantera situationen att processorn arbetar med något annat när det kommer in data från USB. Men är det odokumenterat så finns det risker med att utnyttja det. Om man nöjer sig med att sänka den interna klockan till "vilopuls", så måste man också hantera att det även påverkar seriekommunikationen. Man hamnar lätt i kod som blir mer komplex än önskvärt, vilket kan bli tungt att underhålla och svårt att porta till andra arduinoplattformar om man vill i framtiden.

Vanliga USB-chip, t.ex. FTDI, brukar erbjuda interrupt och/eller flödeskontroll. Antagligen hade arduinogänget god skäl för att välja sin egen lösning, även om jag åtminstone hade inkuderat någon form av dokumenterad handskakning. Nåväl, jag följer ert arbete med portabesystemet med stort intresse :) Ämnet är intressant.
 
Hej Thomas,

Nja - du ser nog USB som en lite extra fancy serieport - men det är mer komplicerat än så.

Med risk för att tappa bort den ursprungliga tråden (om batteriladdning) så är det alltså inte så enkelt med USB.

För det första finns det två grundmoder, Device och Host. Det finns en Host och den kan ha en eller flera Device anslutna. (Tänk en PC med flera tillbehör, mus, tangentbord, skrivare, osv). Device kan bara prata direkt med Host - inte direkt med andra Device.

Den vanliga USB-porten på en Arduino är en Device-port, dvs den är tänkt att ansluta till en PC för att kunna ladda ner program och för TTY-debugging. Enkelt uttryckt har Device alltid den kvadratiska USB-kontakten, medan Host har den rektangulära (så länge man håller sig till normal storlek).

Det går inte att koppla in ett tangentbord till Device-porten på Arduino. Det skulle vara att försöka få två Device att prata med varandra, och det går inte (stöds inte i USB-standarden). Däremot skulle det kunna gå att få Arduinon att uppträda som ett tangentbord gentemot PC:n. (Den funktionen finns inte på Uno, men väl på Leonardo).

I loggdatorn använder vi en version av Arduino som har USB Host-controller på kortet. Det är en MAX3421E. Genom den (och en hel del programvara i form av USB Host Stack) får vi ytterligare en USB-port på Arduinon som låter oss ansluta ett eller flera device. Detta använder vi för att ansluta tangentbordet. Tangentbordet är ett s.k HID (Human Interface Device) och har en egen klass i USB. Därför fungerar det inte alls som UART-klassen (FTDI chip t.ex).

När det gäller interrupt så skulle iofs MAX3421E kunna skapa interrupt - men det är då inte samma sak som att ett Device gör ett interrupt. Det är en rent intern funktion för att driva USB-protokollet. Det finns inget stöd i USB-specifikationen för att ett device skall kunna skapa ett hårdvaruinterrupt på en Host.

Det finns numera en tredje USB-mode som kallas On The Go (OTG). Den kom till när det inte längre var lika självklart vem som skulle vara Host och vem som skulle vara Device. Ansluter du din telefon till PC:n så är PC:n Host och telefonen Device. Vill du koppla in ett tangentbord till telefonen så måste telefonen vara Host. Så en enhet som stödjer OTG kan växla mellan att vara Host och Device gentemot olika enheter.

Greger / SM7JKW
 
Det finns eller i alla fall fanns övergångar från USB till PS2 för tangentbord. PS2 är
så vitt jag kommer ihåg vanlig synkron serieöverföring. Det kan kanske vara en
väg för att undvika den (alltför) komplicerade USB tekniken, genom att använda
sig av en sådan?
 
KBW: Jo, det är riktigt. Men de passiva adaptrar som brukade följa med tangentborden bygger på att man gör nåt trix i BIOS på PC:n. Såvitt jag förstått blir det inget äkta PS/2-tangentbord för att man sätter på en sådan. Sedan har jag sett riktiga omvandlare, men det blir ju en processor till och då är det tveksamt om vi verkligen spar någon ström i slutändan.

Greger / SM7JKW
 
Det finns inget stöd i USB-specifikationen för att ett device skall kunna skapa ett hårdvaruinterrupt på en Host.
Självklart inte. Det vore stolligt om en protokollspecifikation lade sig i en sån sak. Valet om man ska polla eller använda interruptrutiner är upp till implementatören att bestämma utifrån tillgängliga signaler, behov och kravspecifikationer. Det kan finnas goda skäl att välja det ena eller andra. I Arduinos fall misstänker jag att gänget bakom har prioriterat pedagogik och enkel förståelse framför den relativa komplexiteten med ett optimerat kort. Det är helt OK eftersom att lära, labba och ha kul med mikrokontrollersystem är syftet bakom arduinoprojektet.

Från MAX3421E kan man, enligt databladet, få interrupt om man bevakar signalen BUSACT/INIRQ i GPX: "This signal is active whenever there is traffic on the USB bus." Det är alltså trafiken, inte HID:en/device:t, som genererar interruptet. Ifall det aktuella kortet är Arduino MEGA ADK, ska GPX vara draget till pinnen PJ3(PCINT12) på processorn enligt det schema jag hittade. Det bör vara möjligt att få ett interrupt när det blir trafik på USB-bussen och då finns också goda chanser att processorn kan ta sig en tupplur emellanåt för att spara ström.
 
Ja, men all trafik i USB bygger på pollning FRÅN Host. Det är Host som styr all trafik i USB. Det genereras ingen trafik av ett Device utan att Host bett om det. Så länge Host sover kommer den inte att be om någon trafik.

Device kan/får inte sända något spontant.

Tilläggas bör kanske att Device måste svara på en poll inom nån ms. Så det går alltså inte att kasta ut en poll och vänta på att tangentbordet svarar om några sekunder/minuter när någon tryckt på en knapp.

Interruptfunktionen i Host Controllern är bara till för att kunna driva USB-kommunikationen med så hög throughput som möjligt. Men det har vi inte så stort behov av i den här applikationen.

Greger / SM7JKW
 
Last edited:
Vill bara inflika från bakre bänkraden:
Följer den här tråden med stort intresse. Man lär sig något varje dag. Sånt som är svårt att genomskåda i specifikationer.

/Roland
 
KBW: Jo, det är riktigt. Men de passiva adaptrar som brukade följa med tangentborden bygger på att man gör nåt trix i BIOS på PC:n. Såvitt jag förstått blir det inget äkta PS/2-tangentbord för att man sätter på en sådan. Sedan har jag sett riktiga omvandlare, men det blir ju en processor till och då är det tveksamt om vi verkligen spar någon ström i slutändan.

Greger / SM7JKW

Hade en labb på en kurs där vi skulle använda ett PS2-tgb, vi skrev en avkodare i VHDL för FPGA. Jag hade inget PS2-tgb så jag
letade fram en sådan övergång och det fungerade lika bra. Senare testade jag med ett "äkta" PS2-tgb och det betedde sig lika.

Det leder mig till att tro att "fixet" inte ligger i BIOS på PC utan i den inbyggda elektroniken i tgb, det vara ett relativt nytt USB-tgb
som jag använde mig av.
 
Uppenbart utgör anslutningen av tangentbordet via USB en "omväg".

Ifall man vill göra en CPU-lösning med absolut minsta strömförbrukning så vore
en lösning där allt är interruptstyrt så att processorn "sover" ända tills något händer på
ingångsportarna, t.ex. att man trycker på en tangent eller vrider på en ratt.
Då hanteras indata, alla utgångsenheter uppdateras och sedan återgår CPU:n till att "sova".
Inga CPU-cykler eller strömförbrukning går då åt till att ligga i vänte-loopar.
Har för mig att något sådant finns beskrivet i en applikationsnot för MC68HC11.

Om kommunikationen mellan tangentbord och CPU görs som asynkrona seriedata kan man dessutom använda en buffrad UART så att man aldrig riskerar att förlora några data.

"Bytesaffären" kommer då att uppstå mellan strömförbrukning och responstid.
Möjligen skulle ett "realtids-tick" var 100-200 ms eller så som finns för att betjäna yttre enheter
där man kan tolerera längre svarstider vara befogat.

73/
Karl-Arne
SM0AOM
 
Hade en labb på en kurs där vi skulle använda ett PS2-tgb, vi skrev en avkodare i VHDL för FPGA. Jag hade inget PS2-tgb så jag
letade fram en sådan övergång och det fungerade lika bra. Senare testade jag med ett "äkta" PS2-tgb och det betedde sig lika.

Det leder mig till att tro att "fixet" inte ligger i BIOS på PC utan i den inbyggda elektroniken i tgb, det vara ett relativt nytt USB-tgb
som jag använde mig av.

Det kan vara så att det är tangentbordet som känner av hur det är anslutet, jag har inte testat praktiskt. Bara läst nånstans på "nätet" - och fick då uppfattningen att det låg i PC:n. Återstår då att se om dongeln för det trådlösa USB-tangentbordet också klarar av den där fixen ... tveksamt. o_O

Ett av grundkraven var ju att EQL ville ha ett kompakt trådlöst tangentbord. I praktiken har man då USB eller Bluetooth att välja på om man vill betala normala konsumentpriser.

AOM: Jo, det skrev jag redan tidigare att ett tangentbord med en UART hade varit mycket enklare. Då blir det precis som du beskriver. :)

Men trots allt har vi en loggdator som drar i snitt ca 75-80mA nu. Ett batteri på 1Ah räcker i princip 12 timmar.


Greger / SM7JKW
 
Läste lite runt på nätet, det är vissa USB-tgb som känner av / går över i PS2-mode. Det finns ingen standard så det
finns ingen garanti för att en godtycklig adapter fungerar med ett visst tgb. Men med ett sådant USB-PS2 tgb så
skulle du kunna lägga tgb-rutinen i interrupt, vilket väl var problemet med USB dito?
 
Back
Top