Shop OBEX P1 Docs P2 Docs Learn Events
would anybody share his SPIN-Code reading multiple DS1820 1-Wire-devices — Parallax Forums

would anybody share his SPIN-Code reading multiple DS1820 1-Wire-devices

StefanL38StefanL38 Posts: 2,292
edited 2015-02-28 14:26 in Propeller 1
Hi,

I want to realise a easy to configure temperature-data-logger for DS1820-temperature sensors.
DS1820-sensors have digital output based on the 1-Wire-protocol.

I'm crawling my way through the 1-wire-bus-protocol. I estimate I understand half of it.
FullDuplexSerial is an object you can just use without understanding the details of the bitbanging.

I would like to do the same with 1-Wire. So I'm asking if somebody would share his ready-to-use 1-Wire-Code

The code should not only have a small demo of how to read ROM-IDs or read one temperature without checking the ROM-ID
That's what can be found in the OBEX and what I have already loaded and testet.

I don't wnat to RE-invent the wheel again. So I'm asking:

has somebody coded ready to use routines that do:

- scan the 1wire-bus for all devices connected, storing all the ROM-IDs of all found devices for later use in an variable-array

- methods that do all the details of how to read a temperature from a particular DS1820-device selected through its ROM-ID
(sending reset, sending ROM-ID, initiate temperature-conversion, wait for conversion to be finished, read temperature-value from scratch-pad,
,checkif CRC is OK)

- reading the 9bit temperature-value, reading the 12bit temperature value

- and maybe even methods that write data to the Th and Tl registers, read/write to EEPROM

If somebody can provide code like this I will extend comments in the code to make it easier to understand how it works
and will share my complete code which will add a configurable datalogger
first version sending data via serial interface push in regular time-intervals
or send data on request,
later version storing data on SD-card

best regards

Stefan
«1

Comments

  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-14 08:16
    I've been doing 1-Wire for a long time, an even got to work with engineers at Dallas Semiconductor when I lived in Dallas, so my 1W buss protocol is solid. I wrote about 1-Wire on the Propeller for Nuts & Volts magazine -- you may be able to find that article online somewhere.

    I freshened up an old demo (from 2009) with a method that shows you how to read a specific sensor on a multi-sensor buss. I've used this code in the past, but couldn't test it today because I do not have sensors. It might need a little tweaking.

    If somebody can provide code like this I will extend comments in the code to make it easier to understand how it works


    If you modify my 1W object, take my name off of it before posting. I'm willing to support my own code and comments, but not yours. :)
  • StefanL38StefanL38 Posts: 2,292
    edited 2015-02-14 21:29
    Hi Jon,

    thank you very much for your code.

    I analysed it. I understand most of it.
    But there are still some questions left:

    How do I code scanning the 1Wire-Bus for ALL devices that are connected to the bus?
    As soon as two 1Wire-devices are connected to the bus your code responses with "bad CRC"

    best regards

    Stefan
  • MoskogMoskog Posts: 554
    edited 2015-02-15 01:28
    Here is a code I am using for Reading two Devices of DS1820, using "SpinOneWire.spin" (ow) by Micah Dowty. The two sensors are recognized in the case adr sentence ( $E3 and $32). The result is placed in MainBuffer at different locations ready With sign (+ or -) for output on debug screen.

    SpinOneWire.spin
    PUB ReadTemperature | i, numDevices, addr
    
           
      ow.start(OneW)
      'debug.position(0,0)                                          ' home
      repeat
        numDevices := ow.search(ow#REQUIRE_CRC, MAX_DEVICES, @addrs)
    
        'debug.str(string($01, "── SpinOneWire Test ──", 13, 13, "Devices:"))
    
        repeat i from 0 to MAX_DEVICES-1
          'debug.NewLine
        
          if i => numDevices
            ' No device: Blank line
            'repeat 39
              'debug.str(string(" "))
          else
            addr := @addrs + (i << 3)
            adr:= (LONG[addr + 4])>> 24      ' Display the first 2 bytes of device address
            case adr
              $E3: Device := 0
              $32: Device := 1 
              {
            debug.hex(adr,2)
            debug.str(string("  ")) }
    
            if BYTE[addr] == ow#FAMILY_DS18B20
              ' It's a DS18B20 temperature sensor. Read it.
              readTemp(addr)
    
            else
              ' Nothing else to show...
    
        
    PRI readTemp(addr) | temp1, temp2, tc1, Tsign, TInt, TFrc
      '' Read the temperature from a DS18B20 sensor, and display it.
      '' Blocks while the conversion is taking place.
    
      ow.reset
      ow.writeByte(ow#MATCH_ROM)
      ow.writeAddress(addr)
    
      ow.writeByte(ow#CONVERT_T)
    
      ' Wait for the conversion
      repeat
        waitcnt(clkfreq/100 + cnt)
    
        if ow.readBits(1)                                   ' Have a reading! Read it from the scratchpad.
          TSign := 0 
          ow.reset
          ow.writeByte(ow#MATCH_ROM)
          ow.writeAddress(addr)
          ow.writeByte(ow#READ_SCRATCHPAD)
          temp1 := ow.readBits(16)       
          temp2 := ~~temp1 * 625                             ' extend sign, 0.0001° units
          if (temp2 < 0)                                                 ' if negative              
            'debug.str(string("-"))
            TSign := 1                                                ' print sign               
            ||temp2      
          temp2:= (temp2 / 100)+5
          tc1:=((temp2 / 10))
          TInt:=(tc1/10)
          TFrc:=(tc1 // 10) {
          debug.dec(TInt)
          debug.str(string("."))
          debug.dec(TFrc)
          debug.str(string("°C   "))  }
          Case Device
            0: MainBuffer[22] := TSign                 ' Outside environment
               MainBuffer[14] := TInt
               MainBuffer[15] := TFrc
            1: MainBuffer[21] := TSign                 ' Inside environment
               MainBuffer[12] := TInt                  ' 
               MainBuffer[13] := TFrc
    
            
          Return
    
    
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-15 07:58
    How do I code scanning the 1Wire-Bus for ALL devices that are connected to the bus?

    That is a fairly complicated process that I actually did once with a BS2p, but haven't with a Propeller. If you're producing a commercial product for others, you get the joy of reading the Dallas/Maxim spec for 1-Wire buss searching and implementing it in Spin. Again, I did it in PBASIC, so it's completely possible.

    As soon as two 1Wire-devices are connected to the bus your code responses with "bad CRC"

    Any code that uses SKIP_ROM is not intended for multiple devices. Included in the code is a method called read_tca() which allows you to address a specific device. You need to use that.

    I thought you wanted to understand the details of bit-banging 1-Wire. Well, my object shows you how with very plain code. It's up to you to do the rest for your project. If this is a personal (not commercial) project, you can insert one sensor at a time to read the serail #. One you have all the serial #s for your devices, you can create a program that round-robin scans them.
  • StefanL38StefanL38 Posts: 2,292
    edited 2015-02-15 09:15
    Hi Jon,

    well my initial question was if somebody has finished and working well code that scans the whole bus and reads all the devices.
    Seems not to be so. I did another intensive search in the OBEX and found object #81 http://obex.parallax.com/object/81

    "1-wire device interface routines and demos. Low-level routines include network device search and CRC-8 calculation."
    There is a demo included that shows how to scan the bus. This means there is a function "scan the whole bus" available

    This object is from from Cam Thompson. Hi Cam! (winking my hands) thank you very much for your code.

    As nobody has posted code like described above my next step is to code it on my own
    how to store all the adresses found through bus-scan and
    finding out how to send the right bytesequence for reading a particular device.
    I guess Jon's code read_tca shows most of it. Still some work to be done.

    @Moskog: Thank you very much for sharing your code.
    Somehow I prefer to use PASM-routines for the bitbanging. Though for me it's harder to understand how PASM works than how spin works

    If I have coded everything I will share it here in the forum or the OBEX.

    In this forum all support is for free. So I'm far away from complaining about something.
    Anyway I would like to say that more comments in the code will make it much easier to understand.

    I want to give an example of what I mean:
      'the details of the bitbanging according to the 1Wire-protocol is done in the PASM-code below
    
      'par contains hub-addr of the variable used as second parameter of the cognew command cognew(@onewire, @_1Wire_Cmd)                                
      'in the spin-code there are four longs named "_1Wire_Cmd", "_1Wire_Data", "_1Wire_DQ_Pin", "ticks_per_microsecond"
      'these variables are used to communicate between PASM-cog and SPIN-code. Therefore the HUB-RAM-adresses of these longs
      'are stored in the PASM-code 
                                     
                            org     0
    onewire                 mov     r1, par                          ' store hub-addr of start of longs defined in SPIN in "r1"  
                            mov     cmdpntr, r1                      ' save hub-addr of global var "_1Wire_Cmd"
                            add     r1, #4                           ' add 4 to hub-addr to get hub-add of second long "_1Wire_Data"  
                            mov     iopntr, r1                       ' save hub-addr of io value
                            add     r1, #4                           ' add 4 to get hub-addr of long "_1Wire_DQ_Pin" 
                            rdlong  r2, r1                           ' read pin-number
                            mov     owmask, #1                       ' create pin mask
                            shl     owmask, r2                        
                            add     r1, #4                           ' add 4 to get hub-addr of fourth long "ticks_per_microsecond" 
                            rdlong  ustix, r1                        ' read ticks per microseconds
    
    'mainloop of PASM-code
    'if SPIN-variable _1Wire_Cmd is set to a value <> 0 the 1Wire.command will be executed
    'when execution has finished _1Wire_Cmd will be set to zero to signalise finishing to the SPIN-code
    'so the finish of the command can be detected in SPIN through a loop   repeat while _1Wire_Cmd
    'if PASM-code has finished SPIN-variable "_1Wire_Cmd" is set to zero and looping stops 
    

    This CODE is a part of Jon's 1-Wire-code. (Comments are NONSENSED by me (Stefan)

    Of course everybody is free to do as much or less comments as she/he wants
    because nobody gets any extra money and mostly no extra honour for extra commenting.
    But I want to give an impulse with asking: how about adding some extra comments making it easier to understand?

    best regards

    Stefan
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-15 09:58
    The "honour for extra commenting"? Please. Commenting that spells out the obvious is a waste of time, and proves nothing. Do you really think a professional programmer wants to spend the time documenting every MOV instruction? The manual spells out how that instruction works; comments like this:

    ' store hub-addr of start of longs defined in SPIN in "r1"

    ...are complete nonsense.

    But I want to give an impulse with asking: how about adding some extra comments making it easier to understand?

    How about cracking open the documentation -- like those of us who create objects do -- and studying it? Do you think I just woke up on morning and wrote that 1-Wire code? While I have done that with a couple short movie scripts, I've never done that with software. To me this "Hey, how about extra commenting?" thing says that people don't really want to understand, what they want is to be relieved of the burden of self-study. It's the Arduino syndrome: people that cobble together pre-written program fragments and want to declare themselves "programmers." This is why I stopped uploading my objects to ObEx -- and why I'm going to stop sharing my objects in the forums.
  • BeanBean Posts: 8,129
    edited 2015-02-15 10:26
    Jon,
    I agree with you. I can't count how many times I've seen this ADD value,#5 ' Add 5 to value
    It's like "No duh...Tell me something I didn't know."

    As for people just using libraries, I think that is fine for beginners, but the problem is that you have little knowledge of what is really going on. This is why people demand more and more memory and faster and faster processors so they can just lump in a bunch of libraries and make something happen.

    Oh, sometimes I long for the days of writing assembly language on my Timex Sinclair 1000, where every byte and every cycle counted. I worked for several months as a kid working on a space invader game. I learned so much about programming by making it fit in 2K and making it fast and responsive.

    Bean
  • StefanL38StefanL38 Posts: 2,292
    edited 2015-02-15 10:41
    Hi Jon,

    I'm sorry if my posting made you upset. (sounds like that). That was not my intention.
    I asked for opinions and you gave a clear answer. Thank you for that.

    Something beeing "obvoius" depends on the knowledge somebody already has.

    To me the differences of how much somebody knows or how much he should know is only gradually.
    Do I have to have designed the inner circuitry of a chip before I'm ready to use one?
    How much complexity must this self-designed chip have? Transistor?, OP-Amp? Propeller-Chip?
    Only If I have designed or studied the inner circuitry of the propeller-chip in deep details I will be able
    to forseeing the sensivity of the PLL-ciruictry that will make me taking precautions to avoid killing it.
    The other option is to kill it once or twice and learning it when nescessary. It's the same thing to me with software.
    If I don't understand how to use it I will code bugs and if bugs occure the bug will make it nescessary to go deeper inside.
    Do I really have to study this deep before I'm ready to use the propeller-chip?
    Do I have to have coded a compiler myself before I'm ready to use one?

    Now where is the PRINCIPAL difference between putting code-fragments together without understanding all details
    of what the code does and studying the inner circuitry of the propeller-chip?

    As my posting seems to have made you upset feel free to set me on the ignorelist if you want.
    If you would like to explain where you see the principal difference please explain.

    best regards

    Stefan

    P.S: In the meantime Bean chimed in.
    As for people just using libraries, I think that is fine for beginners, but the problem is that you have little knowledge of what is really going on. This is why people demand more and more memory and faster and faster processors so they can just lump in a bunch of libraries and make something happen.

    Oh, sometimes I long for the days of writing assembly language on my Timex Sinclair 1000, where every byte and every cycle counted. I worked for several months as a kid working on a space invader game. I learned so much about programming by making it fit in 2K and making it fast and responsive.

    So the only way to learn effective coding is to do everything from scratch? How about well commented code explaining how it can be done effective?
    The commenting would allow to understand it faster making it easier to chime in and tweak the existing library (to make it faster or more responsive or whatever)
  • BeanBean Posts: 8,129
    edited 2015-02-15 11:09
    Stefan,
    I said that using libraries is "fine for beginners". The problem is that when you must create something from scratch, the amount of work needed seems crazy. So people tend to only do things if a library exist for it. I don't want to speak for Jon, but I think his issue is "Live by the library, die by the library." or don't become dependent on libraries.

    And yes, by doing everything from scratch, you will learn much more than using a bunch of libraries.

    And don't waste your time writing comments that just echo WHAT the instruction is doing. Comments should explain WHY something is being done, not WHAT is being done. The "what" is obvious, the "why" is not.

    Bean
  • potatoheadpotatohead Posts: 10,261
    edited 2015-02-15 11:18
    The better form of comments is to give a running commentary of instruction purpose, not function.
                            org     0                                ' Setup pointers for HUB memory data exchange, COG to COG comms
    onewire                 mov     r1, par                          ' prepare r1 for use as pointer index into HUB address block 
                            mov     cmdpntr, r1                      ' par contains base of comms memory block, also cmdpntr HUB address pointer 
                            add     r1, #4                           ' advance r1 to next HUB long address
                            mov     iopntr, r1                       ' result is iopntr HUB address comms pointer
                            add     r1, #4                           ' next address is pointer to pin number read from HUB
                            rdlong  r2, r1                           ' fetch pin number
                            mov     owmask, #1                       ' prepare to develop pin mask
                            shl     owmask, r2                       ' owmask now contains developed pin mask from pin number in HUB 
                            add     r1, #4                           ' prepare to read ticks from next address 
                            rdlong  ustix, r1                        ' fetch ticks per microsecond from HUB
    

    People can see what the instructions literally do. Unless an odd use case, or trick is in use, it's better to comment their intent. People can always find the strict operation that happens. It's much harder to parse what that means in the context of the program overall.

    I haven't evaluated this code and just took a stab at what that instruction intent might be for this case. If it's off, that's why.

    Somewhere else, these pointer addresses should be listed as whether or not they are read, write, or both.

    User can then read this block of code, understand the flow of data and it's purpose. That's what they really need to proceed or modify or use this code block.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-15 11:25
    The commenting would allow to understand it faster making it easier to chime in and tweak the existing library (to make it faster or more responsive or whatever)

    Okay, this made me laugh -- you want me to write better comments so that you can understand my libraries to make them faster or more responsive? Thank you -- I needed a good laugh. That's not to say you aren't capable of improving my libraries, I just don't get the impression you're at that point yet when you're wrapped around the axle demanding comments for obvious code.

    I'm with Bean: live by the library, die by the library. If one has the ability to make a library "faster or more responsive" the amount of commenting doesn't really matter. Do I write everything from scratch? No, I use a couple off-the-shelf libraries, but the only one I have not modified is FSRW because I haven't taken the time to fully understand it. I modified FullDuplexSerial to my liking (flexible buffer size, and added some high-level methods). I obviously couldn't have modified Chip's PASM code if I hadn't taken the time to learn what the instructions do, and also have a grasp on the mechanics of serial communications.

    In my opinion, listings are not training material per se, they are supplements to training materials. Evey other month I write a column for Nuts & Volts magazine on Spin/PASM programming. Do you really think that I should spend time putting a 2500-word (typical article length) explanation into every library I write? If you do, I cannot help you because I refuse to spend my time stating the obvious.

    I've never put anyone on the ignore list, and I'm not going to start with you -- though I do ignore some people. This is a public forum, and when I choose to help, it is my hope that what I post helps many more than the person who started a particular thread.
  • StefanL38StefanL38 Posts: 2,292
    edited 2015-02-15 11:30
    Hi Bean,
    Hi potatohead,

    thank you for answering. Commenting the why and/or purpose makes sense to me.
    Bean I agree. Live by the library and die by the library. Or to become completely independent create you own hardware-chip from scratch.
    To me still just a gradual difference. Although I readily admit that there are many degrees from end to end.

    best regards

    Stefan
  • potatoheadpotatohead Posts: 10,261
    edited 2015-02-15 11:36
    If it were me understanding this library, or any for that matter, I would simply make new comments as part of that understanding as I did above. (which may be incorrect as this is just a discussion)

    Then, potentially share them, and or expand on it all for others. An example is in my signature for the colors in the Parallax reference graphics driver / demo.

    People are going to write the comments they write. I'll take 'em. If I end up writing new ones, share that, and everybody benefits.

    Maybe over time that activity results in improved comments.

    For me, this is my process on any new code:

    I'll first run it, check to see that it builds, whatever. If that's possible.

    If it's a snippet, I'll check it in it's original context, if that's possible.

    Then read it, parsing for intent as shown. When I can get to a running commentary as shown above, I'm probably well on my way to understanding that code well enough for it to be useful. And I probably learned something new in there too.

    Integrate with my work, comment, continue.

    Share, if appropriate.
  • potatoheadpotatohead Posts: 10,261
    edited 2015-02-15 12:08
    Re: learn this much?

    Yes. You never ever stop learning. Tech changes, code changes, and so forth.

    The most important skill is understanding how to better and more quickly arrive at an understanding for the task at hand.

    Each one commented, understood and use adds to skill, and you get quicker and better.
  • StefanL38StefanL38 Posts: 2,292
    edited 2015-02-15 12:12
    Hi potatohed,

    What you described is a good idea. Will try do so.

    best regards

    Stefan
  • potatoheadpotatohead Posts: 10,261
    edited 2015-02-15 14:13
    Hope you see results.

    I took a coupla minutes to think through what it could be doing, then started the commentary.

    The trick I like is to get it to flow in words nicely and with fewer words too. When you use a lot of words on a line, you've not yet boiled it down to something one PASM instruction can generally do. Use more lines, or fewer words! Both help sort out flow and data to make an effective program.

    That process seems to mirror how the program itself flows and I get it by inference and often deduction.

    When I have been away from it, like I am right now, doing this also helps to bring back that mental context needed to do this stuff. There seems to be a short term memory gap in play when task switching, or just ramping up to do something. This kind of review seems to populate that "cache" and it makes operating with the tools and the problem easier as there are much fewer "lookups" to perform. In computer terms, swap out the garbage, swap in the library code... :)

    While it may seem time consuming, the improved flow I get tends to make or help me program better, which generally saves a lot of other little bits of time, moat notably the time spent flipping between references, etc... Looking up an instruction, then writing it, then thinking about the next step, then trying to visualize it, then looking up another one sucks... Takes all day.

    Reviewing code you wrote last, or library code, or a snippet, seems to fill in the instructions and a lot of details. That's faster right there. Building up a running list of small, instruction sized tasks in plain language seems to fill in a lot of the intent and steps. Populating easy ones speeds it all up and improves too:

    And that is generally pseudocode.

    Write what needs to happen, then write it again using simpler and still connected ideas.

    Soon, the pseudocode and whatever diagrams and notes that result look a whole lot like the kind of useful comments we've got in the discussion here.

    Then, just write a PASM instruction or two for each line.

    I may spend more time resolving the problem this way than I do writing PASM instructions, but those also seem much closer to doing what I want too, which helps with debug and generally just putting the appropriate instructions in the right order types of tasks...

    I will also just start filling in instructions, once the plain language gets simple enough. Populate simple mov, rdbyte, jmp, etc... and slowly it will come together, making the real hard ones that do the meaningful work more obvious.

    This is like a puzzle, where it's hard at first, but as more and more of the pieces are connected and the picture intent is known, fitting the harder ones takes less effort because the obvious problem space associated with them is smaller, allowing for one to consider far fewer opportunities while also making them better, easier to see or guess ones.

    For a video example, maybe it goes like this:

    Display text screen:
    Characters are 1x8 bytes
    There is a font in HUB RAM
    Display all characters on a line
    Display them from upper left to lower right
    Display all of them
    Do it every frame.

    Now, break it down.

    For each scan line: (for example)

    1. Read the character value from the HUB to know which one to display.
    2. Note the scan line and use that as a hint as to which byte in the character needs to be displayed.
    3. Fetch that byte from the HUB
    4. Put it into the waitvid.
    5. Do all the chars for that line.
    6. Do all the lines for the screen.
    7. Reset it all and do it again for each frame.

    And further:

    need to know scan_line, font_start_address, video_buffer_address, num_of_waitvids, line_offset, etc...

    Beginning of line
    1. Prepare to read character number from hub
    2. prepare pointer to font in hub memory
    3. read character from hub
    4. calculate font address based on character number
    5. add scan line offset
    6. get byte from the right character
    7. stuff it into the waitvid
    8. done, next character!
    9. done, next line!
    10. done, next frame!

    And further might be something like:
    rdbyte  screen_character, index     'read character from hub
    ???	                            'prepare to calculate font address, pixel address
    rdbyte  pixels, index               'get the pixels
    waitvid pixels, colors              'stuff them into waitvid
    cmp ???                             'are we done with the line?
    jmp	                            'no?  get more characters and do more waitvids 
    ???	                            'yes!  Reset the line pointers and advance to next scanline...
    


    etc....

    Soon, it's just filling in the blanks, and it goes fairly well.

    This may work well if you do well with words. Maybe not so well, if not. And in that case, pictures, or whatever works might make more sense.

    In any case, that's my general process, be it my own code, library, or something I'm doing PASM on. Or anything really. If it's a new language, then I do this A LOT. Until I find I can write simple things without doing it.

    If it's code somebody else wrote, the instruction blanks are filled, but you need the intent blanks filled in! That's what the running commentary process accomplishes.

    If it's code you are writing, you need to figure out what to write, which is the intent blanks. Once that's done, you work down to fill instruction blanks in.

    If it's code you are combining, however it goes, then you need to know the intent, and map out the data flows and write the words that get the data where it needs to go and do what it needs to do.

    If it's math, solve it however you can solve it and make a few test cases so you can check what the P1 is going to do.

    Then use factoring, algebra and whatever other math options you can find to use P1 operations, but simpler ones. Make sure the tests pass. You may want a subroutine, like for divide.

    Get down to add, shift (multiply by power of 2), subtract, and so forth. Make sure the tests pass.

    Say you've gotta plot a dot, or calculate an address.

    In the case of the dot, the address of the byte where the dot lives is a nice calculation to work with. Say the screen is one byte per pixel, and it's a 160x96 screen.

    Given X and Y, the dot address is = (y*160)+x

    A multiply by 2 and add is what we got. So use closest power of 2 and add more

    dot address = (y*128)+(y*32)+x

    Our checks need to be to make sure X and Y do not exceed their values.

    y 0 - 95 and x 0 - 159

    Some tests:

    x 0 y 0 = 0 = beginning of screen
    x 50 y 40 = (6400)+(50) = 6450
    x 159 y 95 = (15200)+159 = 15350 = end of screen.

    Edit: should add edge cases:

    x159 y 0
    x 0 y 95
    etc...


    words might be:
    skip range checks (because this is just example)
    prepare to compute dot or pixel address
    first do y
    add x to get dot address
    call the pixel plotter to see it on screen

    code might be:
            mov     address, #0                'prepare to compute pixel address
            mov     address, pixel_y           'address = (y*160)+X
            shl     address, #7                'compute (y*128)
            shl     pixel_y, #5                'compute (y*32)
            add     pixel_y, address              '(y*128)+(y*32) = (y*160)
            add     address, pixel_x           'pixel address done!
            call    #plot                      'draw it to screen
    

    I had a bug in the above, because I wrote "add address, pixel_y" and when I reread my comments, saw it. The other one was I added "temp" which should have been "address", both corrected in the above. That's nice when it happens.

    And there is at least one simplification there too. Really don't need to zero out the address variable as it's going to get written over to do the two part Y address calculation. So that can go.

    Result is a nice code snippet that's very likely to do what it is supposed to. Then code it, or insert it and carry on, no different from the library example above.

    I just did these on the fly, no Prop Tool, IDE, etc... But now, I'm ready to fire up a board and do some stuff! Most of that mental context is back.

    (Goes off to play on P1 for a while now)
  • MJBMJB Posts: 1,235
    edited 2015-02-15 15:34
    StefanL38 wrote: »
    well my initial question was if somebody has finished and working well code that scans the whole bus and reads all the devices.
    Seems not to be so.
    Peter's Tachyon based Propeller Hardware Explorer with my 1-Wire extention does this automatically on all Prop pins with a pullup.
    I can not attach the propeller image here,
    so sent it to you in private.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-02-15 17:37
    JonnyMac wrote: »
    Okay, this made me laugh -- you want me to write better comments so that you can understand my libraries to make them faster or more responsive? Thank you -- I needed a good laugh. That's not to say you aren't capable of improving my libraries, I just don't get the impression you're at that point yet when you're wrapped around the axle demanding comments for obvious code.

    I'm with Bean: live by the library, die by the library. If one has the ability to make a library "faster or more responsive" the amount of commenting doesn't really matter. Do I write everything from scratch? No, I use a couple off-the-shelf libraries, but the only one I have not modified is FSRW because I haven't taken the time to fully understand it. I modified FullDuplexSerial to my liking (flexible buffer size, and added some high-level methods). I obviously couldn't have modified Chip's PASM code if I hadn't taken the time to learn what the instructions do, and also have a grasp on the mechanics of serial communications.

    In my opinion, listings are not training material per se, they are supplements to training materials. Evey other month I write a column for Nuts & Volts magazine on Spin/PASM programming. Do you really think that I should spend time putting a 2500-word (typical article length) explanation into every library I write? If you do, I cannot help you because I refuse to spend my time stating the obvious.

    I've never put anyone on the ignore list, and I'm not going to start with you -- though I do ignore some people. This is a public forum, and when I choose to help, it is my hope that what I post helps many more than the person who started a particular thread.

    Admit that you are a failure Jon! :) and look! IF ONLY you commented it properly then others could make it FASTER AND MORE RESPONSIVE !!!!! Yes, I think I will have a good laugh with you too.

    Anyone who needs verbose commenting is not normally in a position to really even just understand the code, maybe they might understand the comments, but you need to understand why the code is written the way it is to achieve it's grand purpose in order to "tweak" it. If you have this level of understanding it is extremely unlikely that you even need someone else's code let alone comments, especially verbose comments in the first place.

    @Stephan, btw I have to say that reading these sensors, accepting serial commands, and logging onto an SD card is a snap in Tachyon. But there would be no real challenge if you did it that way as everything is too easy and MJB has the 1-wire search code too.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-15 18:16
    well my initial question was if somebody has finished and working well code that scans the whole bus and reads all the devices.

    My mistake (along with my apparently-crappy commenting style). I use "scanning" to mean reading known devices. One "searches" the 1-Wire buss for unknown devices, catalogs them, then scans later.
  • KyeKye Posts: 2,200
    edited 2015-02-15 19:52
    @StefanL38

    About code comments:

    I've found that unless you understand what the code is for then no amount of comments will help you understand it. Similarly, I've found that if you know what the code is for then comments aren't so necessary.

    However, it helps to add comments when you do something not so straight forward. These types of comments are very helpful months down the road.

    Also, good variable and function names go a long way too.

    I recommend reading the 1-Wire spec.
  • potatoheadpotatohead Posts: 10,261
    edited 2015-02-15 21:49
    @Jonny Mac: Your style isn't crappy.

    And hey, comments are comments! I'll take 'em. Almost always better than no comments at all. Same with code. I'll take it. Almost always a good thing too.

    @Kye: Deffo. When it's a non-standard, or trick use, those comments are gold. Give that code a year, and most people who wrote it and didn't comment, will look at it and have to figure out the trick again...

    And this:
    Also, good variable and function names go a long way too.

    Yes! I'm so guilty of using a few letters, older school register style. A,X,Y, and so forth. When I go back to that code, the comments are probably what makes it somewhat easy. Where I didn't do that, it sucks. Gotta parse it again.

    But, I hate the typing... Ah well.

    @StephenL38: You should reconsider tossing ignore out there so quick. :) A little bit of charm, or humility, or just "thanks man, nice catch!" kind of thing goes a really long way. Reconsider when you sell yourself short. Working with the people pays as well as working with code does.

    If my commentary seemed long, or elementary, etc... it's just to better associate the words in what are effective comments in my experience to instructions / code. And it's for other passers by who may benefit. Don't think it's aimed at anyone in particular. Just thought it would have some value.

    And besides, it did get me propping tonight, which is never a bad thing.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-15 22:19
    I recommend reading the 1-Wire spec.

    Indeed. I've learned a ton by reviewing code written by others against an official data sheet. Often, the data sheet will provide insights that will help us discover why a programmer made one choice or another.

    Also, good variable and function names go a long way too.

    On board with Kye there, too. I tend to be concise, yet use meaningful names. A young programmer once told me I should change the name of the out() method in a 74xx595 object to output_one_byte_with_74xx595(). After I picked myself up off the floor, I said, "No, thank you." and I suggested that with experience, his method names would become more practical.

    I think the real key is to dive in and do it. Personally, I tend to write libraries instead of looking for them because I enjoy programming -- and when it comes to code with my name on it I tend to be a control freak. My acting teacher used to say that actors have to get on a stage or in front of a camera to advance in their craft. Watching good acting is not enough -- otherwise there would be no teachers, we'd simple watch great plays an movies. I think programming is the same: we have to write code, not simply stitch together objects written by others. Again, I'm not anti-object, in fact, I often chastise my friend Rick for not asking for my code. To his great credit, he wants to try first. When he cannot get where he wants to go he often invites me to lunch or dinner and we talk. If things get desperate, he'll ask for a bit of code. He's made a lot of progress the last couple years, and his work was featured in the Bud Light Super Bowl commercial. Rick helped build and did the electronics for the human-sized Pac Man ghosts. He used my WS2812 driver because that's beyond him at the moment, but everything else -- with just some enthusiast cheer-leading from me -- was all him.
  • ErNaErNa Posts: 1,752
    edited 2015-02-16 02:27
    As we are living in the times of the internet, other ways to create documentation are given. I use CMapTools to create something like a flow diagram to visualize the structure of a piece of code. Like I did it some time ago for the game of life, where documenting the program flow of the initial version showed symmetries in code which allowed to rearrange the flow to simplify the structure. http://cmapspublic3.ihmc.us/rid=1193930895701_686240336_10261/CMap0047_game_of_life.cmap. As I plan to use 1-wire components too, and as the problem with drivers exists for radios also, this could be a starting point to show, how CMapTools can be used in collaboration.
  • MJBMJB Posts: 1,235
    edited 2015-02-16 06:20
    @Stephan, btw I have to say that reading these sensors, accepting serial commands, and logging onto an SD card is a snap in Tachyon. But there would be no real challenge if you did it that way as everything is too easy and MJB has the 1-wire search code too.
    I sent him my Tachyon 1-wire code already plus the EXPLORER image including the 1-wire code with 1-wire auto detection on all pins.
  • bte2bte2 Posts: 154
    edited 2015-02-16 11:57
    When I began programming, it was for machine control. I have a Heathkit Hero robot with a 6-digit display and a hex keypad. It has a Motorola 6808 processor, and everything I wrote went into RAM. Every byte that I programmed into the thing was byte-by-byte. I still remember a lot of them:

    86 AA 'load ACCA with immediate byte $AA
    BD F6 4E ' jump to the sub to clear the display and home the cursor
    BD F7 AD ' jump to the sub to write the contents of ACCA to the current cursor position on the display


    While I learned how to do it the hard way, I also picked up some bad habits in that most of my programs weren't commented or even really written down.

    Along about 1986 or so, I bought a PC that didn't have a hard disk drive (was still a couple years out) but I was able to write my robot programs in mnemonics instead of byte codes. And comment them. I could hit the compile button and then use the dot-matrix printout for a list of bytes to manually enter into the robot.

    Every tiny change in any program resulted in me having to manually count address offsets (all of them) throughout.

    Stuff today? You youngsters have it WAYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY easier than I ever did. My first PC cost nearly $4000 by the time I left the store. That is $4000 in then-Dollars, which is probably like $8000 today.

    384K of RAM and one 5.25", 360K single-sided drive.

    This isn't intended to be a rant about who walked through the most snow to get to school, it is intended to let you know that the world expects you to do your own heavy lifting.

    You will be better off for your efforts.
  • bte2bte2 Posts: 154
    edited 2015-02-16 12:06
    JonnyMac wrote: »
    It's the Arduino syndrome: people that cobble together pre-written program fragments and want to declare themselves "programmers."

    I have seen the term "script kiddies" bandied about.
  • MJBMJB Posts: 1,235
    edited 2015-02-16 14:02
  • StefanL38StefanL38 Posts: 2,292
    edited 2015-02-17 14:00
    I'm still reading the prop-forum and still reading this thread.
    But I have nothing to say or to ask at the moment....
    There seems to be no resonance on what I was asking for.
    So I decided to stop trying to create resonance or trying to explain
    why it makes sense to me to do it this or that way.

    @potatohead: Thank you for explaining on how you do it.
  • bte2bte2 Posts: 154
    edited 2015-02-17 16:55
    Not to sound like a jerk, but your OP was somewhat of a tall order. There aren't many programming forums where your request would get any better of a reception.

    Anything that is provided will need to be reworked to fit your programming style, and that means analysis.

    Automatically (and reliably) inventorying a 1W buss is a tricky proposition, and if you are going to venture into those waters, you need to bone up. To my way of thinking, providing you with more than just the very basics will hurt you more than help you.

    Again, I'm not trying to be a jerk, but that is how I personally read it.

    I hope you find that which you seek. I did some 1W stuff with PICs but never the Propeller.
  • ChrisGaddChrisGadd Posts: 310
    edited 2015-02-28 09:23
    Seems to me that the request was perfectly reasonable and what any 1-wire driver should be able to accomplish. There're a couple generic drivers already in the obex, and I just added my own here written specifically for the DS1822.
    It runs entirely in Spin, searches the bus for any connected devices and stores the rom codes, reads temperatures, and searches for alarms. Works with externally or parasitically-powered devices.
Sign In or Register to comment.