MikroBasic en de DS18B20

Arco

Special Member

Het zou kunnen dat het lcd display al pull-ups aan boord heeft, dan moet je de externe pull-ups weglaten...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Tjonge, hardnekkig hoor. :(

Ik heb nu de LCD op I2C1 gezet, de MCP9801 op I2C2.
Gescheiden dus.
Met 4K7 pullup aan de LCD en 2K2 aan de MCP9801.

Blijft hetzelfde: de led toont aan dat het strandt op de I2C1 (wegschrijven naar de LCD).

Én de 255 van de Lower Bit blijft ook hetzelfde: alle bits hoog, dus 255.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Het zou kunnen dat het lcd display al pull-ups aan boord heeft, dan moet je de externe pull-ups weglaten...

Nee, die zitten er blijkbaar niet. Ik heb ze eruit gehaald en dan doet de display het niet.
Dus er maar weer in, nu loopt hij weer. (en zo te zien loopt het door ook nog)

Grote vraag blijft waarom die lower bits op high staan. (of worden weergegeven, of niet goed worden uitgelezen)

Misschien is er een assembler voorbeeld met een MCP9801? Dan zou ik dat eens kunnen proberen.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

(ik gebruik wel de pic24 compiler)

Daarmee bedoel je dat je in MikroBasic een PIC24 type hebt geselecteerd (dus geen andere separate compiler geinstalleerd)?

Ik wil dat ook best wel eens proberen.
Een suggestie: zou een PIC24F16KL402 kunnen?
Waarom deze? Die heeft een DIL package (en kan ik dus gewoon in een breadboard prikken) en is goedkoop.

Wellicht zijn er nog andere. Ik ken de 24F reeks niet.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Voor de PIC24 moet je de dsPic/Pic24 compiler downloaden... (de 8 en 16 bitters zijn totaal verschillend qua opbouw)
De 24FJ16KL402 heb ik nooit gebruikt. Alleen de 24FJ256GA108/24FJ128GA70x...

[Bericht gewijzigd door Arco op donderdag 16 januari 2020 23:19:20 (17%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Hmm, dat zijn meteen van die 'joekels' die je niet zomaar even aansluit.

Ik dacht ik zoek iets om even uit te proberen op mijn breadboard.

Ondertussen heb ik van alles geprobeerd: de voedingsspanning terugbrengen naar 3V3, de pull-ups wijzigen (in de datasheet noemen ze zelfs hoge waarden van 14K3 tot 50K bij 5V).
Andere instellingen in de resolutie mbv CONFIG register.
Leesroutine aangepast, gespeeld met bytes, integers en words.

Ik heb voor de zekerheid zelfs een derde MCP9801 gesoldeerd. Maar niks hielp, de lower bits van de temp blijven hoog.
Terwijl het bij de Arduino meteen raak is.

Daarom lijkt het toch een beetje in de compiler te zitten, alhoewel het me wat sterk lijkt.
Temeer omdat het eerste byte gewoon wordt gelezen.

Maar ja, wat blijft er over. Het is mijn eer te na weer terug te gaan naar de DS18B20. :/

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Dit is de 'sketch' van Arduino.
Het programma doet eigenlijk helemaal hetzelfde. De sensor is een ander type maar het werkt wel meteen.

c code:

/Project 6.03 Read TCN75A Temperature Sensor
#include <Wire.h>  
int tempreg = 0;         
float temperature = 0;    
byte address = 72;

void setup(){ 
  Serial.begin(9600);
  Wire.begin();
  //Do some setup for the sensor 
  // Set the resolution of the measurement 
  Wire.beginTransmission(address);
  // point to Configuration Register
  Wire.write(0x01);   
  // set the resolution  
  Wire.write(0x60);   
  // ends the command  
  Wire.endTransmission();       
  // points to the Temperature Register  
  Wire.beginTransmission(address);  
  Wire.write(0x00);            
  Wire.endTransmission();        
} 

void loop(){
  // Receives data from the Temperature Register 
  Wire.requestFrom(address,byte(2)); 
  tempreg = Wire.read();       
  tempreg= tempreg << 8;      
  tempreg |= Wire.read();   
  tempreg = tempreg >> 4;  
  // Calculate the temperature
  temperature =( float ) tempreg / 16;
  // Display the temperature in the Serial Monitor 
  Serial.print("Temp F = ");
  Serial.print(temperature*9/5 + 32,2);
  Serial.print("   ");
  Serial.print("Temp C = ");
  Serial.println(temperature, 2); 
  delay(500);  
Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Met Set_Alert (28,32) kun je de alarmtemperatuur instellen. Bij 32° wordt de alarmuitgang hoog, bij 28° weer laag (hysteresis)

Dit werkt dus ook gewoon met MikroBasic programma.
Het 255 mysterie rest nog.

Ik zie uit publicaties dat de TCN75A ook wordt gebruikt, Heeft dezelfde pin layout en lijkt verdacht veel op de MCP9801.

Je kunt ze krijgen in verschillende nauwkeurigheden, gelijk aan de MCP9801.

Is dit een verouderd type (of juist nieuwer?)

Ik zou er een paar kunnen bestellen bij Farnell en het programma daar eens mee testen. Ze kosten bijna niks.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Op 17 januari 2020 13:02:17 schreef Bavelt:
[...]

Dit werkt dus ook gewoon met MikroBasic programma.
Het 255 mysterie rest nog.

Ik zie uit publicaties dat de TCN75A ook wordt gebruikt, Heeft dezelfde pin layout en lijkt verdacht veel op de MCP9801.

Je kunt ze krijgen in verschillende nauwkeurigheden, gelijk aan de MCP9801.

Is dit een verouderd type (of juist nieuwer?)

Ik zou er een paar kunnen bestellen bij Farnell en het programma daar eens mee testen. Ze kosten bijna niks.

EDIT: Kleine aanvulling: De TCN75A werkt weliswaar ook met 2 bytes temperatuur, maar de lower byte is hier redundant. De higher byte geeft de temperatuur aan in Graden, waarbij het LSB een 0,5 graad is.

Desondanks toch maar proberen, ik heb er twee besteld.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

De 9800 moet ook gewoon werken. Ik heb er al veel gebruikt, nog nooit een probleem gehad...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

De 9800 moet ook gewoon werken. Ik heb er al veel gebruikt, nog nooit een probleem gehad...

Kreeg ik het maar aan de praat. Zou ik toch ergens overheen kijken? Heb je wellicht toevallig een volledig MB programma in de aanbieding?
Die zijn dan wel op de PIC24 serie geënt, maar toch...

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik zit nog even het I2C protocol te bestuderen.
Zou het wellicht kunnen zitten in het geval dat de tweede read van het Tempregister te snel na de eerst komt?
Dat bv de master nog niet klaar is om de 2e te lezen?

Een Delay-MS(5) tussen de reads helpt niet, maar dat is denk ik ook niet de juiste methode.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Nou, Ik heb het aan de praat gekregen.

Alleen kan ik het zelf niet verklaren.

De Read Code:

pic basic code:

'========================================================================================
Sub Function MCP9800_Read(Dim pReg As Byte) As Word                 'Read
'========================================================================================
  I2C1_Start()                                                      'Start
  I2C1_Wr(0x90)                                                     'MCP write address
  I2C1_Wr(pReg)
  I2C1_Repeated_Start()                                             'Bus restart
  I2C1_Wr(0x91)                                                     'MCP read address
  If pReg = MCP9800_CONFIG Then                                     'Config reg. only
    Result = I2C1_Rd(1)                                             '1 byte long; rest
  Else                                                              'is 2 bytes
    Hi(Result) = I2C1_Rd(1)
    Lo(Result) = I2C1_Rd(0)
  End If
  I2C1_Stop()                                                       'Stop
  delay_ms(5)                                                       'Wait to complete
End Sub
 

Het werkt als je dus de ACK omdraait: eerst een (1) en dan een (0).

pic basic code:

Hi(Result) = I2C1_Rd(1)
Lo(Result) = I2C1_Rd(0)

Terwijl je het juist andersom verwacht.

Is dit te verklaren?

(Tenzij ACK een 1 is en een NAK een 0)

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

In de datasheet staat nl dit:

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Daar kwam ik ook net achter. Schijnbaar zijn de parameters omgekeerd:
Bij de Pic24 compiler is NACK een '1' en bij de gewone Pic compiler een '0'...
Loopt hier op een 16LF1939 die ik nog had liggen...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Op 18 januari 2020 15:31:13 schreef Bavelt:
Nou, Ik heb het aan de praat gekregen.

Alleen kan ik het zelf niet verklaren.

De Read Code:

pic basic code:

'========================================================================================
Sub Function MCP9800_Read(Dim pReg As Byte) As Word                 'Read
'========================================================================================
  I2C1_Start()                                                      'Start
  I2C1_Wr(0x90)                                                     'MCP write address
  I2C1_Wr(pReg)
  I2C1_Repeated_Start()                                             'Bus restart
  I2C1_Wr(0x91)                                                     'MCP read address
  If pReg = MCP9800_CONFIG Then                                     'Config reg. only
    Result = I2C1_Rd(1)                                             '1 byte long; rest
  Else                                                              'is 2 bytes
    Hi(Result) = I2C1_Rd(1)
    Lo(Result) = I2C1_Rd(0)
  End If
  I2C1_Stop()                                                       'Stop
  delay_ms(5)                                                       'Wait to complete
End Sub
 

Het werkt als je dus de ACK omdraait: eerst een (1) en dan een (0).

pic basic code:

Hi(Result) = I2C1_Rd(1)
Lo(Result) = I2C1_Rd(0)

Als ik in de datasheet kijk, dan staat er ook inderdaad na eerste byte lezen een ACK zenden, dan weer lezen en dan een NAK sturen.

Ja zou het m.i. wel andersom verwachten.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Bij de pic24 compiler is het de actuele staat van het ACK bit (hoog of laag)
Bij de gewone compiler betekent een '1' wel en een '0' geen ACK bit. Verwarrend, want de eigenlijke status is juist omgekeerd... ;)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Nou, dat is dan mooi opgelost. Zo zie je maar, de aanhouder wint ;)

De grote winst zit hem in het feit dat ik veel heb lopen grasduinen in datasheets, het I2c protocol bestuderen, testen met de Arduino. etc.

Nu nog een klein probleempje: de temp op de display tonen.

De 1e 4 bits van de lower byte geeft de eenheden van 0,0625 Graden aan.

Dus eerst delen door 4, dan maal 0,0625.

Nu heb ik dat gedaan met:

pic basic code:


Dim tp1 as float
tp1 = t2>>4 * 0.0625
FloatToStr(tp1, str) 

De laatste instructie veroorzaakt "not enough rom space". Wat ik er ook uithaal in het programma.

Wat maakt nu dat de conversie van float naar string (heb ik op 20 gezet) alle ruimte blijkbaar opeet? :?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Ik gebruik:

pic basic code:


   tempword = MCP9800_Read(MCP9800_TEMP)
   TmpFloat = Tempword / 256.0                                       
   FloatToStr(TmpFloat, Str)                                         
   Str[5] = chr(0)

De Float library gebruikt natuurlijk wel heel veel geheugen (iets van 500 words), dus 't zou goed kunnen dat je geheugen op is...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Inderdaad slim, om het hele word te delen door 256. Dan krijg je meteen de juiste waarde.

Tjonge, Dat die float library zoveel ruimte in beslag neemt!
Want ook met deze constructie heb ik ruimtegebrek.

alhoewel de ruimte zonder het FloatToStr commando voldoende lijkt:

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Floating point vindt een standaard MCU helemaal niet leuk.
Hier groeit het programma van 1268 words (zonder float) naar 3405 words (met float)...

Beter is bij weinig geheugen om de temperatuur en het fractionele deel beiden als integer te behandelen. Iets minder precies, maar scheelt veel geheugen.
Dit gebruikt meer als 2000 words minder...

code:


  temp = MCP9800_Read(MCP9800_TEMP)
  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
  ByteToStr(TmpB,  str)
  lTrim(str)
  If Length(Str) = 1 Then Str = "0" + Str End If
  Lcd_Out (1,9, "." + str + " C")
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Nou, het is al met al keurig gelukt!

Ik had dit er van gemaakt:

Het volledige project is als bijlage gepost.

pic basic code:

'==============================================================================
 Program Temp_MCP9801
'Temp sensor:     MCP9801
'MicroController: PIC16F1827
'Display:         OLED 0,96" I2C
'------------------------------------------------------------------------------

const Dos8x16ext As Byte [1520]=   (
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  '
  0x00,0x00,0x00,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x33,0x00,0x00,0x00,  ' !
  0x00,0xF3,0xF3,0x00,0x00,0xF3,0xF3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  ' "
  0x30,0xF3,0xF3,0x30,0x30,0xF3,0xF3,0x30,0x03,0x0F,0x0F,0x03,0x03,0x0F,0x0F,0x03,  ' #
  0x00,0x78,0xF3,0xCF,0xCF,0xCC,0x8C,0x00,0x00,0x0C,0x0C,0x3C,0x3C,0x0F,0x07,0x00,  ' $
  0x00,0x1C,0x1C,0xC0,0xF0,0x3C,0x0C,0x00,0x00,0x0C,0x0F,0x03,0x00,0x0E,0x0E,0x00,  ' %
  0x00,0xD8,0xFC,0xCC,0x7C,0x18,0x00,0x00,0x1F,0x3F,0x31,0x33,0x1F,0x3F,0x33,0x00,  ' &
  0x00,0x00,0x00,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  ' '
  0x00,0x00,0x00,0xF0,0xF8,0x1C,0x04,0x00,0x00,0x00,0x00,0x0F,0x1F,0x38,0x20,0x00,  ' (
  0x00,0x04,0x1C,0xF8,0xF0,0x00,0x00,0x00,0x00,0x20,0x38,0x1F,0x0F,0x00,0x00,0x00,  ' )
  0xC0,0xCC,0xFC,0xF0,0xF0,0xFC,0xCC,0xC0,0x00,0x0C,0x0F,0x03,0x03,0x0F,0x0C,0x00,  ' *
  0x00,0xC0,0xC0,0xF8,0xF8,0xC0,0xC0,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,  ' +
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x7C,0x3C,0x00,0x00,0x00,  ' ,
  0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  ' -
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x00,0x00,0x00,  ' .
  0x00,0x00,0x00,0x80,0xE0,0x7C,0x1C,0x00,0x00,0x38,0x3E,0x07,0x01,0x00,0x00,0x00,  ' /
  0x00,0xF8,0xFC,0x0C,0x8C,0xFC,0xF8,0x00,0x00,0x1F,0x3F,0x31,0x30,0x3F,0x1F,0x00,  ' 0
  0x00,0x00,0x30,0xFC,0xFC,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,  ' 1
  0x00,0x38,0x3C,0x0C,0xCC,0xFC,0x38,0x00,0x00,0x30,0x3C,0x3F,0x33,0x30,0x30,0x00,  ' 2
  0x00,0x0C,0x0C,0xCC,0xFC,0x3C,0x0C,0x00,0x00,0x1C,0x3C,0x30,0x33,0x3F,0x1C,0x00,  ' 3
  0x00,0x00,0xC0,0xF0,0xFC,0xFC,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x3F,0x3F,0x0C,0x00,  ' 4
  0x00,0xFC,0xFC,0xCC,0xCC,0xCC,0x8C,0x00,0x00,0x18,0x38,0x30,0x30,0x3F,0x1F,0x00,  ' 5
  0x00,0xF0,0xF8,0x9C,0x8C,0x8C,0x00,0x00,0x00,0x1F,0x3F,0x31,0x31,0x3F,0x1F,0x00,  ' 6
  0x00,0x0C,0x0C,0x0C,0xCC,0xFC,0x3C,0x00,0x00,0x00,0x3C,0x3F,0x03,0x00,0x00,0x00,  ' 7
  0x00,0x38,0xFC,0xCC,0xCC,0xFC,0x38,0x00,0x00,0x1F,0x3F,0x30,0x30,0x3F,0x1F,0x00,  ' 8
  0x00,0x78,0xFC,0xCC,0xCC,0xFC,0xF8,0x00,0x00,0x00,0x30,0x30,0x38,0x1F,0x0F,0x00,  ' 9
  0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x00,0x00,0x00,  ' :
  0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0xC0,0x7C,0x3C,0x00,0x00,0x00,  ' ;
  0x80,0xC0,0xE0,0x70,0x38,0x18,0x08,0x00,0x00,0x01,0x03,0x07,0x0E,0x0C,0x08,0x00,  ' <
  0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x03,0x03,0x03,0x03,0x03,0x03,0x00,  ' =
  0x08,0x18,0x38,0x70,0xE0,0xC0,0x80,0x00,0x08,0x0C,0x0E,0x07,0x03,0x01,0x00,0x00,  ' >
  0x00,0x38,0x3C,0x0C,0xCC,0xFC,0x38,0x00,0x00,0x00,0x00,0x37,0x37,0x00,0x00,0x00,  ' ?
  0xF0,0xF8,0x1C,0xCC,0x4C,0x98,0xF0,0x00,0x0F,0x1F,0x38,0x33,0x32,0x33,0x19,0x00,  ' @
  0x00,0xF0,0xF8,0x1C,0x1C,0xF8,0xF0,0x00,0x00,0x3F,0x3F,0x03,0x03,0x3F,0x3F,0x00,  ' A
  0x00,0xFC,0xFC,0xCC,0xCC,0xFC,0x78,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x1F,0x00,  ' B
  0x00,0xF8,0xFC,0x0C,0x0C,0x3C,0x38,0x00,0x00,0x1F,0x3F,0x30,0x30,0x3C,0x1C,0x00,  ' C
  0x00,0xFC,0xFC,0x0C,0x1C,0xF8,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x38,0x1F,0x0F,0x00,  ' D
  0x00,0xFC,0xFC,0xCC,0xCC,0xCC,0x0C,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x00,  ' E
  0x00,0xFC,0xFC,0xCC,0xCC,0xCC,0x0C,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,  ' F
  0x00,0xF8,0xFC,0x0C,0xCC,0xCC,0xCC,0x00,0x00,0x1F,0x3F,0x30,0x30,0x3F,0x1F,0x00,  ' G
  0x00,0xFC,0xFC,0xC0,0xC0,0xFC,0xFC,0x00,0x00,0x3F,0x3F,0x00,0x00,0x3F,0x3F,0x00,  ' H
  0x00,0x0C,0x0C,0xFC,0xFC,0x0C,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x00,0x00,  ' I
  0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0x00,0x00,0x1C,0x3C,0x30,0x30,0x3F,0x1F,0x00,  ' J
  0xFC,0xFC,0xC0,0xF0,0x3C,0x0C,0x00,0x00,0x3F,0x3F,0x00,0x03,0x0F,0x3C,0x30,0x00,  ' K
  0x00,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x00,  ' L
  0xFC,0xFC,0x70,0xC0,0x70,0xFC,0xFC,0x00,0x3F,0x3F,0x00,0x01,0x00,0x3F,0x3F,0x00,  ' M
  0x00,0xFC,0xFC,0xE0,0x80,0xFC,0xFC,0x00,0x00,0x3F,0x3F,0x01,0x07,0x3F,0x3F,0x00,  ' N
  0x00,0xF8,0xFC,0x0C,0x0C,0xFC,0xF8,0x00,0x00,0x1F,0x3F,0x30,0x30,0x3F,0x1F,0x00,  ' O
  0x00,0xFC,0xFC,0x0C,0x0C,0xFC,0xF8,0x00,0x00,0x3F,0x3F,0x03,0x03,0x03,0x01,0x00,  ' P
  0x00,0xF8,0xFC,0x0C,0x0C,0xFC,0xF8,0x00,0x00,0x1F,0x3F,0x38,0x1E,0x3F,0x37,0x00,  ' Q
  0xFC,0xFC,0x8C,0x8C,0xFC,0xF8,0x00,0x00,0x3F,0x3F,0x01,0x03,0x0F,0x3C,0x30,0x00,  ' R
  0x00,0x78,0xFC,0xCC,0x8C,0x8C,0x18,0x00,0x00,0x18,0x31,0x31,0x33,0x3F,0x1E,0x00,  ' S
  0x00,0x0C,0x0C,0xFC,0xFC,0x0C,0x0C,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,  ' T
  0x00,0xFC,0xFC,0x00,0x00,0xFC,0xFC,0x00,0x00,0x1F,0x3F,0x30,0x30,0x3F,0x1F,0x00,  ' U
  0x00,0xFC,0xFC,0x00,0x00,0xFC,0xFC,0x00,0x00,0x03,0x0F,0x3C,0x3C,0x0F,0x03,0x00,  ' V
  0xFC,0xFC,0x00,0x80,0x00,0xFC,0xFC,0x00,0x3F,0x1F,0x0E,0x07,0x0E,0x1F,0x3F,0x00,  ' W
  0x00,0x1C,0x7C,0xE0,0xE0,0x7C,0x1C,0x00,0x00,0x38,0x3E,0x07,0x07,0x3E,0x38,0x00,  ' X
  0x00,0x3C,0xFC,0xC0,0xC0,0xFC,0x3C,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,  ' Y
  0x00,0x0C,0x0C,0xCC,0xFC,0x3C,0x0C,0x00,0x00,0x3C,0x3F,0x33,0x30,0x30,0x30,0x00,  ' Z
  0x00,0x00,0x00,0xFC,0xFC,0x0C,0x0C,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x00,  ' [
  0x00,0x0C,0x0C,0xFC,0xFC,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x00,0x00,0x00,  ' \
  0x80,0xE0,0x78,0x1E,0x78,0xE0,0xE0,0x00,0x01,0x01,0x00,0x00,0x00,0x01,0x01,0x00,  ' ]
  0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  ' ^
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,  ' _
  0x00,0x07,0x0E,0x1C,0x38,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  ' `
  0x00,0x00,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x1E,0x3F,0x33,0x33,0x3F,0x3F,0x00,  ' a
  0x00,0xFC,0xFC,0x60,0x60,0xE0,0xC0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x1F,0x00,  ' b
  0x00,0xC0,0xE0,0x60,0x60,0x60,0x00,0x00,0x00,0x1F,0x3F,0x30,0x30,0x30,0x30,0x00,  ' c
  0x00,0xC0,0xE0,0x60,0x60,0xFC,0xFC,0x00,0x00,0x1F,0x3F,0x30,0x30,0x3F,0x3F,0x00,  ' d
  0x00,0xC0,0xE0,0x60,0x60,0xE0,0xC0,0x00,0x00,0x1F,0x3F,0x32,0x32,0x33,0x33,0x00,  ' e
  0x00,0xC0,0xC0,0xF8,0xFC,0xCC,0xCC,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,  ' f
  0x00,0xC0,0xE0,0x60,0x60,0xE0,0xE0,0x00,0x00,0xCF,0xDF,0xD8,0xD8,0xFF,0x7F,0x00,  ' g
  0x00,0xFC,0xFC,0x60,0x60,0xE0,0xC0,0x00,0x00,0x3F,0x3F,0x00,0x00,0x3F,0x3F,0x00,  ' h
  0x00,0x00,0x60,0xEC,0xEC,0x00,0x00,0x00,0x00,0x00,0x30,0x3F,0x3F,0x30,0x00,0x00,  ' i
  0x00,0x00,0x00,0x00,0xEC,0xEC,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xFF,0x7F,0x00,0x00,  ' j
  0xFC,0xFC,0x80,0xC0,0xE0,0x60,0x00,0x00,0x3F,0x3F,0x03,0x07,0x1E,0x38,0x30,0x00,  ' k
  0x00,0x00,0x0C,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x30,0x3F,0x3F,0x30,0x00,0x00,  ' l
  0xC0,0xE0,0xE0,0xC0,0xE0,0xE0,0xC0,0x00,0x3F,0x3F,0x00,0x07,0x00,0x3F,0x3F,0x00,  ' m
  0x00,0xC0,0xE0,0x60,0x60,0xE0,0xC0,0x00,0x00,0x3F,0x3F,0x00,0x00,0x3F,0x3F,0x00,  ' n
  0x00,0xC0,0xE0,0x60,0x60,0xE0,0xC0,0x00,0x00,0x1F,0x3F,0x30,0x30,0x3F,0x1F,0x00,  ' o
  0x00,0xE0,0xE0,0x60,0x60,0xE0,0xC0,0x00,0x00,0xFF,0xFF,0x30,0x30,0x3F,0x1F,0x00,  ' p
  0x00,0xC0,0xE0,0x60,0x60,0xE0,0xE0,0x00,0x00,0x1F,0x3F,0x30,0x30,0xFF,0xFF,0x00,  ' q
  0x00,0xE0,0xE0,0x60,0x60,0xE0,0xC0,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,  ' r
  0x00,0xC0,0xE0,0x60,0x60,0x60,0x60,0x00,0x00,0x31,0x33,0x33,0x36,0x3E,0x3C,0x00,  ' s
  0x00,0x60,0x60,0xF8,0xF8,0x60,0x60,0x00,0x00,0x00,0x00,0x1F,0x3F,0x30,0x30,0x00,  ' t
  0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x1F,0x3F,0x30,0x30,0x3F,0x3F,0x00,  ' u
  0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x03,0x0F,0x3C,0x3C,0x0F,0x03,0x00,  ' v
  0xE0,0xE0,0x00,0x80,0x00,0xE0,0xE0,0x00,0x3F,0x1F,0x0E,0x07,0x0E,0x1F,0x3F,0x00,  ' w
  0x00,0x60,0xE0,0x80,0x80,0xE0,0x60,0x00,0x00,0x30,0x3D,0x0F,0x0F,0x3D,0x30,0x00,  ' x
  0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xCF,0xDF,0xD8,0xD8,0xFF,0x7F,0x00,  ' y
 '0x00,0x60,0x60,0x60,0xE0,0xE0,0x60,0x00,0x00,0x30,0x3C,0x3F,0x33,0x30,0x30,0x00,  ' z
  0x80,0x80,0xC0,0xFC,0x7E,0x02,0x02,0x00,0x01,0x01,0x03,0x3F,0x7E,0x40,0x40,0x00,  ' {
  0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x00,0x00,0x00,  ' |
  0x02,0x02,0x7E,0x7C,0xC0,0x80,0x80,0x00,0x40,0x40,0x7E,0x3F,0x03,0x01,0x01,0x00,  ' }
  0xC0,0x60,0xE0,0xC0,0x80,0x80,0xE0,0x00,0x01,0x00,0x00,0x01,0x01,0x01,0x00,0x00)  ' ~

Dim Temp  as Word
    Temp2 as integer
    Str as string[5]

Const MCP9800_TEMP     = 0x00                                       'MCP9800 registers
      MCP9800_CONFIG   = 0x01                                       '  "
      MCP9800_HYST     = 0x02                                       '  "
      MCP9800_ALERT    = 0x03                                       '  "

'==================================================================================================
Sub Procedure Lcd_WrCmd(Dim pCmd As Byte)                       'Write data to display
'==================================================================================================
  while Not (i2c1_Is_Idle) wend
  i2c1_Start()
  i2c1_Wr(0x78)
  i2c1_Wr(0x80)
  i2c1_Wr(pCmd)
  i2c1_Stop()
End Sub

'==================================================================================================
Sub Procedure Lcd_WrDat(Dim pDat As Byte)                       'Write data to display
'==================================================================================================
  while Not (i2c1_Is_Idle) wend
  i2c1_Start()
  i2c1_Wr(0x78)
  i2c1_Wr(0x40)
  i2c1_Wr(pDat)
  Delay_ms(1)
  i2c1_Stop()
End Sub

'==================================================================================================
Sub Procedure Lcd_SetPos(Dim px, py as Byte)                    'Set write position on display
'==================================================================================================
  Lcd_WrCmd(0xB0 + py)
  Lcd_WrCmd(0xB0 + py)
  Lcd_WrCmd((px  >> 4) Or 0x10)
  Lcd_WrCmd(px And 0x0F)
End Sub
'
'===============================================================================
Sub Procedure Lcd_Char_8x16(Dim px, py, pchar As Byte)
'===============================================================================
  Dim lIndex As Word
  '----------------------------------------------------------------------------
  lIndex = pChar - 0x20
  lIndex = (lIndex << 4)

  Lcd_SetPos(px, py)
  Lcd_WrDat(Dos8x16ext[lIndex+0])
  Lcd_WrDat(Dos8x16ext[lIndex+1])
  Lcd_WrDat(Dos8x16ext[lIndex+2])
  Lcd_WrDat(Dos8x16ext[lIndex+3])
  Lcd_WrDat(Dos8x16ext[lIndex+4])
  Lcd_WrDat(Dos8x16ext[lIndex+5])
  Lcd_WrDat(Dos8x16ext[lIndex+6])
  Lcd_WrDat(Dos8x16ext[lIndex+7])

  Lcd_SetPos(px, py+1)
  Lcd_WrDat(Dos8x16ext[lIndex+8])
  Lcd_WrDat(Dos8x16ext[lIndex+9])
  Lcd_WrDat(Dos8x16ext[lIndex+10])
  Lcd_WrDat(Dos8x16ext[lIndex+11])
  Lcd_WrDat(Dos8x16ext[lIndex+12])
  Lcd_WrDat(Dos8x16ext[lIndex+13])
  Lcd_WrDat(Dos8x16ext[lIndex+14])
  Lcd_WrDat(Dos8x16ext[lIndex+15])
End Sub
'
'===============================================================================
Sub Procedure LCD_Fill(Dim pFill As Byte)     'Fill display with character pFill
'===============================================================================
  Dim lx, ly As Byte
  For ly = 0 To 8
  LCD_wrCmd(0xB0 + ly)
  LCD_wrCmd(0x01)
  LCD_wrCmd(0x10)
    For lx = 0 to 131
      Lcd_wrDat(pFill)
    Next lx
  Next ly
End Sub

'===============================================================================
Sub Procedure Lcd_String_8x16(Dim px, py As Byte, Dim ByRef pDisp As String)
'===============================================================================
  Dim lLen, lCnt As Byte
  '----------------------------------------------------------------------------
  lLen = Length(pDisp)
  For lCnt = 0 To (lLen-1)
    Lcd_Char_8x16(px+1, py, pDisp[lCnt])
    px = px + 8
  Next lCnt
End Sub

'===============================================================================
Sub Procedure Display_Init()
'===============================================================================
  Lcd_WrCmd(0xA8)                                 'Multiplex ratio set to
  Lcd_WrCmd(0x3F)                                 '63
  Lcd_WrCmd(0xD3)                                 'Display offset RAM counter
  Lcd_WrCmd(0x00)                                 'none
  Lcd_WrCmd(0x40)                                 'Start line address
  Lcd_WrCmd(0xA1)                                 'Set segment remap rotation to left
  Lcd_WrCmd(0xC8)                                 'Common output scan direction
  Lcd_WrCmd(0xDA)                                 'Common signals pad
  Lcd_WrCmd(0x12)                                 'value
  Lcd_WrCmd(0x81)                                 'Contrast control
  Lcd_WrCmd(0xFF)                                 'value
  Lcd_WrCmd(0xA4)
  Lcd_WrCmd(0xA6)                                 'Normal display
  Lcd_WrCmd(0xD5)                                 'Clock ratio:oscillator frequency
  Lcd_WrCmd(0x80)                                 'oooo:rrrr
  Lcd_WrCmd(0x8D)
  Lcd_WrCmd(0x14)
  Lcd_WrCmd(0x00)                                 'Set lower column address
  Lcd_WrCmd(0x10)                                 'Set higher column address
  Lcd_WrCmd(0xD9)                                 '15 clocks, discharge 1 clock
  Lcd_WrCmd(0xF1)                                 'dddd:pppp
  Lcd_WrCmd(0xDB)                                 'Common output voltage
  Lcd_WrCmd(0x40)                                 'level
  Lcd_WrCmd(0x20)                                 'Addressing mode
  Lcd_WrCmd(0x02)                                 'value
  Lcd_WrCmd(0xAE)                                 'Turn OLED panel off
End Sub

'========================================================================================
Sub Function MCP9800_Read(Dim pReg As Byte) As Word                 'Read
'========================================================================================
  While Not (i2c1_Is_Idle) wend
  i2c1_Start()                                                      'Start
  i2c1_Wr(0x90)                                                     'MCP write address
  i2c1_Wr(pReg)
  i2c1_Repeated_Start()                                             'Bus restart
  i2c1_Wr(0x91)                                                     'MCP read address
  If pReg = MCP9800_CONFIG Then                                     'Config reg. only
    Result = i2c1_Rd(1)                                             '1 byte long; rest
  Else                                                              'is 2 bytes
    Hi(Result) = i2c1_Rd(1)
    Lo(Result) = i2c1_Rd(0)
  End If
  i2c1_Stop()                                                       'Stop
  delay_ms(5)                                                       'Wait to complete
End Sub

'========================================================================================
Sub Procedure MCP9800_Write(Dim pReg As Byte, dim lData As Word)    'Write
'========================================================================================
  while Not (i2c1_Is_Idle) wend
  i2c1_Start()                                                      'Start
  i2c1_Wr(0x90)                                                     'MCP write address
  i2c1_Wr(pReg)                                                     '
  If pReg = MCP9800_CONFIG Then                                     'Config re. only
    i2c1_Wr(lData)                                                  '1 byte long; rest
  Else                                                              'is 2 bytes
    i2c1_Wr(Hi(lData))
    i2c1_Wr(Lo(lData))
  End If
  i2c1_Stop()                                                       'Stop
  delay_ms(5)                                                       'Wait to complete
End Sub                             '

'========================================================================================
Sub Procedure MCP9800_SetAlert(Dim pMin, pMax As Byte)
'========================================================================================
  MCP9800_Write(MCP9800_HYST, pMin<<8)                              'Sets min/max temp
  MCP9800_Write(MCP9800_ALERT, pMax<<8)                             '
End Sub                                                             '                 '

'==============================================================================
main:


''==============================================================================
  OSCCON = %01111000                             '16 Mhz Internal
  ANSELB = 0                                     'All output/digital
  TRISB = %00010010                              'Port B1 (SDA) and 4(SCK) Input
  i2c1_init(100000)                              'Init i2c port 100kHz
  Delay_ms(20)
  Display_Init()
  LCD_wrCmd(0xAF)                                'Turn Oled Panel on

  LCD_Fill(0x00)                                 'Clear Screen
  LCD_Setpos(0,0)
  Lcd_String_8x16(0,0, "Temp: ")
  Lcd_String_8x16(56,0, ",")

  MCP9800_Write(MCP9800_CONFIG, %01100000)       '12 bits resolution
 ' MCP9800_SetAlert(25,28)

  While True
   Temp = MCP9800_Read(MCP9800_TEMP)
   BytetoStr(Hi(temp), str)
   Lcd_String_8x16(32, 0,str)
   Temp2 = LO(Temp) >>4 * 6
   ByteTostr(temp2, str)
   Ltrim(str)
   Lcd_String_8x16(60, 0,str)
   Delay_ms(350)
 Wend
end. 
Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

temp = MCP9800_Read(MCP9800_TEMP)
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
ByteToStr(TmpB, str)
lTrim(str)
If Length(Str) = 1 Then Str = "0" + Str End If
Lcd_Out (1,9, "." + str + " C")

Deze aanvulling kan ik er ook wel in doen.
Ik ben reuze bij dat het werkt.

Het issue met het blijven 'hangen' van de processor na x cycli treedt alleen op bij een Oled schermpje van 1,3". De 0,96" versie geeft geen enkel probleem.
Daar zit dus nog even iets raars (of het 1,3"schermpje is stuk, ik heb er maar 1)

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Als je er

code:

  Temp2 = 6 * (lo(temp) >> 4) + lo(temp) >> 6

van maakt is de waarde wat nauwkeuriger...
De extra '0' is nodig voor waardes kleiner als 10. (anders springt de boel zenuwachtig heen en weer)

Bij kleine processors met weinig geheugen altijd proberen floats buiten de deur te houden... ;)

[Bericht gewijzigd door Arco op zaterdag 18 januari 2020 21:46:50 (19%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Het wordt steeds mooier.. ;)

Wat is nu een handige methode om het op 1 decimaal (afgerond) weer te geven?

Fouten zijn het bewijs dat je het probeert..