MikroBasic en de DS18B20

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..
Arco

Special Member

code:

    TmpB = (6 * (lo(temp) >> 4) + (lo(temp) >> 6)) / 10

De tweede extra nul kan dan ook weg.

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

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).

Fouten zijn het bewijs dat je het probeert..
Arco

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
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Fouten zijn het bewijs dat je het probeert..
Arco

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")
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

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 
Fouten zijn het bewijs dat je het probeert..
Bavelt

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?)

Fouten zijn het bewijs dat je het probeert..
Arco

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... :(

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

Golden Member

Ja, inderdaad.
Nogmaals, ik dacht dat het een I2C-er was. Op zich een leuk klein displaytje, maar met de verkeerde chip..

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

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

Golden Member

Dat doe ik ook. Deze displaytjes vergeet ik. Zonder om er energie in te steken met zoveel betere alternatieven. :)

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Deze had ik al een keer gebruikt; weliswaar geen spi of i2c, maar werken ook wel leuk.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

https://nl.aliexpress.com/item/32956123955.html

Ik heb ze nog niet gezien als 4 displays uitvoering met MAX7219.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Waarschijnlijk omdat de MAX7219 nu eenmaal 8 displays kan aansturen...

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

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.
Fouten zijn het bewijs dat je het probeert..
Bavelt

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.

Fouten zijn het bewijs dat je het probeert..
Bavelt

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?

Fouten zijn het bewijs dat je het probeert..
Bavelt

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?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Geen verschil. Ikzelf vindt de 2e methode wat netter staan...

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

Golden Member

Vind ik ook, daarom heb ik het zelf ook doorgevoerd in mijn programma's.

.

Fouten zijn het bewijs dat je het probeert..