There's nothing that says part numbers have to be positioned on shelves in sequential order. You track the *location* of a part as part of your inventory control system. So that you are free to put things wherever is most convenient.
E.g., large sheets of copper, mu metal, FR4, etc. will have similar storage requirements -- regardless of their part numbers. So, you organize the stock in such a way that makes sense for those parts without concern for the arbitrary "identifier" you have assigned them.
Let the machine figure out where something is. Let it print your pick list in an order that *it* knows is efficient (because *it* knows the physical layout of your stockroom and can order the part numbers so you don't wander around looking for numbers "in numerical order"; sort of like preparing a grocery list -- you list the eggs with the butter so you can pick up both of them in "Dairy")
Our part numbering system *was* somewhat intelligent. 0603 resistors are of the form 501-3110-nnne. Then some knucklehead demanded that all parts be numbered sequentially. Now some 0603 resistors will have a number like
00000201. Who cares about making sense to engineering?
THe inventory location has nothing to do with the part number, though.
IME, you have to do this. Engineering will often have parts that are "under consideration", "being evaluated", etc. You don't want to incur the cost of making these "real" parts -- because you don't know if you will *ever* use them in your product line. This has been true of every company I worked for.
"The Stockroom" was for manufacturing's use.
(OK, if you've got "3 samples" that you keep in your desk drawer, no one really cares. But, often you need to buy a considerable quantity of "something" to do a prototype run. Keeping these things safe, organized and "out of the way" usually requires some sort of "parts room")
*Fix* your part/inventory system if *it* is the problem. That's like saying "I'll buy a new car because I can't remember where I parked my old car".
I've always built things by being familiar with *other* things that were being built at the time and seeing what parts *they* used. Pick up a board (usually engineers have copies of the boards they have designed or are supporting "on their desks") and *see* what's being used. Ask the other engineers what they are looking at for future projects, etc. Even outside salesmen can clue you in on what your peers are expressing an interest in ("Hey, Bob asked me for a XXXX databook. Would you like me to drop one off for you, too?")
Why *should* it be? Do you seat your children around the table by age? alphabetically?
A part number is an identifier. A location is an identifier. A child's name is an identifier.
Do you *really* think DigiKey has all of their parts on shelves in numerical order?
Because you don't put "room 4, shelf unit 13, bin 5" on a bill of materials!
You put *things* in *places*. Parts in locations. You associate a part with a location in much the same way that you associate a part with a subassembly.
Part numbers are just ways to identify parts.
Location numbers are just ways to identify locations.
If you reorganize your stock room, should all of the part numbers change? But, clearly the *locations* of all of those parts must change! So, your desire to arrange parts contiguously by part number forces your stock room to have a particular shape.
(Or, do you have a little sign located between part #0999 and #1257 saying "1000-1256 located down the hall"?)
I'm deploying exactly this sort of system currently. Everything has an identifier. EVEN PEOPLE!
The RDBMS puts the smarts to the system. Map an identifier into an "object type": "What is 12345678?" "12345678 is a person"
Based on that object type, figure out what the actual object's characteristics are. "Please describe person 12345678" "12345678 has brown eyes, is 6' tall, male, etc."
When I need an identifier "anywhere", I impose criteria on what sort of object I expect in that "application". So, for a timeclock application, I expect the identifier to map to "PERSON" and not "RESISTOR".
Using this sort of approach, I can have many different classes of objects and allow the descriptions for those objects to be intelligently *parameterized*.
E.g., create a new part: 55667788 What is it: (multiple choice) RESISTOR OK, since it is a resistor... What value: 4K7 Tolerance: 5% Rating: 1/4W etc.
Create a new part: 55667789 What is it: SCREW OK, since it is a screw... Head type: clutch Thread pitch: 32 Size: 6 Length: 1"
Create a new part: 55667790 What is it: PCB OK, since it is a circuit board... Schematic: 12342345 (which must be of type "SCHEMATIC") Artwork: 45567788 (which must be of type "ARTWORK") BOM: 45324323 (which must be of type "BoM")
etc.
Now, I can have a "method" for each part type called "Describe()" that is consistent across *all* objects of that type! So, when I print out a part list,
*all* RESISTORs are described by concatenating Value with Tolerance with Rating and prefacing all of this with the letters "Resistor".
Likewise, all SCREWs are described by concatenating Head with Size with Pitch with Length and prefacing with "Screw".
If I want to know what components are located on shelf
3, of shelving unit 5 in room 2 I just query the RDBMS for the Location identifier(s) associated with that particular physical location; then, pull up the "parts" that claim any of those identifiers as their locations.
If I rearrange stock tomorrow, all I need to do is rebuild the mapping of part identifiers to location identifiers (walk down the aisles with a barcode scanner; scan location identifier barcode; scan all part identifier barcodes in that "location"; step and repeat)
This sort of approach allows identifiers to be refined based on the type of thing they identify -- so you don't end up forcing people to always type:
"RESISTOR, " ", " ", "
each time they create a part number for a "resistor". Yet, you *ensure* that all of these values are specified
*for* that part -- because that is what the "create()" method for a "resistor" enforces.
So, you can build good search tools because all of the attributes of each type of object are "tagged" -- instead of having to do fancy string matching (and hope all of the strings were built correctly)
No, I put "231-2170" for a 1N5247B. And I can go to the stockroom and walk right up to the bin, knowing that number. It's the stock number
*and* the location. Isn't that just too clever?
No. It forces groups of parts to be locally ordered. What's wrong with that?
One of our part attributes, in the database, is "location". S means stockroom. B1 means one area of the basement, where we have stuff like chassis and power transformers. I think we have 4 or 5 named areas. But everybody pretty much already knows that big transformers are downstairs; if you don't, look it up. The parts in the stockroom, the electronic stuff, wraps around the room in part number order. Hardware is in a carousel sort of thing on the production floor. A lot of people, production and engineering, designed the system. It works really well, much better than anything I've ever seen elsewhere... and I've seen some horrors.
If I need an SMB connector, I look up any one and then go browse the shelf where all the other SMBs are located. They are all together, because SMB connectors have a defined part number prefix. Resistors and capacitors and inductors are together, ordered by value. That's nice too.
John
Well, good luck, whenever you get it done.
Saves having to remember all those pesky unstructured "names" things. "Good morning 34719622. Can I get you a cup of 7192453?"
Yikes. Now you need a product structure document (or database) to tell you which schematic goes with which bare board and which assembled board. And where they are all kept. And what drawings (of type "drawing") and parts lists (of type "parts list") apply.
Been there, done that, never again.
I bet that if you have a shell-and-pin connector, the shells are kept far away from the pins because "shell" and "pin" are different types.
A schematic is a reference drawing that doesn't control anything; it refers to parts by reference designator. Assembly drawings and their associated parts lists control product configuration, and they use part numbers. I'm surprised I have to explain stuff this basic.
What doesn't surprise me, any more, is what a horror most material and document control systems are.
I don't like the idea of some poor Joe modifying my code if he can't even understand it. There's a point where mov a,b ; copy b to a becomes so verbose that it adds absolutely no meaning, serving only to obfuscate useful statements.
Supposedly, there was a disassembler which automatically commented, adding exactly this type of superfluous verbosity.
I must admit, your comments don't seem to be vacuously verbose, an impressive feat at their density!
Heh... last one I did looked like:
-=-=-=-
uint8_t A, B;
...
// Switch debouncer
// A = true when open for 3 cycles A = debounce[0] & debounce[1] & debounce[2]; // B == true when closed for 3 cycles B = ~(debounce[0] | debounce[1] | debounce[2]); buttons = ~(A | ~(buttons | B)); debounce[2] = debounce[1]; debounce[1] = debounce[0]; debounce[0] = PINA;
-=-=-=-
Makes sense, right? No? Well, in this case I have the logic diagram which accompanies the code. ASCII art isn't really my style, though I agree it would be handy here for someone looking at this block in situ.
If you haven't decoded the function: it's a block that I'm quite fond of in VHDL. Each button (there are 5, but the whole PINA port is debounced since we get 8 bits/byte -- we'll be masking later when reading the buttons, no need to do it right now) is put into a shift register (which could be a circular list instead of cascaded variables, but it's not speed critical or anything). When all three bits of that register are true (A = 0 & 1 & 2), a flip-flop is set. When all three bits are false (when 0 | 1 | 2 is false), the flip-flop is reset. Actually it's inverted from that, since the buttons are active-low, but that's the jist of it. So it's a filtered, hysteretic debouncer.
Perhaps unusually, I think the code looks better in VHDL. You have constructs like "if debounce[0] == '0' and debounce[1] == '0' and ...", which are imperative, more descriptive than an abstract logic function is. VHDL lets you do whatever you want with bits or vectors, whereas processors can't construct "ifs" on a bitwise basis (not without a *lot* more code).
Having typed this, maybe I'll paste it in as comment... :-p
Tim
--
Deep Friar: a very philosophical monk.
Website: http://webpages.charter.net/dawill/tmoranwms
Agreed. Comments should tell what the *goal* of the code is ("why") and not restate "what it's doing".
Yup. Though I don't see how *time* gets factored in (no doubt the "samples" are taken periodically so there is something, someplace, that allows you to map "number of consecutive samples" to some "period of time".
The handler I posted debounces only on the releasing edge. I.e., as soon as a button closure is detected, the key "event" is passed to the application (assuming it was a *single* contact closure). The state machine re-arms after it has detected a successful "release" (no closures detected for DEBOUNCE_TIMER interval).
Everything is an event. So, you can just as easily pass a "KEYBOARD STUCK" event down the same channel as the keys themselves (simplifies handling at the application layer).
Likewise, I could pass BARCODE_READ down the channel to inform the application that the barcode decoder had just decoded a valid barcode. (Or, POWER_FAIL, MOTOR_AT_LIMIT, etc.)
I like using FSM's in my code. User interfaces are nothing but *big* FSMs (often containing nested FSM's). It seems to make things easier to understand and modify.
Understood. Like me checking for "a single column" detected. Some things end up just being idioms that you hope folks will understand :<
; To be able to get some speed, will use 2 buffers of 106 characters each. ; Using 2 buffers for the incoming characters, and INDF1 as pointer, when one buffer is full, send_udp_data will send it, and incoming characters wil lgo to the other buffer, and vice versa. ; This way there is about 106 characters time, or ; 115200 Bd at 1 start, 1 stop, 8 data bits is 11520 characters / second, = 86.8 us / character, 106 charactes takes 9.2 mS this is the time we have to send the UDP packet.
; character to transmit buffer movfw RCREG movwf POSTINC1
incf transmit_buffer_count
; test if buffer 1 full movlw D'106' cpfseq transmit_buffer_count goto test_buffer_2_full
; buffer 1 full, ; signal to main to send buffer bsf flags2, SEND_BUFFER_1_FLAG
; wait for next character goto int_end_clr
; pointer now points to buffer 2, is RAM at 0x100 + 43 + 106
Our schematic controls the BOM (guarantees that they're in sync). The "assembly drawings" are for inspection use only; pick-n-place machines can't read them.
You didn't answer the other questions. What do you do with obsolete part numbers? Leave a shelf empty for eternity? What happens with a new part that similar to other parts. Move everything in your stockroom to make room for it?
Of course we have no chance to compare apples to apples, but perhaps we could get some feeling. I was more after a "fullblown" thing, the directory list I posted does it "all", tcp & udp checksum, crc16 & 32 (for ppp), defaults to a 512 simultaneous connections (never used up so far :-) ), generally you get a stack a "normal" OS would expect. "Zero copy" is never really quite zero, but to the extent reasonable I am doing it. Incoming tcp data will get copied once if the application asks for it just "somewhere" in its memory space, I know of no other sane way of doing it. Packets can also be accessed raw, of course, but normally tcp is about having an uninterrupted stream. Outgoing data are not copied at all if the hardware will allow it (on the mpc5200 it does, except IIRC for tiny packets where it was impractical to pursue).
We removed empty bins for deleted stock numbers. There was a slot left empty every so often, to allow for expansion. Between the two, the shelves only got reset during the slow season. A lot of designs went from through hole to surface mount. Strange as it may seem, we gained space on the resistor and capacitor shelves for the same level of stock numbers. :)
--
Anyone wanting to run for any political office in the US should have to
have a DD214, and a honorable discharge.
The user probably already has 6.9 megabytes of that installed, but you have to bundle it anyhow just in case they don't, and because providing the ability to download dependencies as required appears to be beyond the capabilities of the people who write Windows installers.
We make dash number versions of assemblies, which includes functional variants and customizations for particular customers. So the values on a schematic are not guaranteed to be correct, and all the shown parts may not be stuffed. Schematic 22S470B is a reference drawing for PCB fab drawing 22D470B and assembly drawing 22A470B. The assembly drawing may in turn have multiple associated parts lists for different dash numbers, a parts list being a file like 22A470.12B for the physical entity 22A470-12B. An ECO or test procedure or manual states which assemblies it applies to. Everything lives on a server.
Once a product drawing set rev A is released to the server, we never change it; the next set will be rev B. If we need to make a small change to the rev A stuff, we do that by ECO. We can create a new dash number of any product, at any time, by creating a new parts list, which can reference any new drawings or procedures that might have been created.
This is pretty much standard military/aerospace policy, with our own non-random way of naming drawings and assemblies. It works great. People without the mil/aero tradition tend to make up all sorts of dangerous fuzzy stuff. When you build airplanes, things need to be kept under control, and configuration must be absolutely known.
If we find a bug in a design, we need to know the exact configuration and status of every unit in the field, so we can alert the customers and fix the ones that need it. Or if a customer returns a unit for cal or repair, we need to exactly understand its version and history.
If a part might be needed for a repair, we keep some in stock. One of our selling points is that we will build or repair anything, no matter how old, as long as we possibly can.
If a part is truly dead, we physically "retire" it to a section of the basement. You never know if engineering will want to play with one. If it's a real klunker, essentially scrap metal, we get rid of it.
We never reuse a stock number. It stays in the database, with a note like "retired" or "buggy:do not use". There's a folder associated with each part where we park datasheets, photos, app notes, measurements, purchasing notes, rants, anything we want to remember.
Most parts are small. 10-20 bins go on a shelf. Or roughly 40 reels. We put parts on shelves. We have some empty shelves, mostly the less accessable high and low ones, because we planned for expansion.
What happens with a new part that
Sure. We leave some spare space on every shelf. If a shelf overflows, you have to shuffle a little, which might take 45 seconds to do. We have a materials/purchasing person who does all that management. A stockroom isn't a graveyard with fixed plots. But the parts are always in physical order by stock number, with big bold labels on every bin, so it's no great mental challenge to locate a part. And then all the similar parts are right next to it. I physically "shop" parts when I'm designing, especially things like connectors and cable ties and heat sinks. Simple things like 0603 caps I can shop on my computer; I know what they look like.
Libraries stash books on shelves using an almost-as-good system. They don't randomly mix cookbooks with mysteries [1] with DVDs, and they do manage to keep the shelves in order. Books are worse, actually, because they don't get stored in bins, and can float between branches.
Why do you want to force dogmatic catagorizations when practical things work better?
We, engineering and production, designed and implemented this system together. We have *lots* of experience with stuff like this. We all love it.
John
[1] there are ambiguities, like the Nero Wolfe Cookbook.
I would never program any Intel machine in assembly. What dogs!
Here's some typical 68K assembly:
.SBTTL . MANAGE RTD CONTROLS
; HERE WE GRAB RTD RESISTANCE AND TEMPERATURE FROM RAM (LEFT THERE ; BY IRQ SCANNER) AND POKE TO VME. WE ALSO HANDLE THE RTD OOPSBITS ; IN 'RFLAGS'. BAD DESIGN RESULTED IN 8000h TEMPERATURE BEING USED ; AS THE 'BAD OR DISABLED RTD' INDICATOR, SO NOW WE PAY FOR OUR SINS.
SRTA: MOVE.L RARES.W, VW1.W ; FETCH RTD RESISTANCE AND ALWAYS MOVE.W # RAHI+WRQ+DBL, VADD.W ; WRITE TO ATOMIC VME SPACE
BCLR.B # 0, RSTAT+1.W ; ZAP RTD 'A' ERROR BIT PEEK RTDA ; GET RTD CONTROL REG FROM VME MOVE.W D4, RATYP.W ; COPY THAT TO RAM BEQ.S ADIS ; DISABLED? POST NO ERRORS!
MOVE.W RATMP.W, D4 ; GET ACTUAL TEMPERATURE CMPI.W # 8000h, D4 ; IS THIS THE ERROR VALUE? BNE.S APOK ; NO, POKE BSET.B # 0, RSTAT+1.W ; YES, SET RTD ERROR BIT BRA.S APOK ; AND POKE ANYHOW.
ADIS: CLR.W D4 ; DISABLED: SET VME TEMP TO ZERO APOK: POKE TMPA ; AND LEAVE FLAG BIT CLEAR JMP (A4)
We're moving to ARMs for most future stuff, so all that will be in C.
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.