There are 53 messages in this thread.
You are currently looking at messages 20 to 30.
Tomás Ó hÉilidhe wrote: > To use the least > amount of memory possible for each LED, I thought I'd go with the > following strategy: > > * Use three bits per LED. 00 = Off. 01 = Red. 10 = Unused. 11 = > Green. The reasoning behind that choice of encoding is flawed. Putting an unused state in the middle of a list of values will "use the least amount of memory possible" only by luck, but never by design. > void SetChunk(uint_fast16_t const i, uint_fast8_t const state); Here's your first unwarranted assumption (although it's not one of portability). You've validated your self-stated requirement: > (Of course you can set the chunk size bigger or smaller than 3 bits) Using uint8_fast_t for the datatype disallows setting the chunk size to more than 8 bits. In addition to that, 'i' should really be size_t or something at least as large as that. As-is, you introduce yet another hardcoded limitation. > #define TOTAL_BITS_NEEDED (QUANTITY_CHUNKS * BITS_PER_CHUNK) Bad macro. Parentheses missing around QUANTITY_CHUNKS and BITS_PER_CHUNK leave the code vulnerable to funny definitions of those constants (e.g. #define BITS_PER_CHUNK 2+3) The same problem occurs repeatedly later on. And it has a portability problem, too! Check out what this does for QUANTITY_CHUNKS=60000u, BITS_PER_CHUNK=6u, on a 16-bit host platform. You lose. Thanks for playing. > #define BITS_ALL_ONES(x) ((1u << (x)) - 1u) Will fail as soon as pow(2,x) > (UINT_MAX + 1)... (e.g. x=17 on a 16-bit platform). > #define CHUNK_ALL_ONES (BITS_ALL_ONES(BITS_PER_CHUNK)) ... so this fails if I set BITS_PER_CHUNK to more than the number of bits in an unsigned int (after lifting the earlier restriction about uint8_fast_t). > I've written this post to show an example of fully-portable code, that > is, code that will behave exactly as intended on every conceivable > implementation of the C89 standard. Well, it doesn't fulfill that promise. And that not just on some conceivable implementation of the C89 standard, but actually on entire *class* of systems that are in wide-spread usage.
In message <7...@f63g2000hsf.googlegroups.com>, Tomás Ó hÉilidhe <t...@lavabit.com> writes >On May 13, 6:56 pm, linnix <m...@linnix.info-for.us> wrote: > >> I am not the only one saying that your ideas are misguided. You are >> picking the smallest uC and trying to show what you can do with it. > > >I'm picking the PIC16F684 because it's the only one I'm familiar with, You said >I know portable programming in C. I'm sure of that. As sure as I know >that the sky is blue. I may not be the BEST portable programmer in the >world, but I can definitely tell you that someone is wrong if they >think it's impossible, or even difficult, to write portable code. I do >it a lot and I find it enjoyable. If you only have experience of one MCU how can you even suggest that you know how to write portable code? You would need real experience of several MCU before even suggesting you could write portable code. Thus far you have not shown anything to back up your claim. -- \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/ \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Tomás Ó hÉilidhe wrote: > I've been talking about portable C programming lately, and I've > claimed that I write fully-portable code. Many people here contested > this claim, some more rudely than others, so instead of trash-talking > back and forth I'm going to actually give an example of the way I > code. > > In my most recent embedded project, there was a severe memory > restriction. I had to store in memory the state of 42 individual > LED's. Each LED could have one of three states. To use the least > amount of memory possible for each LED, I thought I'd go with the > following strategy: > > * Use three bits per LED. 00 = Off. 01 = Red. 10 = Unused. 11 = > Green. > > I decided to go about writing a "module", a C source and header file > couple that would handle this tight memory access and provide a nice, > clean, easy-to-use interface. The module would need two pieces of > information from the programmer: > > * The amount of combinations (i.e. 3 for my LEDs' states) > * The amount of chunks (i.e. 42 because I've 42 individual LED's) I'd put the abstraction at the level of a "LED array", which would be a module responsible for driving an array of LEDs. My version of the interface would be something like this: void set_led_color( int led, int color ); The module would hide the peculiarities of the CPU, the hardware multiplex design, and memory layout restrictions. Given that most of the module needs to be rewritten anyway in case it is ported to a different design, I would not worry about portability of the module code itself. This approach allows simpler code (assume 4 LEDs / byte) and better optimization since I can pick a memory layout that fits the hardware, while keeping the interface to the outside world exactly the same. I consider the last part a more important version of portability.
On May 12, 6:10 pm, Tom=E1s =D3 h=C9ilidhe <t...@lavabit.com> wrote:
> I've been talking about portable C programming lately, and I've
> claimed that I write fully-portable code. Many people here contested
> this claim, some more rudely than others, so instead of trash-talking
> back and forth I'm going to actually give an example of the way I
> code.
>
> In my most recent embedded project, there was a severe memory
> restriction. I had to store in memory the state of 42 individual
> LED's. Each LED could have one of three states. To use the least
> amount of memory possible for each LED, I thought I'd go with the
> following strategy:
>
> * Use three bits per LED. 00 =3D Off. 01 =3D Red. 10 =3D Unused. 11 =3D=
> Green.
>
> I decided to go about writing a "module", a C source and header file
> couple that would handle this tight memory access and provide a nice,
> clean, easy-to-use interface. The module would need two pieces of
> information from the programmer:
>
> * The amount of combinations (i.e. 3 for my LEDs' states)
> * The amount of chunks (i.e. 42 because I've 42 individual LED's)
>
> From there, it would handle all the data accessing, both reading and
> writing. All the programmer has to do is invoke "GetChunk" and
> "SetChunk".
>
> In starting out to write this module, I knew I wanted it to be as
> portable as possible. I wanted it to work on machines that have an 8-
> Bit byte. Also those funky old machines that have a 9-Bit byte. Also
> supercomputers that have a 64-Bit byte.
>
> First off, I started with a header file to provide an interface. I
> refer to the little 3-Bit chunks of memory as a "chunk", and so the
> functions are "SetChunk" and "GetChunk". (Of course you can set the
> chunk size bigger or smaller than 3 bits).
>
> Here's the header file:
>
> /* ------------------------ Begin Header File: data_acc.h
> ------------------------------ */
> #ifndef H__DATA_ACC
> #define H__DATA_ACC
>
> #include <stdint.h>
>
> void SetChunk(uint_fast16_t const i, uint_fast8_t const state);
> uint_fast8_t GetChunk(uint_fast16_t const i);
>
> void SetEntireDataAllZeroes(void);
> void SetEntireDataAllOnes(void);
>
> #endif
> /* ------------------------ End Header File: data_acc.h
> ------------------------------ */
>
> Before I show the source code, I'm going to mention a complication.
> Let's take a canonical system such as an Intel PC that has an 8-Bit
> byte. If we were to use 3 bits per LED, then we'd be able to store 2
> LED's in one byte and we'd have 2 bits left over (i.e. 2(3) + 2 =3D 8).
> Well, instead of discarding those bits, what my code does is it takes
> the last 2 bits from the previous byte in conjunction with the 1st bit
> of the next byte. No bits are wasted on any system, regardless of the
> amount of bits in a byte or the amount of bits per "chunk".
>
> Now before I show the source file, I have to tell you about the two
> constants that are required from the programmer:
>
> QUANTITY_CHUNKS (e.g. This is 42 for the 42 LED's)
> BITS_PER_CHUNK (e.g. This is 2 because I've 2 bits per LED,
> e.g. 01 =3D Red)
>
> These two constants shall be defined in a file called
> "data_acc_specs.h". Here's a sample:
>
> #define QUANTITY_CHUNKS 42u
> #define BITS_PER_CHUNK 3u
>
> How the source code works is as follows. Internally, it has the
> concept of a "chunk pointer", i.e. a data type that gives it all the
> information it needs to locate a specific chunk in memory. The chunk
> pointer consists of two things:
> * The address of the byte in which the first bit resides
> * The index of the bit in that byte
>
> When you invoke GetChunk for instance, it will convert the index of a
> chunk to a "chunk pointer", and this chunk pointer will give it the
> information it needs to locate and read the relevant chunk.
>
> Here's the source code:
>
> /* ------------------------ Begin Source File: data_acc.c
> ------------------------------ */
> #include "data_acc.h"
> #include "data_acc_specs.h"
>
> #include <string.h> /* memset */
> #include <limits.h> /* CHAR_BIT */
> #include <assert.h>
>
> #define TOTAL_BITS_NEEDED (QUANTITY_CHUNKS * BITS_PER_CHUNK)
>
> #define BYTES_NEEDED (TOTAL_BITS_NEEDED / CHAR_BIT + !!
> (TOTAL_BITS_NEEDED % CHAR_BIT))
>
> #define BITS_ALL_ONES(x) ((1u << (x)) - 1u)
>
> #define CHUNK_ALL_ONES (BITS_ALL_ONES(BITS_PER_CHUNK))
>
> static char unsigned data[BYTES_NEEDED]; /* Raw memory for storing
> chunks */
>
> typedef struct ChunkAddress {
>
> char unsigned *pbyte;
> uint_fast8_t i_bit;
>
> } ChunkAddress;
>
> static ChunkAddress GetChunkAddress(uint_fast16_t const chunk)
> {
> # define i_bit_in_entire_data (chunk * BITS_PER_CHUNK)
>
> # define i_byte (i_bit_in_entire_data / CHAR_BIT)
>
> ChunkAddress addrs;
>
> assert(chunk < QUANTITY_CHUNKS);
>
> addrs.pbyte =3D data + i_byte;
> addrs.i_bit =3D i_bit_in_entire_data % CHAR_BIT;
>
> return addrs;
>
> # undef i_bit_in_entire_data
> # undef i_byte
>
> }
>
> uint_fast8_t GetChunk(uint_fast16_t const i)
> {
> ChunkAddress const addrs =3D GetChunkAddress(i);
>
> char unsigned x =3D *addrs.pbyte;
>
> assert(i < QUANTITY_CHUNKS);
>
> x >>=3D addrs.i_bit;
>
> # if CHAR_BIT % BITS_PER_CHUNK || !defined(NDEBUG) /* Chunk can
> spill into next byte */
>
> if (addrs.i_bit + BITS_PER_CHUNK > CHAR_BIT) /* Has spilt into
> next byte */
> {
> # define bits_in_current_byte (CHAR_BIT - addrs.i_bit)
> # define bits_in_next_byte (BITS_PER_CHUNK -
> bits_in_current_byte)
>
> char unsigned y =3D addrs.pbyte[1];
>
> y &=3D BITS_ALL_ONES(bits_in_next_byte);
>
> y <<=3D bits_in_current_byte;
>
> # undef bits_in_current_byte
> # undef bits_in_next_byte
>
> return x|y;
> }
>
> # endif
>
> return x & CHUNK_ALL_ONES;
>
> }
>
> void SetChunk(uint_fast16_t const chunk, uint_fast8_t const cs)
> {
> ChunkAddress const addrs =3D GetChunkAddress(chunk);
>
> char unsigned x =3D *addrs.pbyte;
>
> /* ---- First clear the chunk bits ---- */
>
> x &=3D ~(CHUNK_ALL_ONES << addrs.i_bit);
>
> /* Now OR the actual chunk shifted to the correct place */
>
> x |=3D (unsigned)cs << addrs.i_bit;
>
> *addrs.pbyte =3D (char unsigned)x; /* Truncation warning cast */
>
> # if CHAR_BIT % BITS_PER_CHUNK || !defined(NDEBUG) /* Chunk can
> spill into next byte */
>
> if (addrs.i_bit + BITS_PER_CHUNK > CHAR_BIT) /* Has spilt into
> next byte */
> {
> # define bits_in_current_byte (CHAR_BIT - addrs.i_bit)
> # define bits_in_next_byte (BITS_PER_CHUNK -
> bits_in_current_byte)
>
> char unsigned y =3D addrs.pbyte[1];
>
> /* ---- First clear the chunk bits ---- */
>
> y &=3D ~BITS_ALL_ONES(bits_in_next_byte);
>
> /* ---- Now OR with chunk bits ---- */
>
> y |=3D cs >> bits_in_current_byte;
>
> # undef bits_in_current_byte
> # undef bits_in_next_byte
>
> addrs.pbyte[1] =3D (char unsigned)y; /* Cast to suppress
> truncation warning */
> }
>
> # endif
>
> }
>
> void SetEntireDataAllOnes(void) { memset(data,-1,sizeof data); }
>
> void SetEntireDataAllZeroes(void) { memset(data,0,sizeof data); }
>
> /* ------------------------ End Source File: data_acc.c
> ------------------------------ */
>
> Of course, at the end of all that, you'll want to test it to see if it
> actually works, so here's a sample tester:
>
> /* ------------------------ Begin Source File: main.c
> ------------------------------ */
> #include <stdio.h>
> #include <stdint.h>
>
> #include "data_acc.h"
>
> uint_fast8_t fat_array[42];
>
> int main(void)
> {
> uint_fast16_t i;
>
> uint_fast8_t chunk_value =3D 0;
>
> puts("Filling the fat array...\n");
>
> for (i =3D 0; 42 !=3D i; ++i)
> {
> fat_array[i] =3D chunk_value++;
>
> chunk_value %=3D 4;
> }
>
> puts("Filling the skinny array...\n");
>
> for (i =3D 0; 42 !=3D i; ++i)
> {
> SetChunk(i,fat_array[i]);
> }
>
> puts("Comparing the two...\n");
>
> for (i =3D 0; 42 !=3D i; ++i)
> {
> if (GetChunk(i) =3D=3D fat_array[i])
> printf("Equal. Value =3D %u\n",(unsigned)fat_array[i]);
> else
> puts("ERROR");
> }
>
> return 0;}
>
> /* ------------------------ End Source File: main.c
> ------------------------------ */
>
> So that's it.
>
> I've written this post to show an example of fully-portable code, that
> is, code that will behave exactly as intended on every conceivable
> implementation of the C89 standard.
>
> Of course, people will give examples of more complicated algorithms,
> things like encryption, and I will admit that these things are more
> complex to implement portably, but not impossible.
>
> In C, the "unsigned char" type has no padding bits and thus it allows
> you full access to a contiguous piece of memory, and therefore it can
> be used to do whatever the you want with memory. At times, this can be
> the key to implementing fully-portable code.
>
> If you're working with a machine such as an Intel PC and you're
> writing an encryption algorithm, then it probably is more efficient to
> make assumptions about the size of a byte, about the lack of padding
> in integer types -- and these non-portable assumptions will probably
> lead to more efficient assembler, but with that said, portable
> programming in C is not impossible.
>
> So far, I've had a few people contest my claim of writing fully-
> portable C code. Most of these people also took the opportunity to
> attack me personally instead of focusing on the discussion. I did not
> write this thread for those people; I wrote this thread in the hope of
> enlightening the friendly, polite people about fully-portable C
> programming, and also to rest any doubts they had about me not being
> capable of it.
>
> And lastly, but certainly not least, I'm not infallible. I've checked
> over the above code a few times, but I haven't actually sat down and
> gone thru it with a fine-tooth comb. If there's any errors or
> oversights, please feel free to (politely) point them out to me.
>
> Let's hope this doesn't start a flame.
I don't think I get it. It is my understanding that this is supposed
to be portable microcontroller code. Alright, what are printf and puts
doing in main? Who said there was a screen to print to? That won't
work on my embedded AVR app.
In fact, where does your code have any interface with the outside
world? Where do you read or set the current status of the LED's you
talk about? Wouldn't this require reading and writing a register,
which is inherently specific to a platform? Do you want to use a UART
to send those messages in the printf and puts? Maybe there are two to
choose from. It seems to me that as soon as you want to interface to
the outside world in an embedded app, you need to do something that is
device-specific. Doing things internally, with no external visibility
and no way to talk to the rest of the system, and saying its portable
is not very useful.
Am I missing something?
Dave
In article <a333380f-7a7c-4a1c-853b- 2...@k1g2000prb.googlegroups.com>, m...@linnix.info-for.us says... > On May 13, 10:08=A0am, Vladimir Vassilevsky <antispam_bo...@hotmail.com> > wrote: > > Everett M. Greene wrote: > > > Vladimir Vassilevsky <antispam_bo...@hotmail.com> writes: > > > > >>Tom=3DE1s =3DD3 h=3DC9ilidhe wrote: > > > > >>>In my most recent embedded project, there was a severe memory > > >>>restriction. I had to store in memory the state of 42 individual > > >>>LED's. Each LED could have one of three states. > > > > >>Hence there is a minimum of 67 bits. But this will require heavy weig= ht > > >>arithmetics. > > > > >>>To use the least > > >>>amount of memory possible for each LED, I thought I'd go with the > > >>>following strategy: > > > > >>>* Use three bits per LED. 00 =3D Off. 01 =3D Red. 10 =3D Unused. 11 = =3D > > >>>Green. > > > > >>:)))) > > > > >>Combine the state of five leds into one byte. That totals to eight by= tes > > >>plus four bits for the remaining two leds =3D 68 bits. > > >>[...] > > > > > Somebody is using strange arithmetic. =A0At a minimum, using the > > > state encoding prescribed, you need two bits per LED. > > > > 3^5 =3D 243. Hence the state of five LEDs can be packed into one byte. > > > > > =A0Assuming > > > 8-bit bytes, four LED's states can be packed in one byte. =A0The > > > states for 42 LEDs can then be packed in 11 bytes or 88 bits. > > > > But this is very dull. > > >=20 > Even if the code is perfect, it's lots of overhead to save a few > bytes. All these discussions of saving a few pins and bytes are just > meaningless. Precisely, unless you were making a toy and probably for this using=20 a 4 bit processor or for that matter for this type of application possibly even a _SMALL_ ASIC with register files not RAM to facilitate more direct driving of LEDs. This level of bit stuffing makes the program overheads of sorting out what is where, horrendous and more difficult to follow. Simpler arrays or even arrays of Red and Green LED settings would only be 12 bytes for two arrays of=20 =09Byte of seven bits for a row (of ONE colour LED) =096 bytes gives the 6 rows This array is internal to the game logic and portable across many=20 platforms. As it only uses 7 bits will work if char is by default signed or unsigned. Empty or used positions are determined by simple OR logic. Simple AND function determines an error of both arrays cannot have same bit set. Whatever method is used finding adjacent four bits in any direction needs work. However an array of individual colours/players is easier to scan (Software or Hardware). If array was transposed to be=20 =09Byte of 6 bits for a column (of one colour LED) =097 bytes gives the seven columns Other tricks can be employed by using a shifting pattern OR then AND, repeat for easy masking with existing array for simulating by LEDs the counter falling into the column. Checks for four adjacent values in a byte is a loop with a shifted AND mask and compare. The SAME masks get used for EACH player onto different arrays. All of this is I/O INDEPENDENT. All of this keeps things portable, understandable maintainable for the game play. Note that the maximum in use is 14 bytes, not a lot=20 more than some of the touted methods of 11, 12 or less=20 bytes. So the data storage reduction for the 'portable' section of the code offered, adds a lot of overhead for very little gain, if anything=20 a BIG loss. If this was then done in hardware by multiplexing the=20 LEDs I would then multiplex the LEDs by reading as=20 wide as possible either the Red array then the Green array, or both Red and Green at same column or row. This way you can incorporate a simple startup "Lamp Test" by having the ability to fill both arrays with 1's to multiplex all LEDs, or with time delays=20 rows or columns at a time. Tomas could do well to get hold of the book "Front Panel" which discusses things like Model View and Controller to observe how others do things efficiently. --=20 Paul Carpenter | p...@pcserviceselectronics.co.uk <http://www.pcserviceselectronics.co.uk/> PC Services <http://www.pcserviceselectronics.co.uk/fonts/> Timing Diagram Font <http://www.gnuh8.org.uk/> GNU H8 - compiler & Renesas H8/H8S/H8 Tiny <http://www.badweb.org.uk/> For those web sites you hate
Tomás Ó hÉilidhe schrieb: > Well you do make a good point about picking a better microcontroller, > but then again if I wanted to mass-produce 17 million devices, I'd > probably like to pick a cheaper micrcontroller if it can do the job > just as well as the more expensive microcontroller. True.. Absolutely right. If you can save 10 cent per device you're the hero. No argument against that. However the point is, that you don't build 17 million devices. You've build a connect-four game with one µC before and you have cross-compiled the same code on your pc. Those guys who got into the position to decide what µC to use for such bulk-jobs *know* what they're doing because they have many years of experience behind their belt. Mate, I don't want to depress you. There's nothing bad in knowing the C-standard after 6 years and beeing a good programmer and all, but experience is just what it is: Experience. You can't replace by having read a book or two. Or beeing the best in your class. Neither you can't win a c-standard flame-war here. Honestly, even if you're prepared it's a fight you cannot win (have you even googled against the names whom you've discussed here? You might be surprised). I don't thing noone has bad feelings about you. Relax, chill down and take it easy. Nils Btw - something for you to think about: I suggest you do a ego-google search on your own name once in a while and read what the first two pages tell other people about you. That's exactly what employers and contractors do these days before they invite for interviews. Beeing easy and nice and willing to lern from the old farts is fine. Arguing against them just for the sake and fun of it is not... (said the main who's ego-google history ain't that clean either.. I do like a good flamewar!)
Tomás Ó hÉilidhe wrote: > On May 13, 6:56 pm, linnix <m...@linnix.info-for.us> wrote: > >> I am not the only one saying that your ideas are misguided. You are >> picking the smallest uC and trying to show what you can do with it. > > > I'm picking the PIC16F684 because it's the only one I'm familiar with, > it's the one I've been using in my college course. I think you just made my point for me. If you've only worked with one processor and one tool chain, then you have absolutely no clue of what it takes to write portable code. You may have loads of book learning, but until you've scraped your knees on at least a half a dozen processors you simply don't have the experience needed to write code that's portable in the real world. Trust me, after you've tried writing 'portable' code that'll work across half a dozen processors you'll realize just how embarrassed you should be to even _think_ of claiming to write portable code when you've only written code for one processor (and I bet on only one tool chain, for that matter). -- Tim Wescott Wescott Design Services http://www.wescottdesign.com Do you need to implement control loops in software? "Applied Control Theory for Embedded Systems" gives you just what it says. See details at http://www.wescottdesign.com/actfes/actfes.html
Tomás Ó hÉilidhe wrote: > Well you do make a good point about picking a better microcontroller, > but then again if I wanted to mass-produce 17 million devices, I'd > probably like to pick a cheaper micrcontroller if it can do the job > just as well as the more expensive microcontroller. The problem with that argument is that you're clearly in a situation where the cheaper micro you have _cannot_ do the job just as well. A bigger micro would do the job a whole lot better than a small micro jumping through all those hoops you're discussing. > And don't forget the enjoyment and educational value I'm getting from > working with limited resources. That's actually just about the *only* value there is in those games.
In article <9a6acb81-e927-4685-ab0f- 7...@b64g2000hsa.googlegroups.com>, t...@lavabit.com says... > On May 13, 7:29=A0pm, linnix <m...@linnix.info-for.us> wrote: >=20 > > > I find it interesting to use one sole pin in > > > conjunction with an A-to-D in order to take input from 7 different > > > push buttons. > > > > You can read 1024 levels with build-in A2D converters, but that's not > > the typical way to handle buttons either. >=20 >=20 > I've got 7 push buttons. My old design was that I fed these into a > 74HCT148 encoder which had 3 output pins, and so my uC needed 3 input > pins available in order to see if a button was pressed. (The buttons > in my Connect4 game appear under the columns of LED's. If you press > the button under Column 3 then a chip will fall into that column. Why? For a game at this level I would use TWO buttons =09SHIFT=09Cycle through columns lighting or flashing the TOP most =09=09LED of the right colour in the next available column. =09=09Cycle back to beginning. =09SELECT Go in that column =20 > Anyway someone suggested to me about using the A2D converter so that I > only needed _one_ input pin. Do you think this is a good way of going > about it? The uC I'm using, the PIC16F684, has a 10-Bit A2D. >=20 >=20 > > > So yes, you're right to a certain extent, we can just pick better > > > uC's, but I'm liking the discussions pertaining to being "clever" wit= h > > > pins. > > > > And you are using additional logic chips to do it. =A0You think PCB > > areas are free? >=20 >=20 > For some of the tricks, I am using additional logic chips. For > instance I'm using a shift register for the display multiplexer. For > other tricks, such as using the A2D for the push buttons, I'm actually > getting rid of chips I don't need. >=20 > Of course though there's a trade off. I mean if I were to discard the > shift register, then I'd need 84 I/O pins on my uC for the display, > and maybe it's cheaper to instead get a shift register and a uC with > 12 I/O pins. You could just multiplex and even an external decoder for column muxing. This could be used for switch muxing as well. =097 columns of Red =097 Columns of Green Oh look 14 decodes, or 14 shifts of a column driving of 6 outputs. Careful timing makes it possible to turn the outputs all off just before a column change, avoid decode glitches. Reading back a common switch line would enable upto 14 switches to be read! The 6 outputs could still be done by a shift register, and using things=20 like 74HC595 and monitoring the overflow output would enable all sorts of pin reduction. I think you are making things complicated, unnecessarily. --=20 Paul Carpenter | p...@pcserviceselectronics.co.uk <http://www.pcserviceselectronics.co.uk/> PC Services <http://www.pcserviceselectronics.co.uk/fonts/> Timing Diagram Font <http://www.gnuh8.org.uk/> GNU H8 - compiler & Renesas H8/H8S/H8 Tiny <http://www.badweb.org.uk/> For those web sites you hate
Hans-Bernhard Bröker schrieb:
>> And don't forget the enjoyment and educational value I'm getting from
>> working with limited resources.
>
> That's actually just about the *only* value there is in those games.
Be easy with him. That's a damn good opportunity to learn a lot of things!
Not beeing forced to come up with the most obvious or cheapest solution
but to think a bit out of the box is a luxury that only students (and
sometimes the R&D-guys as well) have.
Nils