OT: Software bloat (Larkin was right)

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")

Reply to
D Yuniskis
Loading thread data ...

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.

Reply to
krw

Cool. Every part gets a location number that determines their location and order on the shelves. So why isn't that the part number?

And the next innovation is to eliminate the useless part number. Got it.

So the pick list is in sequential order by location, and the parts are ordered on the shelves by location number. Great idea.

So what use is the part number now?

John

Reply to
John Larkin

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?")

Reply to
D Yuniskis

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)

Reply to
D Yuniskis

...and if you change the inventory location you change all your schematics. If you obsolete a part you can never use that shelf again?

...and you continually add shelves, even if others are no longer used.

It points to the function of a part, not its inventory location.

Reply to
krw

If I had 4900 children, I probably would.

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.

John

Reply to
John Larkin

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.

John

Reply to
John Larkin

Bicker, bicker.

Concatenate both numbers, hash them, and use the hash code.

The number is completely devoid of meaning, and offers instant access to its field in the database.

This satisfies both parties, debate over. ;-)

Tim

--
Deep Friar: a very philosophical monk.
Website: http://webpages.charter.net/dawill/tmoranwms
Reply to
Tim Williams

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
Reply to
Tim Williams

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 :<

Reply to
D Yuniskis

On a sunny day (Sat, 22 May 2010 00:49:31 -0700) it happened D Yuniskis wrote in :

Use clear variable names, and also labels that say what is happening.

get_rx_char: ; test_serial_port_interrupt btfss PIR1, RCIF ; test if serial port interrupt goto int_end

; have serial char in RCREG

; test if RS232 streaming to UDP movlw MODE_STREAM_RS232_TO_UDP cpfseq mode goto int8_no_streaming

; stream bcf flags2, TIMEOUT_FLAG bcf flags2, ALL_SEND_FLAG

; 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

test_buffer_2_full: movlw D'212' cpfseq transmit_buffer_count

; wait for next character goto int_end_clr

; buffer 2 full ; signal to main to send buffer 2 bsf flags2, SEND_BUFFER_2_FLAG

; reset the pointer to point to buffer 1 again, should have been send by now lfsr FSR1, (0x100+D'43')

; clear the byte counter clrf transmit_buffer_count

; wait for next character goto int_end_clr

int8_no_streaming:

Reply to
Jan Panteltje

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?

Why isn't your street address your name?

Reply to
krw

...and creates the worst of both alternative.

You *must* be a Pelosi Demonicrat.

Reply to
krw

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).

Dimiter

------------------------------------------------------ Dimiter Popoff Transgalactic Instruments

formatting link

------------------------------------------------------

formatting link

Reply to
Didi

If

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.
Reply to
Michael A. Terrell

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.

Reply to
Nobody

have

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.
Reply to
John Larkin

We agree on that!

John

Reply to
John Larkin

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.

John

Reply to
John Larkin

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.