Shop OBEX P1 Docs P2 Docs Learn Events
Trying to decide on what problem to tackle — Parallax Forums

Trying to decide on what problem to tackle

SarielSariel Posts: 182
edited 2011-08-01 09:19 in Propeller 1
I guess this can be better titled as "HOW to tacke this problem...." rather than the garbage I posted it as..... anyhow


Working again on the new version of my tester. I want a "Probe Mode" so that single-ended assemblies can be plugged into a mating fixture, and a grounded probe is touched to one of the bare wires, and a pin number comes up on the display. I would like to access this info in the "Point" method, by using the "TP" variable as some kind of step counter. Here is my list of needs/problems:

1 - This main program is only a template. I want to be able to change one area quickly, so that this unit can test multiple assemblies without having to re-write all of the code. If modifications could be made in less than a minute or two, It would allow the prototyping dept. to have one for new assembly design and checking, and all my time would not be used up with every new assembly that comes through here.

2 - Some connectors are labeled by letters, some by numbers. Large pin count connectors go up to "Pin Z", then cycle to "Pin AA", and continue on. My hardware and code supports 64 test points.

3 - DAT blocks for this purpose are confusing me. If one assembly uses numbers, and the others are letters, wouldn't this change the data length per test point, thus making it difficult to predict where "TP A" ends, and "TP B" begins in one program, versus "TP 1" and TP 2" in another, using the same template program?

4 - Lookup would be super simple, but I am under the assumption that you cannot store anything but numbers in this fashion, and ASCII code would be a pain to do a conversion on by hand for 64 test points, every time I need to modify for a new assembly.

Here is a copy of the code I am using in my output file
 
VAR              
 
  Byte Xpos
  Byte Ypos
  Byte RowCnt
  Byte BlankCntA 
  Byte BlankCntB        
OBJ
 
  text : "tv_text"
 
DAT
RevA    byte  "0.000", 0  
Assy    byte  "Sample", 0
FIX     byte  "FX-0000", 0
{                        
TP1     byte  "1", 0     
TP2     byte  "2", 0       
TP3     byte  "3", 0  
TP4     byte  "4", 0  
TP5     byte  "5", 0  
TP6     byte  "6", 0  
TP7     byte  "7", 0  
TP8     byte  "8", 0  
TP9     byte  "9", 0  
TP10    byte  "10", 0  
TP11    byte  "11", 0  
TP12    byte  "12", 0  
TP13    byte  "13", 0  
TP14    byte  "14", 0  
TP15    byte  "15", 0  
TP16    byte  "16", 0  
TP17    byte  "17", 0  
TP18    byte  "18", 0  
TP19    byte  "19", 0  
TP20    byte  "20", 0     
TP21    byte  "21", 0  
TP22    byte  "22", 0  
TP23    byte  "23", 0  
TP24    byte  "24", 0  
TP25    byte  "25", 0  
TP26    byte  "26", 0  
TP27    byte  "27", 0  
TP28    byte  "28", 0  
TP29    byte  "29", 0  
TP30    byte  "30", 0   
TP31    byte  "31", 0  
TP32    byte  "32", 0  
TP33    byte  "33", 0  
TP34    byte  "34", 0  
TP35    byte  "35", 0  
TP36    byte  "36", 0  
TP37    byte  "37", 0  
TP38    byte  "38", 0  
TP39    byte  "39", 0  
TP40    byte  "40", 0   
TP41    byte  "41", 0  
TP42    byte  "42", 0  
TP43    byte  "43", 0  
TP44    byte  "44", 0  
TP45    byte  "45", 0  
TP46    byte  "46", 0  
TP47    byte  "47", 0  
TP48    byte  "48", 0  
TP49    byte  "49", 0  
TP50    byte  "50", 0   
TP51    byte  "51", 0  
TP52    byte  "52", 0  
TP53    byte  "53", 0  
TP54    byte  "54", 0  
TP55    byte  "55", 0  
TP56    byte  "56", 0  
TP57    byte  "57", 0  
TP58    byte  "58", 0  
TP59    byte  "59", 0  
TP60    byte  "60", 0   
TP61    byte  "61", 0  
TP62    byte  "62", 0  
TP63    byte  "63", 0  
TP64    byte  "64", 0  
}
PUB Start(TVPin)
''Start TV Cog
  text.start(TVPin)
  Header    
 
PUB TPIndex | Index, TPNo
  TPNo := lookup(Index:  1,  2,  3,  4,  5,  6,  7,  8,  9, 10,{    ' Lookup table for TP data
                       }11, 12, 13, 14, 15, 16, 17, 18, 19, 20,{
                       }21, 22, 23, 24, 25, 26, 27, 28, 29, 30,{
                       }31, 32, 33, 34, 35, 36, 37, 38, 39, 40,{
                       }41, 42, 43, 44, 45, 46, 47, 48, 49, 50,{
                       }51, 52, 53, 54, 55, 56, 57, 58, 59, 60,{
                       }61, 62, 63, 64) 
PUB Header
''  Base Screen                                           
 
  text.str(string($0B, 01, $0C, 03, "┌────────────────┬─────────────────────┐"))   ' Output Screen art
  text.str(string($0B, 02, $0C, 03, "│                │      Failures:      │")) 
  text.str(string($0B, 03, $0C, 03, "│                ├─────────────────────┤"))
  text.str(string($0B, 04, $0C, 03, "│                │                     │"))
  text.str(string($0B, 05, $0C, 03, "│                │                     │")) 
  text.str(string($0B, 06, $0C, 03, "│                │                     │")) 
  text.str(string($0B, 07, $0C, 03, "│                │                     │")) 
  text.str(string($0B, 08, $0C, 03, "│                │                     │"))
  text.str(string($0B, 09, $0C, 03, "│                │                     │")) 
  text.str(string($0B, 10, $0C, 03, "│                │                     │"))  
  text.str(string($0B, 11, $0C, 03, "│                │                     │")) 
  text.str(string($0B, 12, $0C, 03, "└────────────────┴─────────────────────┘"))
  text.str(string($0A, 02,{      ' Assy Flag 
                 }$0B, 01,{
                 }$0C, 03,{
                 }"Assy: ")) 
  text.str(@Assy)
 
  text.str(string($0A, 02,{     ' Display fixture 
                 }$0B, 04,{
                 }$0C, 03,{
                 }"Fixture:"))
 
  text.str(string($0A, 02,{     ' Display fixture number 
                 }$0B, 05,{
                 }$0C, 03))                                          
  text.str(@Fix)
 
  text.str(string($0A, 13,{     ' Display rev 
                 }$0B, 12,{
                 }$0C, 07,{
                 }"N.A.T.S. v"))                                                                                                 
  text.str(@RevA)                                                                  
  Xpos := 18                    ' Cursor Position for reports
  Ypos := 3
  RowCnt := 0 
 
PUB Testing
''Test in progress
  text.str(string($0A, 05,{     ' In-Process msg 
                 }$0B, 10,{
                 }$0C, 06,{
                 }" Testing  "))                        
 
PUB Pass
''Pass message
 
 
  text.str(string($0A, 05,{     ' Pass flag
                 }$0B, 10,{
                 }$0C, 04,{
                 }"   PASS   "))                       
 
PUB Fail(FailCnt)
''Failure message
 
  text.str(string($0A, 02,{     ' Failure count flag                            
                 }$0B, 07,{
                 }$0C ,03,{
                 }"Fails= "))     
  text.dec(FailCnt)           
  text.str(string($0A, 05,{     ' Fail flag
                 }$0B, 10,{
                 }$0C, 01,{
                 }"   FAIL   "))                                          
  RowCnt := 0
PUB Short (TestPoint, FailCnt)
''Short message
  Placement(FailCnt)            ' Set cursor for error                                                                  
  text.str(string($0A, 05,{     ' Lg. Short Flag
                 }$0B, 10,{
                 }$0C ,01,{
                 }"  SHORT   "))                     
 
  text.str(string($0A))         ' Go to position
  text.out(Xpos + RowCnt)                                                 
  text.str(string($0B))                                                    
  text.out(Ypos)                                                                
  Ypos := Ypos + 1 
 
  text.str(string($0C, 06,{     ' Sm. Short flag
                 }"S-"))                       
  text.dec(TestPoint)       
 
PUB Open (TestPoint, FailCnt)
''OPEN message
 
  Placement(FailCnt)            ' Set cursor for error 
  text.str(string($0A, 05,{     ' Lg. Open Flag 
                 }$0B, 10,{
                 }$0C, 01,{
                 }"   OPEN   "))                     
 
  text.str(string($0A))         ' Go to position
  text.out(Xpos + RowCnt)                                                      
  text.str(string($0B))                                                        
  text.out(Ypos)                                                               
  Ypos := Ypos + 1
 
  text.str(string($0C, 06,{     ' Sm. Open Flag
                 }"O-"))                                                                           
  text.dec(TestPoint)                                                            
 
PRI Placement(FailCnt) 
''   put in place a display overflow plan. resume test key,
''   clean the report area, then continue test  
  if FailCnt == 9               ' If end of Column1 is found
    Ypos := YPos - 8            ' Bring cursor back up to the top    
    RowCnt := 1                 ' Increment row counter variable
    Xpos := XPos + 4            ' Move to next row
  if FailCnt == 17              ' If end of Column2 is found 
    Ypos := YPos - 8            ' Bring cursor back up to the top
    RowCnt := 2                 ' Increment row counter variable
    Xpos := XPos + 4            ' Move to next row 
  if FailCnt == 25              ' If end of Column3 is found
    Ypos := YPos - 8            ' Bring cursor back up to the top
    RowCnt := 3                 ' Increment row counter variable 
    Xpos := XPos + 4            ' Move to next row                                                                     
 
Pub Counter(StepCnt)
'' Test step counter
  text.str(string($0A, 02,{     ' Step Number 
                 }$0B, 02,{
                 }$0C, 03,{
                 }"Step: ")) 
 
  text.str(string($0A, 06,{     ' Clear Old Numebr 
                 }$0B, 02,{
                 }$0C, 03,{
                 }"   "))
  text.str(string($0A, 06,{     ' Show Step Number
                 }$0B, 02,{
                 }$0C, 03))                                                              
  text.Dec(StepCnt)             ' Step number shown
 
  text.str(string($1))                                                         
PUB Point(TP)
  text.str(string($0A, 24,{     ' Probe Flag A
                 }$0B, 04,{
                 }$0C, 03, {
                 }"Probe:"))
  text.str(string($0A, 24,{     ' Probe Flag B
                 }$0B, 06,{
                 }$0C, 05, {
                 }" TP-   "))  
  text.str(string($0A, 24,{     ' Disp. Point Number
                 }$0B, 06,{
                 }$0C, 05,{
                 }" TP-   "))
  text.str(string($0A, 27,{     ' Disp. Point Number
                 }$0B, 06,{
                 }$0C, 05))
 
  text.Dec(TP)                  ' placeholder TP numebr (Step number copy for development) 
 
PUB nerp 
''Flag for debugging
  text.str(string($0A, 05,{     ' Disp. break Flag
                 }$0B, 09,{
                 }$0C, 06,{
                 }"  NERP  "))                                                                                                   
  waitcnt(clkfreq * 2 + cnt)                                                            
 
 
PUB BinOut( BinDat, Bits)
''Output binary status of tester inputs to TV (debug mode)
  text.str(string($0A, 04,{     ' Display position for bin data  
                 }$0B, 12,{
                 }$0C, 05))
  text.bin(BinDat, Bits)         ' Actual Binary Data
PUB Clean
'' Clean up display for next run
  BlankCntA := 18               ' Clear failure notification area
  BlankCntB := 3
  repeat 8                                            
    Repeat 21      
      text.str(string($0A))
      text.out(BlankCntA)
      text.str(string($0B))      
      text.out(BlankCntB)
      text.str(string($0C, 03, " "))  
      BlankCntA := BlankCntA + 1
    BlankCntB := BlankCntB + 1
    BlankCntA := 18 
 
  text.str(string($0A, 02,{     ' Clear FailCount area                             
                 }$0B, 07,{
                 }$0C ,03,{
                 }"        ")) 
 
  text.str(string($0A, 05,{
                 }$0B, 09,{
                 }$0C, 03,{
                 }"         ")) ' Clear notification area   
 
  Xpos := 18                    ' Reset cursor position
  Ypos := 3
  RowCnt := 0

Comments

  • StefanL38StefanL38 Posts: 2,292
    edited 2011-07-26 07:09
    Hello Sariel,

    I'm really sorry but I did not understand what you want to do.
    If you have explained more details in another thread please provide a link to it. Of if not please explain what your project does.

    From the basic principle Is the purpose of your canle-tester to check
    if PIN "A" of connector-1 is connected to PIN 27 of connector-2
    if PIN "Z" of connector-1 is connected to PIN 12 of connector-2
    if PIN "AA" of connector-1 is connected to PIN 45 of connector-2
    etc.?

    You wrote something about probing. In the code you posted there is a lot of output to a TV-screen
    but almost nothing about how the probing/testing is done.

    You want to change "an area quickly" which area of what? area of code?
    what are the typical changes? Can you give some examples?
    is there a regular pattern in the changes?

    Can you please provide a simple, a medium complex and a most complex example of how wires are named and what must be changed
    not as code but as a written description.

    How does a typical screen of a test passed everything alright and how does a typical screen look like where failures are in the cable?

    keep the questions coming
    best regards

    Stefan
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-07-26 07:57
    If I understand your question correctly, in the Point method you want to print something like "TP 27" or "TP AA" depending on whether the pins are numbered numerically or by letters. The text.dec method will handle the first case, so you just need a way to translate numbers to letters for the latter case. The following code will do that.
    pub Letters(TP)
      TP--
      if TP => 26
        text.tx(TP/26 + "A" - 1)
        TP //= 26
      text.tx(TP + "A")
    
    You can use a global "mode" variable to determine whether you use the numerical mode or the alphabetical mode. I'm not sure how the user interacts with the program, but if you have a keyboard you could prompt the user to enter the mode and number of pins to test.

    Dave
  • SarielSariel Posts: 182
    edited 2011-07-26 07:57
    Sorry about that, I tried to explain my problem with a minimal amount of ramblings. the code I posted is just one object file that the main test program uses, mostly for data output.

    This is my full base theory of operation:

    Yes. this is an auto-tester that has a data pin from a TPIC6595 connected to a data pin of a 74HC165 to make the resulting connection an I/O. this is repeated for each of the 8 data pins on each IC, then the TPIC's and 165's multiplexed to 8 pairs to give me a total of 64 I/O's.

    The main program cycles outputs to the TPIC6595, one point at a time. there is an array of variables in the main program that is compared to the data streamed in from the 74HC165's, and does some math to determine if the data found is an open, short, or correctly wired.

    A feature that is heavily requested by the production floor is an extra mode in the tester where we are able to connect a cable that has a connector on one end, bare wires on the other via an adapter that is made just for the product in question. This will let them be able to determine if the wire's color is correct for single-ended assemblies. I have a switch and the basic idea for putting the tester into this alternate mode.

    I would like one data section for Test point labeling, like I did for the "Expected cable information". Like I said earlier, Lookups I believe only handle numbers. I can trick it using ASCII codes in case I want letters, or even color names, but this is cumbersome. Numbers are no big deal, because in previous versions of this tester, I was able to tie it in with step numbers, and all was good. This is a clunky way of doing it, and I am looking for something better. If I were to use a DAT section (like the area for Fixture number, assembly number, and system Rev information), wouldn't that case problems if I do a "Raw access" to the data because in one product file the test point would be labeled "1", and in another it could be called "A", or in another called "Blue", creating a different offset, thus giving me garbage on the display?

    Here is the full source up to this point. I plan on adding the test point methods to the top level file as soon as I get this issue figured out.


    AutoTester MK2 v.001 - Archive [Date 2011.07.26 Time 09.48].zip
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-07-26 08:22
    If you want to allow the user to assign names I would suggest creating a table that would hold the maximum number of characters for each pin. As an example, if you allow up to 15 characters per name you would create a tabel that is 64*(15+1) = 1024 bytes in size. The "+1" allows for the terminating null. You would then print an entry as text.tx(@labels+(MAX_CHARS+1)*(TP-1)). The default names for the pins could just be decimal numbers. It woud look something like this:
    con
      MAX_CHARS = 15
    dat
      labels
      byte "1", 0[MAX_CHARS]
      byte "2", 0[MAX_CHARS]
      ...
      byte "62", 0[MAX_CHARS-1]
      byte "63", 0[MAX_CHARS-1]
      byte "64", 0[MAX_CHARS-1]
    
    If the user changes the labels you could write them back to EEPROM so they would persist during a reboot or power cycle.
  • SarielSariel Posts: 182
    edited 2011-07-26 08:34
    ahhhhhh fixed length in the DAT section. Perfect. I don't think I would be needing anything as large as 15 characters tho. I think I can get away with an absloute max of 7. Numbers up to 64, letters from "A" to "BL" (or something close to that), and colors I could abbreviate like BLU, GRN, with the mother of all memory hogs being striped jackets like WHT/GRN

    I'll start coding all this in after a little bit, and let ya know if this does the trick. Thanks Dave.
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-07-26 09:44
    Hello Dave,

    congrats to your ideas. You took the time to understand the problem and made good suggestions.

    best regards

    Stefan
  • SarielSariel Posts: 182
    edited 2011-07-26 11:28
    Works like a charm. Made a couple modifications to your suggestion... for the TV_Text object, there is no tx method, so I got it by just using...
      text.str(@labels+(MAX_CHARS)*(TestPoint))
    

    I wrote this into my open and short reporting methods, and from the first looks, it was changing the wire location flags accordingly. Thanks so much for the suggestion
  • SarielSariel Posts: 182
    edited 2011-07-26 12:33
    Hrm... Something is still not right. I tried it on one point, altered it in the DAT section, dumped it back to RAM, and it changed accordingly... now that I'm verifying all the test points, for some, it gives no data, for others it gives garbage. my shift today is over, but I'll look into it more tomorrow, and give more information as I have it.
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-07-26 13:05
    text.str is the correct method to use. If there was a tx method it would have printed the string address instead of the string, which was a mistake on my part.

    I defined MAX_CHARS to be the maximum size of each label, not including the terminating null. Therefore, the string address should be computed as @labels + (MAX_CHARS+1)*(TestPoint-1). I'm assuming TestPoint has values from 1 to 64. If TestPoint has values from 0 to 63 then the "-1" should not be used. Similarly, if you define MAX_CHARS to include the null then the "+1" should not be used.

    Each entry must contain the same number of bytes in the table. In my example, I padded out with MAX_CHARS zero-bytes for single-byte names, and (MAX_CHARS-1) for two-byte names. If you intialize the table with multi-byte labels you need to adjust the number of zeros accordingly.
  • SarielSariel Posts: 182
    edited 2011-07-27 03:48
    Ugh.. I'm thinking my brains were fried by the end of the day. I Have it reporting full numbers again because I left a couple wrong "Zero Fill" markers, But things seem to be a bit out of order to what I was expecting, but I think I may have a plan of attack. I think between the 2 of us, we have MSB and LSB switched around, and that is a bit of a significant problem, especially since I split the input stages into 2 busses because of the inherit limit of space per max variable size. I'll admit it.. I took the easy way out and stored the input as 2 separate variables, and deal with them separately. Hence the reason why my cable data section in the top level file is 128 longs... well... long. It is going to take some creative re-organizing of the labels to get the pin names to come out correctly, but I am hoping that will solve it without me having to completely re-write the I/O section.
  • SarielSariel Posts: 182
    edited 2011-08-01 07:36
    Ok... on to the next part of all of this Let's say, for example that I wanted a break point in the program if it were to find a test point labeled *EMPTY* (yes, with the asterisk). This will speed up testing so that it does not continue past an end of test marker. I have tried looking for $2A in the data, knowing that I can use the asterisk as my marker. This did not work out. I just now tried to look for it by...
        if (labels + (MAX_CHARS+1)*(TestPoint-1))  == string("*EMPTY*")   
    
    ...and it skips right past it. Just for grins, I also put the "@" before labels, but to my understanding this would not do it either because that would just compare the Data's address to *EMPTY*, and that will never be equal. There has to be a way to do this... can anyone out there think of a good way of accomplishing it?
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-08-01 07:53
    The left side of the "==" expression is the address of the label for the test point given by "TestPoint". The right side is the address of the constant string "*EMPTY*". What you should do is use STRCOMP() to compare the two strings.
    if STRCOMP(labels + (MAX_CHARS+1)*(TestPoint-1), string("*EMPTY*"))
    
    Note that every time you use the "string" operator Spin will create a new instance of the string. So if you reference "*EMPTY*" more than a few times you may want to put it in the DAT section, and reference it as a variable.
    dat
      emptry_str byte "*EMPTY*", 0
    
    ...
    if STRCOMP(labels + (MAX_CHARS+1)*(TestPoint-1), @empty_str)
    
  • SarielSariel Posts: 182
    edited 2011-08-01 09:19
    Note that every time you use the "string" operator Spin will create a new instance of the string. So if you reference "*EMPTY*" more than a few times you may want to put it in the DAT section, and reference it as a variable.

    Yeah I looked that up while you were editing your post, and saw pretty much the same thing in the prop book. I am going to be doing that comparison once inside of a loop, so it should not take up any more memory than making a variable out of it, and referencing that.

    But, all that aside, I got it working. Thanks again Dave. And still, I learn piles of info from folks in this forum. Truely everyone here is ridiculously helpful. I just hope that someone else out there is learning from my blundering, and someday in the near future I will be able to give a little back. :o)
Sign In or Register to comment.