Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Micromite variables
Author | Message | ||||
helltek Newbie Joined: 04/02/2015 Location: United StatesPosts: 29 |
I'm looking for help. I try to write search routine to find Maxim/Dallas 1-wire devices. When I try to assign Family code, or the Serial number to variable Family(device), it doesn't work. When I try to read Family(1), Family(2), Family(3) I get the last Family code assigned to all of them. Basically Family(device) is not getting it. How do you populate variable x(i) ??? |
||||
Greg Fordyce Senior Member Joined: 16/09/2011 Location: United KingdomPosts: 153 |
Can you post your code? |
||||
helltek Newbie Joined: 04/02/2015 Location: United StatesPosts: 29 |
'==================== 'SUBROUTINES '==================== '-------------------- 'One Wire Search '-------------------- 'Search the 1-wire bus and discover attached devices one_wire_search: devices = 0 discover_device: discrepancy = 0 last_bit=0 Family(devices)=0 Family_nbr=0 SerNo_nbr=0 CRC_nbr=0 ROMcode_nbr=0 ONEWIRE RESET (one_wire_pin) if MM.ONEWIRE = 0 then goto one_wire_error1 'MM.ONEWIRE returns 0 if no presence pulse ONEWIRE WRITE (15), 0, 1, &hF0 'pin, flag, length, data [, data…] (F0h = Search) count64bits: for i = 1 to 64 ONEWIRE READ (15), 4, 1, a 'read 1 bit of 1-wire devices ONEWIRE READ (15), 4, 1, b 'read complement of 1 bit If a + b = 2 then goto one_wire_error2 'no devices responded if a + b = 0 and last_discrepancy=i then a=1 if a + b = 0 and last_discrepancy>i then a=last_bit if a + b = 0 and last_discrepancy<i then a=0 if a + b = 0 then last_discrepancy = i: discrepancy = discrepancy + 1: last_bit=a ONEWIRE WRITE (15), 4, 1, a 'write bit to continue search print bin$(a,1); if i>0 and i<9 then Family_nbr=Family_nbr+(a<<i-1): Family(devices+1)=Family_nbr if i>8 and i<57 then SerNo_nbr=SerNo_nbr+(a<<(i-9)): SerNo(devices+1)=SerNo_nbr if i>56 and i<65 then CRC_nbr=CRC_nbr+(a<<(i-57)): CRC(devices+1)=CRC_nbr ROMcode_nbr=ROMcode_nbr+(a<<i-1): ROMcode(devices+1)=ROMcode_nbr next i devices = devices + 1 print "last_discrepancy =" last_discrepancy print "discrepancy =" discrepancy print "last_bit =" last_bit print "devices =" devices print "Family"(devices)" = " hex$(Family(devices), 2)"h" print "SerNo"(devices)" = " hex$(SerNo(devices), 12)"h" print "CRC"(devices)" = " hex$(CRC(devices), 2)"h" print "ROMcode"(devices)" = "hex$(ROMcode(devices), 8)"h" print "Device CRC:" 'check crc c1=0 'clear crc "c1" prior sending first byte b1=ROMcode(devices) 'byte or bytes to calculate crc on n=8 'the number of bytes sent (since leading zeros are not in the integer) gosub crc_8 if c1<>0 then i=devices: gosub one_wire_error3 print "-------------------" if discrepancy <> 0 then goto discover_device 'search for more devices one_wire_search_end: error=0 RETURN one_wire_error1: error=1 print: print "Error1 MM.ONEWIRE = 0, Devices not found": print devices = 0 RETURN one_wire_error2: error=2 print: print "Error2 True bit + Complement bit in search" i " do not match": print RETURN one_wire_error3: error=3 print: print "Error3 CRC(device"(i)") does not match": print RETURN |
||||
Chris Roper Senior Member Joined: 19/05/2015 Location: South AfricaPosts: 280 |
I suspect you need to tell it how many entries in the array: #define MaxDevices 10 Dim Family(MaxDevices) ... Cheers Chris http://caroper.blogspot.com/ |
||||
helltek Newbie Joined: 04/02/2015 Location: United StatesPosts: 29 |
I played with the DIM but I'm not getting anywhere. It either doesn't work (assignes the last Family code read to all variables, or I get all kinds of error messages: Variable out of bounds, Variable not declared, etc. There has to be a way to use variable x(i) in Basic. It worked in GWBasic 25 years ago. |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5907 |
maxdevices = 10 DIM Family(maxdevices) FOR device = 1 TO maxdevices Family(device)=device*10 NEXT device FOR device = 1 TO maxdevices PRINT Family(device) NEXT device The code you supplied doesn't DIM the array so we can only guess where your problem is. With MMBasic, you have the choice of starting arrays at zero or one. See OPTION BASE Jim VK7JH MMedit  MMBasic Help |
||||
helltek Newbie Joined: 04/02/2015 Location: United StatesPosts: 29 |
This is the actual search routine: count64bits: for i = 1 to 64 ONEWIRE READ (15), 4, 1, a 'read 1 bit of 1-wire devices ONEWIRE READ (15), 4, 1, b 'read complement of 1 bit If a + b = 2 then goto one_wire_error2 'no devices responded if a + b = 0 and last_discrepancy=i then a=1 if a + b = 0 and last_discrepancy>i then a=last_bit if a + b = 0 and last_discrepancy<i then a=0 if a + b = 0 then last_discrepancy = i: discrepancy = discrepancy + 1: last_bit=a ONEWIRE WRITE (15), 4, 1, a 'write bit to continue search print bin$(a,1); if i>0 and i<9 then Family_nbr=Family_nbr+(a<<i-1): Family(devices+1)=Family_nbr if i>8 and i<57 then SerNo_nbr=SerNo_nbr+(a<<(i-9)): SerNo(devices+1)=SerNo_nbr if i>56 and i<65 then CRC_nbr=CRC_nbr+(a<<(i-57)): CRC(devices+1)=CRC_nbr ROMcode_nbr=ROMcode_nbr+(a<<i-1): ROMcode(devices+1)=ROMcode_nbr next i devices = devices + 1 ------------------------------------------------------------------- In Maxim/Dallas 1-wire datasheet it is READ 2 bits, WRITE 1 bit, do it 64 times for each device, so the loop for i = 1 to 64 discovers one device. The full 64 bit device number is te ROMcode_nbr, Family code is separated into the first 8 bits Family_nbr, 48 bit serial number is in SerNo_nbr and the CRC byte is in CRC_nbr. That's one device. Now I need to save it in: ROMcode(devices) Family(devices) SerNo(devices) CRC(devices) That's the part that doesn't work. I'm unable to assign the Family(devices)=Family_nbr as you see it in the code. I never had to use DIM in GWBasic, so I don't know how to do it. In GWBasic x(i) was accepted variable. Here in MMBasic it doesn't work. Even if I try the code snippets you provide, I get errors. Variable out of bounds, etc. |
||||
helltek Newbie Joined: 04/02/2015 Location: United StatesPosts: 29 |
Just a note: I used GWBasic, 8051 Basic, BasicMicro Basic, and variable x(i) worked in all of them. I didn't try Parallax BasicStamp, but I can hook one up and test it. I think this is a bug in the Micromite and I hope someone found an easy way around, since there is no storage area where I can save discovered devices. Only the variable "devices" will tell me how many devices are on the 1-wire bus when the search routine ends. |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5907 |
You appear to have 4 arrays Family() SerNo() CRC() ROMcode() (Unless they are referring to user defined functions) For each array, you need to declare how big they are. You use DIM for this. DIM Family(25) etc. This will allow for up to 25 elements in the array. Some versions of basic will automatically create arrays but the size is usually limited to 10 or 11 elements so you will still need to DIM larger arrays. If you are uncertain about the number of devices, just make the array bigger. Extra elements are not usually a problem. I don't have any one wire devices here so I couldn't run your full code but seeing it might help. The code sample I posted does run on V4.5 and V4.7 LIST ALL
maxdevices = 10 Dim Family(maxdevices) For device = 1 To maxdevices Family(device)=device*10 Next device For device = 1 To maxdevices Print Family(device) Next device > run 10 20 30 40 50 60 70 80 90 100 > If I change the loop to read For device = 1 To maxdevices+1 We get an error [5] Family(device)=device*10 Error: Array index out of bounds If you are getting errors "Variable not declared", I assume that you have OPTION EXPLICIT set, but I am only guessing. Jim VK7JH MMedit  MMBasic Help |
||||
helltek Newbie Joined: 04/02/2015 Location: United StatesPosts: 29 |
I'm really dumb when it comes to understanding code, DIMs, arrays, etc. I can not imagine it in real life, so I have no clue how they are arranged and what they can hold or represent. For example I have no idea why your example says "device*10". What is it multiplying? The way the example is, I need to somehow place it around my "for i = 1 to 64" loop because the 64 bits are just one 1-wire device. The number of "devices" are the next devices hooked up to the 1-wire bus. The search routine has to do this 64 bit loops until there is no discrepancy (multiple devices) on the 1-wire bus. Each loop increments the number of discovered "devices", so there would be Family(devices) or in simple example x(i) Family(1), Family(2), Family(3) where the number is a device and the Family is the Family Code of the device let say 28h for DS18B20 thermometer. Then there is the 48 bit Serial number SerNo(devices) and crc checksum byte CRC(devices). |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5907 |
That was just a way of getting a value to put in the array. It has no meaning other than something to show that the array was filled. Jim VK7JH MMedit  MMBasic Help |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9066 |
maxdevices = 10, so the FOR/NEXT loop that starts with 'FOR device=1 to maxdevices' is calculating the values for the array elements and is saving them there. So, with device=1 at the start of the loop, the line 'Family(device)=device*10' calculates the value for the element in the Family array at position 'device'. The first time through the loop, 'device' is 1, so: Family(1)=1*10 - this is because device is currently 1, and the value of Family(1) will now be 10. Next time through the loop, device=2, so: Family(2)=2*10 - Family(2) will equal 20. Third time: Family(3)=3*10 - Family(3) will equal 30. ...and so on, till it gets to 10, and therefore Family(10) will equal 100. The 'Print Family(device)' loop just reads back that data, and prints it. EDIT: Jim beat me to it!!! Smoke makes things work. When the smoke gets out, it stops! |
||||
MicroBlocks Guru Joined: 12/05/2012 Location: ThailandPosts: 2209 |
Easiest to imagine an Array is to think of a cabinet with drawers. The bottom one is drawer number 0. Arrays can have dimensions. Lets stay with one dimension for now. If you define a one dimensional Array with DIM myArray(10) then it will have 11 !! 'drawers'. Remember computers start counting with 0. 10 is the highest number or 'Upper bound'. If you don't use a DIM to define an array and you want to write something in it then it is the same as asking someone to put a book in drawer 4. If there is no cabinet with drawers this is impossible. Same here. You ask the program to store a value (book) in a drawer(array element) that is non existent. This is what causes the error 'Variable not declared' Now imagine you have a cabinet with 5 drawers and you ask someone to put a book in drawer 6. This is also impossible. The is the cause of error 'Variable out of bounds' What is important when working with arrays is to make sure they exist and before storing values in it make sure the 'drawer' exists. It is always best to define the variables you use, this can catch errors. Include the command OPTION EXPLICIT as the first line of your code. Creating: [code] CONST ARRAYSIZE 10 DIM myArray(ARRAYSIZE) DIM ArrayIndex = 0 [/code] Checking: [code] if ArrayIndex <= ARRAYSIZE then myArray(ArrayIndex)="Whatever value" [/code] used in loops [code] for ArrayIndex = 0 to ARRAYSIZE myArray(ArrayIndex) = 'Some value' next [/code] [code] ArrayIndex = 0 DO UNTIL ArrayIndex > ARRAYSIZE 'Do some searching/calculations/etc myArray(ArrayIndex) = "A result" ArrayIndex = ArrayIndex +1 LOOP [/code] Hope this helps. Microblocks. Build with logic. |
||||
helltek Newbie Joined: 04/02/2015 Location: United StatesPosts: 29 |
I tried whatever I could think of, but no luck. For example this code does what happens. maxdevices = 10 Dim Family(maxdevices) Dim ROMcode%(maxdevices) Dim SerNo%(maxdevices) Dim CRC(maxdevices) for devices = 1 to maxdevices if devices <= maxdevices then Family(devices)=1 if devices <= maxdevices then Family(devices)=2 next devices print Family(1) print Family(2) print Family(3) There is no way to asign value (the 1-wire device code) in this loop since the last device is what's printed. There is no Family(1), Family(2), etc. They're all same. I have no idea why simple x(i) variable can't be created. |
||||
Chris Roper Senior Member Joined: 19/05/2015 Location: South AfricaPosts: 280 |
That is because you are assigning the value 2 to every element of the array. [code] for devices = 1 to maxdevices if devices <= maxdevices then Family(devices)=1 ' assigns a value of 1 if devices <= maxdevices then Family(devices)=2 ' overwrite with a value of 2 next devices ' increment to next array element and repeat print Family(1) ' prints 2 print Family(2) ' prints 2 print Family(3) ' prints 2 [/code] I have added comments to try and show what your code is doing Cheers Chris http://caroper.blogspot.com/ |
||||
Greg Fordyce Senior Member Joined: 16/09/2011 Location: United KingdomPosts: 153 |
Quick question, your comments say 'read 1 bit' but the ONEWIRE READ reads bytes not bits, possibly some of the problem? Try a simple program or even use the command prompt to try the commands and see what the response is from the devices. For example ONEWIRE READ (15), 4, 1, a PRINT a and see what response you are getting. It may be that the devices aren't responding as you expect them to and this is causing some of your problems. One of the nice features of MMBASIC is being able to try things at the command prompt. |
||||
helltek Newbie Joined: 04/02/2015 Location: United StatesPosts: 29 |
The option 4 after pin number in ONEWIRE READ (or WRITE) reads only 1 bit. My routine reads the correct bits because I can read temperature and read pullup or pulldown of 2413 switch. I think, I have the DIMs now done correctly, following your examples, but I discovered problem with my search. When I hook up multiple devices, the search is reading them over and over until it hits maxdevices and stops with error. I need to figure out how to sort out which devices are already discovered and when there are no more devices to look for (last device). I will try to make sense of the appnotes. They are not exactly clear to understand. Would be whole lot easier if there was 1-wire code for the Micromite to download and look up. |
||||
helltek Newbie Joined: 04/02/2015 Location: United StatesPosts: 29 |
Update. My 1-wire search routine seems to work. It has to be tested with various 1-wire device combinations to see if it chokes on some similar serial numbers, but right now I have only few different devices to test. |
||||
Chris Roper Senior Member Joined: 19/05/2015 Location: South AfricaPosts: 280 |
That's Great news helltek. Well done. It is a good feeling when your persistence pays off and you get it working. After working through a few more problems like that one you will know MMBasic inside out Cheers Chris http://caroper.blogspot.com/ |
||||
helltek Newbie Joined: 04/02/2015 Location: United StatesPosts: 29 |
Thanks to you guys. I couldn't figure it myself. I still don't know how the program works. I have DIM with different names than the variables and no idea why it is that way, but it works and that's the end result I need. Long time ago (in DOS days) I used Basic, Batch functions and Assembly. I never needed DIMs and I think the assembly language was the most logical, but when I look at Microchip assembly it doesn't look that simple, so I love the Micromite. It doesn't require any external parts, it is inexpensive and works great. Can't ask for more. |
||||
Print this page |