![]() |
Forum Index : Microcontroller and PC projects : PicoMite/PicoMiteVGA V5.07.04 betas
![]() ![]() ![]() ![]() |
|||||
Author | Message | ||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6218 |
Problems reading the DS18B20 I have two chips. One good and one suspect. Both chips function correctly using a MX170 or CMM2 (which use the same code as the picomite) On the picomite, both chips work when using the TEMPR function with or without pullups. Using the ONEWIRE functions, the only combination that works is my known good chip without any pullup. Known good DS18B20 with 4.7k pullup, external power TEMPR command works OK ONEWIRE version fails Known good DS18B20 without any pullup, external power TEMPR command works OK ONEWIRE version works OK Suspect DS18B20 with 4.7k pullup, external power TEMPR command works OK ONEWIRE version fails Suspect DS18B20 without any pullup, external power TEMPR command works OK ONEWIRE version fails There seems to be a timing vulnerability, especially evident using the ONEWIRE commands. Both the rom serial number bytes and the scratchpad are corrupted by getting an extraneous first bit of each byte. Most of the time, I can find the correct values by shifting the bytes by one bit and inserting a new high bit. The problem is knowing if that high bit should be a 1 or 0. The CMM2 uses different timing for the read function.(picomite uses 6,8,56 uS) int ow_readBit(int pin) { int result; PinSetBit(pin, LATCLR); // drive pin low uSec(3); PinSetBit(pin, TRISSET); // set as input PinSetBit(pin, LATSET); // release the bus uSec(10); result = PinRead(pin); // read pin PinSetBit(pin, TRISCLR); // set as output uSec(53); // wait 56uSec return result; } Can we try those timings to see if it makes a difference? In the scratchpad, the first two bytes are temperature and the 5th byte is resolution and should be 1F, 3F, 5F or 7F The bas program I have been using to test. It's been heavily butchered over the last 2 days as I tried all sorts of ideas to determine the reasons. 'DS18x20 test code by TassyJim DIM INTEGER PinNbr = 24 ' 22 DIM FLOAT tem PRINT "Family name: ";FamilyName$(PinNbr) PRINT "Rom Code: ";getRomCode$(PinNbr) PRINT "Shifted : ";bitshift$(getRomCode$(PinNbr)) PRINT "ScratchPad: ";getScratchpad$(PinNbr) PRINT "Shifted : ";bitshift$(getScratchpad$(PinNbr)) IF powerMode(PinNbr) THEN PRINT "Power mode External" ELSE PRINT "Power mode Parasitic" ENDIF tem =TEMPR(PinNbr) PRINT "temperature= "; tem PRINT "scratchpad ";HEX$(tem*16-256,2);" 01..." FOR n = 0 TO 3 TIMER = 0 PRINT "Temperature: ";getTemp(PinNbr,n);" ";TIMER;"mS,";n+9;" bit " PRINT "ScratchPad: ";getScratchpad$(PinNbr) PRINT "Shifted : ";bitshift$(getScratchpad$(PinNbr)) NEXT n END FUNCTION bitshift$(bits$) LOCAL INTEGER n bits$= bt$+bits$ bits$ = LEFT$(bits$,64) FOR n = 0 TO 7 bitshift$ = bitshift$ +HEX$(VAL("&h"+MID$(bits$,n*3+1,2))/2,2)+" " NEXT n END FUNCTION FUNCTION getRomCode$(PinNbr AS INTEGER) ' get ROM Code - useful if you want more than 1 device on wire LOCAL INTEGER a1,a2,a3,a4,a5,a6,a7,a8 ONEWIRE WRITE PinNbr,1,1,&h33 'read ROM code ONEWIRE READ PinNbr,2,8,a1,a2,a3,a4,a5,a6,a7,a8 getRomCode$ = HEX$(a1,2)+" "+HEX$(a2,2)+" "+HEX$(a3,2)+" "+HEX$(a4,2)+" "+HEX$(a5,2)+" "+HEX$(a6,2)+" "+HEX$(a7,2)+" "+HEX$(a8,2) END FUNCTION FUNCTION getScratchpad$(PinNbr AS INTEGER, style AS INTEGER) LOCAL INTEGER a1,a2,a3,a4,a5,a6,a7,a8,a9 ONEWIRE WRITE PinNbr,1,2,&hcc,&hbe ONEWIRE READ PinNbr,2,9,a1,a2,a3,a4,a5,a6,a7,a8,a9 getScratchpad$ = HEX$(a1,2)+" "+HEX$(a2,2)+" "+HEX$(a3,2)+" "+HEX$(a4,2)+" "+HEX$(a5,2)+" "+HEX$(a6,2)+" "+HEX$(a7,2)+" "+HEX$(a8,2) END FUNCTION FUNCTION powerMode(PinNbr AS INTEGER) AS INTEGER ' check whether power external (1) or parasitic (0) ONEWIRE RESET PinNbr ONEWIRE WRITE PinNbr, 1,2,&hcc, &hb4 ONEWIRE READ PinNbr,4,1,powerMode END FUNCTION FUNCTION getFamily(PinNbr AS INTEGER) AS INTEGER getFamily = VAL("&h"+LEFT$(getRomCode$(PinNbr),2)) END FUNCTION FUNCTION FamilyName$(PinNbr AS INTEGER) LOCAL INTEGER fn fn = getFamily(PinNbr) AND &h7F SELECT CASE fn CASE 16 FamilyName$ = "DS1820/DS18S20" CASE 34 FamilyName$ = "DS18S22" CASE 40 FamilyName$ = "DS18B20" CASE 32 ' 16 * 2 FamilyName$ = "*** DS1820/DS18S20" CASE 68 ' 34 * 2 FamilyName$ = "*** DS18S22" CASE 80, 81 ' 40 * 2 FamilyName$ = "*** DS18B20" CASE ELSE FamilyName$ = "Unknown" END SELECT END FUNCTION FUNCTION setResolution(PinNbr AS INTEGER,r AS INTEGER) IF r < 0 THEN r = 0 IF r > 3 THEN r = 3 ONEWIRE WRITE PinNbr, 1,5,&hcc, &h4E, &h00,&h00,r*32 END FUNCTION FUNCTION getTemp(PinNbr AS INTEGER,prec AS INTEGER) AS FLOAT LOCAL INTEGER fn, t, a1,a2,a3,a4,a5,a6,a7,a8,a9 LOCAL FLOAT Value fn = getFamily(PinNbr) AND &h7F 'power = powerMode(PinNbr) power = 0 ' we have disabled the external/parasitic check and stick to parasitic timing t = setresolution(PinNbr,prec) 'read external when b goes high, for parasitic just wait IF power = 0 THEN ONEWIRE WRITE PinNbr, 9, 2, &hcc, &h44 ' start conversion PAUSE (100 << prec) ' pause time varies depending on resolution ELSE ONEWIRE WRITE PinNbr, 1, 2, &hcc, &h44 ' start conversion t = TIMER DO IF TIMER - t > 1000 THEN Value = 1000 EXIT DO ENDIF ONEWIRE READ PinNbr, 4 , 1 , b ' conversion done? LOOP UNTIL b = 1 ENDIF ONEWIRE WRITE PinNbr,1,2,&hcc,&hbe ONEWIRE READ PinNbr,2,9,a1,a2,a3,a4,a5,a6,a7,a8,a9 SELECT CASE fn CASE 16, 32'DS18S20 or DS1820 IF a2 AND &h80 THEN 'if MSB of a2=1 then negative 'Read 12bit resolution and adjust 'truncate 0.5deg value (or use integer division \) a1 = a1 AND &hFE a1=a1 / 2 'make whole degrees 'add compensation values read from scratchpad a1=a1*16 'make lsb 1/16 degree a1 = a1 -4 +(16 - a7) 'add 12 bit value 'take 2s complement a1 = (a1 XOR &hFF) + 1 Value = -a1/16 'make decimal value in degrees ELSE 'positive temp Value = a1 / 2 '9bit value 'Read 12bit resolution and adjust a1 = a1 AND &hFE 'truncate 0.5deg(or use integer division \) Value = a1/2- 0.25 + (16 - a7) /16 '12 bit value ENDIF CASE 34, 40, 68, 80 ' DS18S22 or DS18B20 IF (a2 AND &b1000) THEN 'negative temp 'make 2s complement (1s complement+1) a2 = (a2 XOR &hFF) a1 = (a1 XOR &hFF)+1 IF a1=1 THEN a2=a2+1 'add the carry if required Value = -((a2 AND &b111) * 256 + a1) / 16 ELSE 'positive temp Value = ((a2 AND &b111) * 256 + a1) / 16 ENDIF CASE ELSE 'Value = 1000 we have defeated the checks to see whats happening Value = ((a2 AND &b111) * 256 + a1) / 16 END SELECT 'ENDIF getTemp= Value END FUNCTION Jim VK7JH MMedit |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2414 |
Re timing inconsistency. Found something that may (or not) be relevant. While playing with Peters PicoMite CSub LOG to get data from a DHT11 sensor I found that the pulse widths were sometimes wrong. It turned out to be the rising edges (as recorded by LOG) were sometimes late by 5 to 15uS but the falling edges were always at the expected time. What I did not determine was the cause. DHT11? Pico hardware? CSub LOG? or MMBasic? Elsewhere mention has been made of the USB module needing to periodically use some processor time so there is another possibility (or not). In this case changing the program to just use the interval between falling edges enabled extraction of accurate data. Edit. Have changed the error times, failing memory, had them too long. Edited 2022-02-27 15:22 by phil99 |
||||
PeterB Guru ![]() Joined: 05/02/2015 Location: AustraliaPosts: 655 |
G'Day lizby et al I have read and re-read you Picomite serial client until my head hurts and now I need to ask some trivial questions so please don't be rude. Are you sending I2C data out through a PC USB port and receiving it through the USB port on the Pico? My fundamental problem is a total lack of understanding of the USB system. Can the Pico be replaced by an MX470? I really would like to control the world from a PC. ![]() Peter |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6218 |
COM1 receives the commands open "com1:115200, 256, SerInt, 4" As #1 ' interrupt triggered with 4 characters SUB serint does the work You use a USB to TTL adapter to connect to the PC and send the commands (and listen for results) You could do the same with any of the mites. pico is available and cheap. Jim VK7JH MMedit |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10062 |
Jim Please see if the attached makes any difference to ds18b20 PicoMite.zip Edited 2022-02-27 18:30 by matherp |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4851 |
@peter, Is there an example how to use Settick pause Settick resume I get error messages when I add the label, and also when I add label and timer number. Thanks Volhout PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10062 |
googling "settick pause" would have found the answer ![]() SetTick 1000,myint t=Timer Do SetTick pause,myint Pause 500 SetTick resume,myint Pause 1000 Loop Sub myint Print Timer-t t=Timer End Sub or SetTick 1000,myint,4 t=Timer Do SetTick pause,myint,4 Pause 500 SetTick resume,myint,4 Pause 1000 Loop Sub myint Print Timer-t t=Timer End Sub Edited 2022-02-27 20:56 by matherp |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4851 |
Yip, feel like an idiot. It needs a comma!! PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10062 |
PicoMite/PicoMiteVGA V5.07.04b5 https://geoffg.net/Downloads/picomite/PicoMite_Beta.zip Implements EXECUTE command as per CMM2 Fixes bug that caused tempr function to give pin reserved error under certain circumstances Changes to onewire timings to match CMM2 Enables pins that are not exposed on the Pico to be used for reserved functions (e.g.SYSTEM I2C) |
||||
PeterB Guru ![]() Joined: 05/02/2015 Location: AustraliaPosts: 655 |
Good morning Jim (and everybody else) Thanks for your help. My problem now is I2C is DATA & CLOCK while USB is D+ & D- so how does that work? Peter |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3309 |
The addition of the EXECUTE command makes a Picomite serial client almost trivial. All regular basic I/O-related commands can simply be sent over serial and EXECUTEd. The only commands which need special handling are those which return values: DIN, AIN, CIN, FIN, PIN, TEMPR. ' serialClient.bas acts on serial messages ' if first character is "!", text data is to be returned, CR terminate ' otherwise, single command is to be run with "EXECUTE" OPTION AUTORUN ON dim integer msg(3) dim string cmd pause 2000 print "Picomite SerialClient starting" SetPin 22,21,com1 ' setpin 21,uart0tx:SetPin 22,uart0rx open "com1:115200, 256, SerInt, 4" As #1 ' interrupt triggered with 4 characters DO ' the program loops forever WATCHDOG 2000 ' this will recover from errors LOOP SUB SerInt ' received a message msg(0)=asc(input$(1,#1)) if chr$(msg(0)) <> "!" then pause 30 ' allow all characters in command to arrive line input #1,cmd cmd=chr$(msg(0))+cmd ' input$(255, #1) print cmd EXECUTE cmd else ' function call will return data msg(0)=asc(input$(1,#1)): msg(1)=asc(input$(1,#1)): msg(2)=asc(input$(1,#1)) print msg(0);" ";msg(1);" ";msg(2);" " if msg(0) = 3 then ' the command must be 3 if msg(2) = 10 then ' DS18B20 ' s$ = mid$(str$(tempr(pin(msg(1)),3,3) + Space$(12),1,12) ' get the temperature s$ = str$(tempr(pin(msg(1))),3,3) ' get the input on the I/O pin print s$ else ' value of DIN, AIN, CIN, FIN, PIN pin ' s$ = mid$(str$(pin(msg(1))) + Space$(12),1,12) ' get the input on the I/O pin s$ = str$(pin(msg(1))) ' get the input on the I/O pin print "pin(";msg(1);"): "+s$ endif print #1,s$ ENDIF ENDIF do while loc(1)>0: cmd=input$(255,#1): loop ' flush the input buffer END SUB ' return from the interrupt ![]() This is run from MMB4W. Not implemented, but EXECUTE "GOSUB somewhere" would be very valuable. For the commands which return a value, 3-byte sequences (plus CR) are sent (following Geoff's I2C protocol), but using only the binary 3 value for the first byte to indicate that a return value is expected. The pin number in binary form is the second byte, and the third byte is "don't care" except that for the DS18B20 the value must be 10. These 3-byte function-type commands are preceded by "!"--anything that does not have this lead character is sent straight to EXECUTE. This simple program provides pretty good I/O for a PC running MMB4W or MMBasic DOS or a device running MMB4L. The code is easily expanded to provide more features as required. Picomite on FruitOfTheShed ~ Edited 2022-02-28 13:21 by lizby PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7499 |
It doesn't. They are two entirely different things. :) What lizby has done is modify the I2C code originally written by Geoff in the "Getting Started With the Micromite" manual. He's left the original code in but commented it out so that you can see what he's changed. I2C isn't actually used. For the communication link lizby has used a COM port instead. This is, of course, just serial digital on the PicoMite so you need to connect it to a PC using a USB/TTL(3.3v) converter. Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
PeterB Guru ![]() Joined: 05/02/2015 Location: AustraliaPosts: 655 |
Thanks Mick. It's amazing what difference a ' makes and I'm sorry I'm a bit slow but we might still get there. It's 22 degrees here and the last day of summer. ![]() But that's better than 8. Peter |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7499 |
22? Sheesh - that's tropical! 07:52AM here, thick cloud and raining miserably and 7C. Tough old blighters, us "oop north". ;) No prob. " ' " was never my favourite punctuation either. :) Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
PeterB Guru ![]() Joined: 05/02/2015 Location: AustraliaPosts: 655 |
It is tropical at the moment because it is raining. For the last week or so it has been 30 to 35 just about ideal to get Nancye out into the garden and talk about the butterflies and plants and butterflies and ................ Life is good Peter |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10062 |
See the EVAL function. That has always been there. |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3309 |
Thanks, I'll look into it. I realized that it's easy enough to look at the incoming serial text for "pin(" or "tempr(" and process as needed. This would eliminate the need for the byte-code routine. PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
Bleep Guru ![]() Joined: 09/01/2022 Location: United KingdomPosts: 578 |
Hi Peter, I've just loaded PicoMite/PicoMiteVGA V5.07.04b5 When I try to re-instate my options, the OPTION DISPLAY gives an error, has this changed? I've checked release notes and other threads. > option reset > OPTION DISPLAY 49, 100 Error : Invalid Option > OPTION DISPLAY 49 Error : Invalid Option > I've just tried some other options and they are all giving an error, I've tried clearing flash and re-installing, still the same. Thanks, Kevin. Edited 2022-02-28 23:01 by Bleep |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10062 |
You don't say which and what else is set. OPTION DISPLAY can't be used on the VGA version and can't be used on the normal version if OPTION LCDPANEL CONSOLE is set. In those cases the combination of screen size and font determine the screen width and height in characters |
||||
Bleep Guru ![]() Joined: 09/01/2022 Location: United KingdomPosts: 578 |
Hi Peter, Yes you're quite right, I was using the VGA version, for which the options I was using were not valid! Thanks, Kevin. |
||||
![]() ![]() ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |