Improved Logic Gates.

I've Decided i'm going to write (feel free to join in or offer advice) a Series of firmwares that turns an
ATTiny45/85 (8 pin dip) into that Missing Logic Gate you need.

I'm going to be doing it in this order.

XOR - Finished (Completed)
AND
OR
NOT (Hex/Inverter)
NAND
NOR

..Please add any i missed.

http://www.kpsec.freeuk.com/gates.htm

I'm Emulating the 4000 series.

Once i've written them i'll zip them up and post them for all to use.

Meanwhile, i'll post each routine as i finish them in this thread

The code to emulate the EXOR (Exclusive or logic gate)

//Logic Attiny45/85 Emulated Gates 4XXX series.

/* Instructions
  1. Upload the ISP sketch to an Arduino board.
  2. Program the attiny accordingly.
  3. Upload this sketch via Aruduino as ISP
*/

//Arduino Emulating a Logic EX-OR (Exclusive-OR)
//I Plan on doing a library of these, either to temp replace
//a faulty IC, or to improve on one..
//for example, No need to tie these pins down with pull up/down resistors
//add extra functionality of logic

//This Code is for an XOR (Exclusive OR) 

void setup() 
{
  // put your setup code here, to run once:
  pinMode(4,INPUT);  // pin 3
  pinMode(3,INPUT);  //pin 2
  pinMode(0,OUTPUT);  //pin 5  (this is your Logic HIGH/LOW)  
}

void loop() 
{  
  boolean Status1 = digitalRead(3);
  boolean Status2 = digitalRead(4);  
  if (Status1==Status2) 
      digitalWrite(0,LOW); 
     else
   {  
   if ((Status1==HIGH) || (Status2==HIGH)) 
     {
       digitalWrite(0,HIGH);  //Your Logic Result on Pin 5       
       //add a delay for example, stuff 4070 can only dream of :D... 
       //delay(400);
       //or analogWrite, make it Fade in and Out!
     }
      else
        digitalWrite(0,LOW);
   }  
}

I Hope this has not been done before, if it has here's my take on it, I'm sure there's probably much much elegant and efficient ways to do what i'm
doing right now and i'm sure people will.. but it's not exactly calculating pi to a 1k billion places or operating anything time critical, i'm merely using
Attiny85's at 1mhz or 8mhz internal oscillator.

If you find it useful, eg to replace a dead logic gate chip with one of these as a short term fix, please do.

The Code to Emulate the AND logic gate in 8 pin DIP form [edit, fixed, only outputs High when BOTH are HIGH

/* Instructions
  1. Upload the ISP sketch to an Arduino board.
  2. Program the attiny accordingly.
  3. Upload this sketch via Aruduino as ISP
*/

//Arduino Emulating a Logic AND gate
//I Plan on doing a library of these, either to temp replace
//a faulty IC, or to improve on one..
//for example, No need to tie these pins down with pull up/down resistors
//add extra functionality of logic

void setup() 
{
  // put your setup code here, to run once:
  pinMode(4,INPUT);  // pin 3
  pinMode(3,INPUT);  //pin 2
  pinMode(0,OUTPUT); //pin 5  (this is your Logic HIGH/LOW)  
}

void loop() 
{  
  boolean Status1 = digitalRead(3);
  boolean Status2 = digitalRead(4);
    if ((Status1==HIGH) && (Status2==HIGH))
     { 
          digitalWrite(0,HIGH);  //Your Logic Result on Pin 5       
       //add a delay for example
       //delay(400);
     }
      else
        digitalWrite(0,LOW);
}

I suspect your AND will return HIGH if both inputs are HIGH or both inputs are LOW
not sure that's what I'd expect

the comments in setup are confusing
pinMode(4,INPUT); // pin 3
pinMode(3,INPUT); //pin 2
pinMode(0,OUTPUT); //pin 5

a) I would use #defines
b) why don't the numbers match!

IMOH
YMMV

This code emulates an OR logic gate.

/* Instructions
  1. Upload the ISP sketch to an Arduino board.
  2. Program the attiny accordingly.
  3. Upload this sketch via Aruduino as ISP
*/

//Arduino Emulating a Logic OR gate
//I Plan on doing a library of these, either to temp replace
//a faulty IC, or to improve on one..
//for example, No need to tie these pins down with pull up/down resistors
//add extra functionality of logic

void setup() 
{
  // put your setup code here, to run once:
  pinMode(4,INPUT);  // pin 3
  pinMode(3,INPUT);  //pin 2
  pinMode(0,OUTPUT);  //pin 5  (this is your Logic HIGH/LOW)  
}

void loop() 
{  
  boolean Status1 = digitalRead(3);
  boolean Status2 = digitalRead(4);  
   if ((Status1==HIGH) or (Status2==HIGH)) 
     {
       digitalWrite(0,HIGH);  //Your Logic Result on Pin 5       
       //add a delay for example
       //delay(400);
     }
      else
        digitalWrite(0,LOW);
}

mmcp42:
I suspect your AND will return HIGH if both inputs are HIGH or both inputs are LOW
not sure that's what I'd expect

the comments in setup are confusing
pinMode(4,INPUT); // pin 3
pinMode(3,INPUT); //pin 2
pinMode(0,OUTPUT); //pin 5

a) I would use #defines
b) why don't the numbers match!

IMOH
YMMV

Originally, I wired it up completely different to use different pins then changed my mind to use a PWM channel over a standard Pin out.
Defines... yes but i've really not delved that far into the language yet.

As for the AND gate

Cool, i'll fix it cheers

try

#define INPUT_PIN1 3
#define INPUT_PIN2 4
#define OUTPUT_PIN 5

pinMode(INPUT_PIN1, INPUT);
pinMode(INPUT_PIN2, INPUT);
pinMode(OUTPUT_PIN, OUTPUT);

has the side benefit that if you change pins, you have one line to change :slight_smile:

Ahh "Why don't the numbers match"

Pin5 is Pin0 on an Attiny85.

cjdelphi:
Ahh "Why don't the numbers match"

Pin5 is Pin0 on an Attiny85.

tru enough
but either talk real pins or logical pins or expand the comment!

The NOT/Inverter code... not entirely sure it will work, not had chance to test it (yes it compiles)

/* Instructions
  1. Upload the ISP sketch to an Arduino board.
  2. Program the attiny accordingly.
  3. Upload this sketch via Aruduino as ISP
*/

//Arduino Emulating a Logic NOT gate
//I Plan on doing a library of these, either to temp replace
//a faulty IC, or to improve on one..
//for example, No need to tie these pins down with pull up/down resistors
//add extra functionality of logic

void setup() 
{
  // put your setup code here, to run once:
//  pinMode(4,INPUT);   //pin 3 add an extra not gate?
//  pinMode(1,OUTPUT);  //Logic OUT pin 6

  pinMode(3,INPUT);   //pin 2
  pinMode(0,OUTPUT);  //pin 5  (this is your Logic HIGH/LOW)  
}

void loop() 
{  
  boolean Status1 = digitalRead(3);
  digitalWrite(0,!Status1);  //Your Logic Result on Pin 5         
}

Here's what i've done so far.

P.S it's my birthday today, be nice, please.... It was just a thought I had... modify the code as wil.

AttinyLogicGates.zip (3.64 KB)

Happy Birthday cjdelphi.

I dont know the Tiny pins, but after reading inpute A and B, output C would be :-

for OR, C = A||B

for AND, C = A && B

for ecl OR, C = ( A && ! B ) || ( B && !A )

But replacing a fauly 4000 chip with a micro is a bit expensive ?

Boffin1:
But replacing a fauly 4000 chip with a micro is a bit expensive ?

Thanks for the birthday wishes :slight_smile:

  • yes it would be expensive, but i was thinking more along the lines of "uh oh, this circuit requires a whatever logic gate" - you don't have one but if there's a library
    full of emulated logic chips, while you're waiting for the shop to open or ebay to send the chip, why not program a small unused attiny to do the job for you? until you
    get one...

Esp if you're learning about logic chips and don't actually want to buy any....

Maybe

digitalWrite(0, !digitalRead(3));

For NOT.

I'd also think about using direct port manipulation to make these "gates" faster.

EDIT: f'example, an AND function

switch (PINB & 3) {		// assumes inputs on bits 0 and 1

	case 0:
	case 1:
	case 2:
		PORTB &= ~(1 << 2);	// assumes outputs on bit 2
		break;
		
	case 3:
		PORTB |= (1 << 2);
	
}

I haven't checked which bits are which, just an example.


Rob

You cant get more direct port manipulation the CD4000 logic Rob :slight_smile:

I actually looked through my shoebox of chips yesterday, mostly 4000 series, and I felt as guilty as I do when I havn't taken the dog for a walk for a while !

I used CMOS all the time until Arduino stole my heart ...................

  boolean Status1 = digitalRead(3);
  boolean Status2 = digitalRead(4);
    if ((Status1==HIGH) && (Status2==HIGH))
     { 
          digitalWrite(0,HIGH);  //Your Logic Result on Pin 5       
       //add a delay for example
       //delay(400);
     }
      else
        digitalWrite(0,LOW);
  1. define the input / output pins somewhere so your program is more portabe;
  2. you can easily rewrite that to this:
#define AND(x, y) (digitalRead(x) && digitalRead(y))

...
  digitalWrite(OUTPUT_PIN, AND(INPUT_PIN1, INPUT_PIN2)); //output and of pin1/pin2 on output pin

You can implement other functions similarly.

  1. things like this have very limited uses: the test is done only when that line was executed. So a transistion when that line isn't executed will be missed - I would use an interrupt for sure.

I guess it's one way to get a simple logic function, but feels like overkill to me. Wouldn't it be more satisfying to make your own 'logic gates' from discrete components and wire them up to a plug with the form factor you want?

Firstly you can use & and | rather than && and || (which may compile to conditional tests and jumps rather than
ALU operations). digitalRead() returns 0 or 1 (== LOW or HIGH), guaranteed.

Secondly for a flexible gate definition use table look-up - then the actual logic function depends on
the table values (for a 2-input gate there are 16 possibilities (several of which aren't very useful!).

For speed direct port manipulation is needed really - even then the speed will several 100ns propagation.

It would be great to find a microcontroller that is 14 or 16 pin and which can be programmed to emulate
any of the different 4000 or 7400 chips of that footprint!! In practice often discrete logic chips are chosen
because the speed is needed (otherwise the MCU would be doing the work).

So what you're really trying to do is re-invent the PLA and FPGA.

why not macrofy the code :wink:

#define AND(A,B,O) digitalWrite(0, digitalRead(A) && digitalRead(B))
#define OR(A,B,O) digitalWrite(0, digitalRead(A) || digitalRead(B))
#define NOT(A,O) digitalWrite(0, !digitalRead(A))
// etc

void setup()
{
...
}

void loop() 
{  
  AND(1,2,3);
}

Thanks MarkT,

Firstly you can use & and | rather than && and || (which may compile to conditional tests and jumps rather than
ALU operations). digitalRead() returns 0 or 1 (== LOW or HIGH), guaranteed.

I am not there yet ( my cheat sheet shows & as Pointer access and Bitwise operators )

The other point is that a hardware version is OK in a 12v or whatever circuit !