Sida 1 av 2
Python: Hjälp med funktion och skapa mjukvaru-peak detector
Postat: 11 december 2016, 02:19:13
av Magnus_K
Hej på er,
Sitter och följer en guide på nätet om hur jag ska läsa ut data från min
MCP3208 (8-kanalers ADC).
Tyvärr följer guiden en liknande ADC från samma tillverkare men den (i stort sett) enda skillnaden är att ADC:n, som guiden använder sig av är 10 bitar, och min är 12 bitar. Det är även en viss skillnad när start-biten kommer (som ni ser nedan). Således saknar jag ett par bitar i "resultatet".
Idag var första gången i mitt liv (tror jag) som jag skrev någon rad python-kod och försöka hänga med på alla sudo, wget, nano och nya grejer med RPi:n, är tufft.
Nu sitter jag i en sits där jag inte ens kan lokalisera "källan" till koden jag använder mig av. Vet inte vart jag ska börja läsa.
Jag har installerat något som hette Python3 och spidev och guiden jag följt är
https://www.youtube.com/watch?v=wIAffBTtrKY#t=7.866791.
Ni behöver inte berätta svaret (om ni inte vill) eller kräkas ut en massa dynga om "så här går det när man kopierar kod". Jag försöker komma igång och utan såna guider så hade jag inte ens försökt.
Ps. Koden ser ut som nedan samt bifogat hur SPI-datan spottas ut ur ADC:n. Ds
EDIT: Trodde jag hade det. Maskade av
rawData[1] med 15 istället för 3 men det fixade inte biffen. Får jobba vidare.
EDIT1: Ändrade ämnet för att bättre passa en ny frågeställning.
Kod: Markera allt
rawData = spi.xfer([1, (8 + channel) << 4, 0])
processedData = ((rawData[1]&3) << 8) + rawData[2]
return processedData
guidens_data.JPG
min_data.JPG
Re: Helt vilsen i python-träsket, vart ska jag leta?
Postat: 11 december 2016, 02:48:45
av Mr Andersson
Testa med
Kod: Markera allt
rawData = spi.xfer([(4 + ((8 + channel) >> 2)), ((8 + channel) << 6) & 192, 0])
processedData = ((rawData[1]&15) << 8) + rawData[2]
return processedData
Skillnaden ligger i att på 10-bitaren är startbiten första biten i första byten, sen kommer 4 bitar kanalväljare i den övre halvan av andra byten. I 12-bitaren är allt skiftat 2 bits till vänster.
Re: Helt vilsen i python-träsket, vart ska jag leta?
Postat: 11 december 2016, 03:00:59
av Magnus_K
Du är ju helt otrolig!
Räknande lite på det tidigare och förväntade mig ~1800 ADC-bananer med 2,5V ref och 1,1V in. Och visst, efter din kod så har jag 1811 bananer in.
Känns väldigt bra att ha klurat ut att jag skulle maska av med 15, och om jag inte minns helt fel så var du en av dom inblandade att lära mig sånt där.
Satt precis och försökte få till det där med start-biten när jag såg ditt inlägg. Inte för att jag någonsin skulle kunna klämma ur mig något liknande men det låter bra
Har du/ni lust att gå igenom raden
rawData = spi.xfer([(4 + ((8 + channel) >> 2)), ((8 + channel) << 6) & 192, 0]) med mig?
4 + (8 + channel >> 2 = Detta ger 1100 (för kanal 0) och sedan skiftas det ner 2 bitar för att skapa dom nedre bitarna i första byten?
8 + channel) << 6 = bitarna som skiftades bort i föregående manöver återskapas här och skiftas upp i andra byten?
& 192 = Maska av så resten av andra byten verkligen är 0?
Re: Helt vilsen i python-träsket, vart ska jag leta?
Postat: 11 december 2016, 03:11:37
av Mr Andersson
Första byten:
4 - Startbiten är bit 2 (eller 3 om man räknar första som 1 men av gammal vana börjar jag alltid index med 0

)
(8 + channel) - 8:an för att vi vill ha single ended (jag vet inte om du ville ha det men originalkoden hade det) plus 3 bitar kanal (0-7, du bör kanske ha någon check innan att kanalnummret inte är utanför området). Resultatet är 4 bitar och vi vill bara ha de två högsta, därför
>> 2.
Andra byten:
(8 + channel) - samma som tidigare. Skifta 6 steg vänster, från 0000xxxx till (xx)xx000000. AND med 192 (0b11000000) för att ta bort overflow. Python är inte begränsad till 8-bitars nummer så vi kommer att få nummer större än 255 annars.
Sista byten används inte och kan därför sättas till vad som helst. Jag valde 0 för att originalkoden hade det.
Re: Helt vilsen i python-träsket, vart ska jag leta?
Postat: 11 december 2016, 03:16:44
av Magnus_K
Ahaaaaaa, de 3 olika byten avskiljs alltså med ett "," i spi.xfer(). Nu hänger jag med!
Det var därför jag undrade om vart jag kunde läsa om den funktionen för jag fattade inte vad alla argument innebar.
Du har helt rätt i att jag ville köra single enden. Tack för hjälpen
Mr Andersson!
Ps. Otroligt skönt att få bekräftat att min lilla RPi-hatt fungerar som den ska också

Ds
Re: Helt vilsen i python-träsket, vart ska jag leta?
Postat: 11 december 2016, 03:25:04
av Mr Andersson
Jepp i python är [ ] kommaseparerade listor eller arrayindex beroende på kontext.
Kul att det fungerade. Alltid nervöst att ge ut kod man inte kan testa själv först.

Re: Python: Hjälp med funktion och skapa mjukvaru-peak detec
Postat: 11 december 2016, 21:21:26
av Magnus_K
Det gick så himla bra med förre frågeställningen så jag skrev om ämnet lite och fortsätter, då det ändå rör precis samma komponenter och kod.
Kortet verkar fungera bra men nu vill jag sampla AC-spänningen och försöka konvertera denna till något användbart.
Har aldrig gjort något liknande, och absolut inte med hjälp av mjukvara, så skulle verkligen uppskatta lite inputs.
Signalen som ska bearbetas är alltså en 50Hz sinus som är DC-förspänd(?) med 1,1V. AC-signalen som rider på denna kan som högst bli 2Vpp, med andra ord ett spann på 0,1-2,1Vpp sinus.
För att kunna ta mig steg för steg i programmeringen så har jag tänkt mig följande flöde:
- - Lägga in 1,1V som nolla på AC-signalen
- Sampla signalen med 1,25kHz för att få 25st samplingspunkter per sinus (50Hz * 25)
- Vid varje sampling så jämförs det nuvarande värde med föregående. Om den nya är högre så spara undan denna som "Vpeak"
- Varje sampling måste också stämmas av mot någon slags "nollgenomgång" också. Detta bör inblanda översta punkten.
- Vpeak multipliceras sen med roten ur 2 och vi bör få en Vrms (Arms) som sen ska presenteras.
Tänker jag rätt?
Re: Python: Hjälp med funktion och skapa mjukvaru-peak detec
Postat: 11 december 2016, 23:05:29
av rvl
Multipliceras med 1/sqrt(2) * nån annan av kretsen beroende konstant, menade du säkert, eller hur?
Samplar du tillräckligt ofta för att leva med det fel som uppstår om/när den verkliga toppen hamnar mitt emellan två sampel? Om inte, så kanske parabolisk interpolering av tre värden närmast toppen ge en bra approximation, även med glesare sampling.
Nollnivån kanske kan tas fram med ett långtidsmedelvärde?
Re: Python: Hjälp med funktion och skapa mjukvaru-peak detec
Postat: 11 december 2016, 23:16:27
av Magnus_K
Ah, ja där blev det fel. Visst räcker det att dividera Vpeak med sqrt(2) för att få RMS va?
Tror jag kan leva med det mätfel som kommer bli pga "klippt toppvärde", dock låter parabolisk interpolering intressant. Vet inte vad det är men namnet avslöjar ju en del. Ska läsa lite och återkomma.
Det var inte heller någon dum idé angående metoden att få fram nollpunkten. Jäkligt bra.
Ska försöka hitta lite kod som hjälpa mig på traven och läsa på om dina tips. Tack rvl!
Re: Python: Hjälp med funktion och skapa mjukvaru-peak detec
Postat: 12 december 2016, 00:52:26
av rvl
Snickrade till ett litet exempel på interpolering. Ser ut att ha blivit rätt, även om jag nu råkar sitta med fel dator (windows), men jag hade i alla fall python på den.
Kod: Markera allt
import math
def peak(top, before, after):
location = 0.5 * ( before - after ) / ( before - 2*top + after)
magnitude = top - 0.25 * ( before - after ) * ( location )
return(magnitude)
def sinus(x):
Amplitude = 2048.0
return( Amplitude * math.sin( 2.0 * math.pi * (x/25.0) ))
t = range(25)
#for x in t:
# print( sinus(x) )
print("top sample and neighbours")
print( sinus(5) )
print( sinus(6) )
print( sinus(7) )
print("interpolated")
print( peak( sinus(6), sinus(5), sinus(7)) )
'''
resultatet blev:
=================== RESTART: C:/Python27/egi/parabolic.py ===================
top sample and neighbours
1947.76374537
2043.95873982
2011.72428949
interpolated
2047.94045057
>>>
("ratt svar" hade varit 2048)
'''
Edit: med maximalt ofördelaktig fasförskjutning (+0.75 från ovanstående)
Kod: Markera allt
top sample and neighbours
2031.85090829
2031.85090829
1904.1822431
interpolated
2047.80949144
Re: Python: Hjälp med funktion och skapa mjukvaru-peak detec
Postat: 12 december 2016, 10:17:32
av Magnus_K
Oj oj oj, det där ser ju
perfekt ut! Tack för att du tog dig tid. Väldigt snällt!
Funderade på att jag kanske måste hålla nere koden lite för att inte CPU:n hänger med men "lscpu" avslöjade att CPU:n snurrar med 700MHz!
Ska försöka implementera det här nu. Återkommer med resultat. Tack än en gång
rvl!
Re: Python: Hjälp med funktion och skapa mjukvaru-peak detec
Postat: 12 december 2016, 10:33:18
av Magnus_K
Liten fråga om koden.
Funktionen "peak" vill ha 3 parametrar, top, before, after.
before och after är alltså det "gamla" värdet och det ny-samplade. Men top, vilket värde är det?
Ska det vara max amplitud sett från nollan?
Re: Python: Hjälp med funktion och skapa mjukvaru-peak detec
Postat: 12 december 2016, 10:51:18
av rvl
Nja, exemplet visade bara interpoleringen, när man redan hittat den ungefärliga toppen, dvs högsta samplet. Before och after är toppens närmaste grannar.
Sjäva sökandet som du är mest intresserad av, gick jag tillsvidare helt förbi och hårdkodade dit jag visste att den fanns för exempelkurvan.
Re: Python: Hjälp med funktion och skapa mjukvaru-peak detec
Postat: 12 december 2016, 12:03:42
av Magnus_K
Nu hänger jag med. Tack

Re: Python: Hjälp med funktion och skapa mjukvaru-peak detec
Postat: 12 december 2016, 13:27:14
av lillahuset
Varför krångla till det?
Sampla signalen till en hyfsat stor buffer.
Räkna ut medelvärdet och subtrahera från värdena.
Kvadrera värdena, dividera med antalet värden och dra roten ur.