code:
TmpB = (6 * (lo(temp) >> 4) + (lo(temp) >> 6)) / 10
De tweede extra nul kan dan ook weg.
Special Member
code:
TmpB = (6 * (lo(temp) >> 4) + (lo(temp) >> 6)) / 10
De tweede extra nul kan dan ook weg.
Golden Member
TmpB = (6 * (lo(temp) >> 4) + (lo(temp) >> 6)) / 10
Dit gaat nog niet volledig goed:
22,09 wordt dan 22,9 (zou 22,1 moeten zijn).
Special Member
Hier werkt 't anders prima, hoor...
22.09 wordt 22.0 (integer delingen doen niet aan afronden naar boven ... )
Als je wilt dat de 'normale' afrondregels worden gevolgd (0...4 naar beneden, 5...9 naar boven), moet je dit gebruiken:
pic basic code:
TmpB = (6 * (lo(temp) >> 4) + (lo(temp) >> 6))
If TmpB Mod 10 > 4 Then TmpB = Tmpb + (10 -TmpB Mod 10) End If
TmpB = TmpB / 10
Special Member
Dan is er toch wat verkeerd in je code...
Zo zoiets moeten zijn:
pic basic code:
temp = MCP9800_Read(MCP9800_TEMP)
'-------------------------------- 1 digit----------------------------------
ByteToStr(hi(temp), str)
lTrim (Str)
If Length(Str) = 1 Then Str = "0" + Str End If
Lcd_Out (1,1, "Temp: " + str)
TmpB = (6 * (lo(temp) >> 4) + (lo(temp) >> 6))
If TmpB Mod 10 > 4 Then TmpB = Tmpb + (10 -TmpB Mod 10) End If '<- afronding naar boven
TmpB = TmpB / 10
ByteToStr(TmpB, str)
lTrim(str)
Lcd_Out (1,9, "." + str + " C")
'------------------------------ 2 digit ---------------------------------
ByteToStr(hi(temp), str)
lTrim (Str)
If Length(Str) = 1 Then Str = "0" + Str End If
Lcd_Out (2,1, "Temp: " + str)
TmpB = (6 * (lo(temp) >> 4) + (lo(temp) >> 6))
ByteToStr(TmpB, str)
lTrim(str)
If Length(Str) = 1 Then Str = "0" + Str End If
Lcd_out(2,9,"." + str + " C")
Golden Member
Hij doet het al:
pic basic code:
While True
temp = MCP9800_Read(MCP9800_TEMP)
ByteToStr(hi(temp), str)
lTrim (Str)
If Length(Str) = 1 Then Str = "0" + Str End If
Lcd_String_8x16 (0, 0, "Temp: " + str)
Lcd_String_8x16 (0, 4, "Temp: " + str)
Temp2 = (6 * (lo(temp) >> 4) + (lo(temp) >> 6))
ByteToStr(Temp2, str)
lTrim(str)
Lcd_String_8x16(62,0, "," + str + " C")
Temp2 = (6 * (lo(temp) >> 4) + (lo(temp) >> 6))
If Temp2 Mod 10 > 4 Then Temp2 = Temp2 + (10 -Temp2 Mod 10) End If
Temp2 = Temp2 / 10
ByteToStr(Temp2, str)
lTrim(str)
Lcd_String_8x16(62,4, "," + str + " C")
Delay_ms(350)
Wend
Golden Member
Nou, geweldig. Dank Arco (wederom).
In plaats van deze Oled display kan je natuurlijk ook andere displays gebruiken. Zoals de LCD met HD14780, een 7-segment, Matrix led, etc.
Kern is dat het lezen van de MCP9801 nu goed gaat. De DSB1820 met zijn one-wire laat ik nu maar achter me.
Ik heb de volgende uitdaging alweer: ik kocht een tweetal leuk uitziende displaytjes bij tante Alie.
In mijn onschuld dacht ik bij het bestellen dat het een I2C protocol was,
omdat ik 2 pinnen met CLK en DIO zag.
Maar het is geen I2C, omdat hij geen slave address heeft.
De chip die erop zit is een TM1637.
Ik heb de datasheet erbij gepakt, maar lijkt niet eenvoudig. Op het forum is het wel een paar keer zijdelings genoemd, maar nergens iets met MikroBasic. Vervolgens wat Arduino-voorbeeldjes geprobeerd (ik ervaar wel vaak dat bij een aangeboden 'sketch' allerlei bestanden, zoals .h files, missen).
Het ding werkt daar nu op (UNO boardje), met een redelijke lichtsterkte.
Is dit nu naast de I2C en SPI weer een andere standaard?
En als ik zoiets in MikroBasic wil aansturen, waar ik overigens steeds beter mee uit de voeten kan, is dat te doen?
Of moet je dan alles zelf programmeren? (Datalijn i.r.t. klok hoog houden, etc?)
Special Member
De chip heeft zo te zien een door de fabrikant 'verkreupelde' versie van i2c... (er is geen slave adres)
Kan me niet voorstellen waarom een of andere sukkelaar dat zou willen uitvinden: je kunt nog maar 1 device aan de i2c bus hangen dan...
Golden Member
Ja, inderdaad.
Nogmaals, ik dacht dat het een I2C-er was. Op zich een leuk klein displaytje, maar met de verkeerde chip..
Special Member
Ik was dan bij de MAX7219 gebleven... https://nl.aliexpress.com/item/32956123955.html
Golden Member
Dat doe ik ook. Deze displaytjes vergeet ik. Zonder om er energie in te steken met zoveel betere alternatieven.
Golden Member
Ik heb ze nog niet gezien als 4 displays uitvoering met MAX7219.
Special Member
Waarschijnlijk omdat de MAX7219 nu eenmaal 8 displays kan aansturen...
Golden Member
Ofschoon deze display beperkingen kent (geen I2C),
heb ik toch even als oefening een programma in MikroBasic gefabriceerd om ze te laten werken.
Dat is gelukt.
Daarom zet ik het hier nu neer, om het te delen met belangstellenden (breng ik ook eens iets ).
Deze display is wel bruikbaar voor stand alone toepassingen, zoals een klokje of temperatuur, o.i.d.
Ze zijn klein, supergoedkoop en vergen net als de I2C maar 4 pinnen.
In MikroBasic is er weinig van te vinden van deze (overigens wel veel op Chineses websites aangeboden Display met de TM1637 als chip).
Vandaar deze publicatie.
Het programma telt doorlopend van 0-9999. De helderheid kan via CMD3 worden aangepast van 0x8A - 0x8F.
Hieronder het programma en de MikroBasic project.
pic basic code:
Program TM1637
'Procesor: PIC16F1827
Dim SDA as sbit at PORTB.1 'pin 7 'Serial data pin
Dim SCK as sbit at PORTB.4 'pin 10 'Serial clock pin
'These are the 3 commands used by the TM1637 controller:
Const CMD1 = $40 'CMD1=$40 is the write command
Const CMD2 = $C0 'CMD2=$C0 is the start digit position(left most)
Const CMD3 = $8B 'CMD3=$8A is the end command that turns the display on and sets brightness
'(CMD3=$8F for max brightness - see TM1637 spec sheet)
Const CharX as Byte[10] =
(0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F)
Dim Disp as byte [4]
'=========================================================================================
Sub Procedure StartSeq
SCK = 1
SDA = 0 'The Start sequence takes SDA low and then SCK low 5 uSec later
Delay_us(5)
SDA = 0
Delay_us(5)
End sub
'=========================================================================================
'=========================================================================================
Sub Procedure AckSeq
'=========================================================================================
SCK = 0 'The ACK waits for the TM1637 to assert low on SDA
Delay_us(5) 'and then replies with a 5 uSec ACK pulse on SCK
IF SDA = 0 THEN
SCK = 1
Delay_us(5)
SCK = 0
END IF
End Sub
'=========================================================================================
'=========================================================================================
Sub procedure ShiftOut(dim databyte as byte)
'=========================================================================================
dim bits as byte
SCK = 0 'Start Clock low
For bits = 0 to 7
databyte = byte(databyte >> 1) 'Least Significant Bit First
If STATUS.0 = 0 Then 'Shifted bit is in Carry Bit of Status Register
PORTB.1 = 0 'Put bit data on output
Else
PORTB.1 = 1
End If
PORTB.4 = 1 'Clock High
Delay_us(5)
PORTB.4 = 0 'Clock Low
Next bits 'Get next bit
end sub
'=========================================================================================
Sub Procedure StopSeq
'=========================================================================================
SCK = 0 'The stop sequence takes SCK high and then SDA high 5 uSec later
SDA = 0
Delay_us(5)
SCK = 1
Delay_us(5)
SDA = 1
Delay_us(5)
SDA = 0
End Sub
'=========================================================================================
Sub Procedure Write_Display
'=========================================================================================
StartSeq()
ShiftOut(CMD2) 'This shifts out the 8-bit command character $C0 that places
AckSeq() 'the first character CHR1 in the leftmost digit location
ShiftOut(charX[disp[0]]) 'ShiftOut CHR1-CHR4 to fill the display left to right
AckSeq() 'TM1637 auto-increment mode
ShiftOut(charX[disp[1]]) 'ShiftOut CHR1-CHR4 to fill the display left to right
AckSeq() 'TM1637 auto-increment mode
ShiftOut(charX[disp[2]]) 'ShiftOut CHR1-CHR4 to fill the display left to right
AckSeq() 'TM1637 auto-increment mode
ShiftOut(charX[disp[3]]) 'ShiftOut CHR1-CHR4 to fill the display left to right
AckSeq() 'TM1637 auto-increment mode
StopSeq()
End sub
'=========================================================================================
Main:
'=========================================================================================
OSCCON = %01110000 '8MHz internal
ANSELB = 0 'Port B Digital
TRISB = %00000000 'Port B Output
Startseq() 'ShiftOut Mode 0 - LSB first, clock normally low
ShiftOut(CMD1) 'This shifts out the 8-bit write command character $40
AckSeq()
StopSeq()
Startseq()
ShiftOut(CMD3) 'Intensity
AckSeq()
StopSeq()
Disp[0] = 0
Disp[1] = 0
Disp[2] = 0
Disp[3] = 0
While true
Disp[3] = Disp[3] + 1
if disp[3] > 9 then disp[3] = 0 disp[2] = Disp[2] + 1 end if
if disp[2] > 9 then disp[2] = 0 disp[1] = disp[1] + 1 end if
if disp[1] > 9 then disp[1] = 0 Disp[0] = disp[0] + 1 end if
if disp[0] > 0 then disp[3] = 0 disp[2] = 0 disp[1] = 0 disp[0] = 0 end if
Write_Display()
Delay_ms(50)
Wend
End.
Golden Member
En nog een MikroBasic voorbeeldje om te delen:
Temperatuurmetertje, met de MCP9801 en display TM1637.
Één cijfer achter de komma, met decimale punten (colon) getoond.
Golden Member
Volgende oefening die ik wilde doen was om ook de vochtigheid te meten.
Na wat speuren in Farnell kwam ik op de SHTC3. Deze meet ook tevens temperatuur en is I2C.
Is dit een aan te bevelen oefendingetje?
Golden Member
Ik vroeg me even af,
Is in MikroBasic het verschil tussen
pic basic code:
Dim a as byte
Dim b as byte
en
pic basic code:
Dim a as byte
b as byte
alleen cosmetisch? M.a.w. de compiler maakt er exact hetzelfde van of of kost variant 1 meer ruimte?
Special Member
Geen verschil. Ikzelf vindt de 2e methode wat netter staan...
Golden Member
Vind ik ook, daarom heb ik het zelf ook doorgevoerd in mijn programma's.
.