Inspired by Robert Ray and his KFC, Kentucky Fried Chicken project, I decided to develop my own version and 3D print it.
The model is based on images found on internet and is modeled using Fusion 360. The model is divided into several parts, so painting will be more easy.
The sign with the bucket has light and will rotate, using a motor with gear. The KFC store is illuminated using a LED Filament Lamp.
The model, with the different LED's and motor, are controlled by a microcontroller.
The KFC video(turn on sound)
Searching the net, I found several images of the KFC store, including a catalog image showing the KFC standard store in 1970-1980. Based on this, I developed the model. Hopefully the proportions are correct, so the model looks good.
The 3D-model is created in many pieces, so its easy to paint the different parts before they are glued together.
The model is divided into several parts for easy painting and assembly.
Item |
Part Number |
Description |
1 |
KFC-B-1 |
Main structure of building |
2 |
KFC-F1 |
Front columns and beams |
3 |
KFC-B1-1 |
Baldakin Roof 1 |
4 |
KFC-B2-2 |
Baldakin part, transparent resin |
5 |
KFC-R1-2 |
Roof Tower over shop |
6 |
KFC-R1-1 |
Roof over shop |
7 |
KFC-WI1 |
Wall between shop and kitchen |
8 |
KFC-R2-1 |
Roof over kitchen |
9 |
KFC-HVAC1 |
Roof Ventilation Unit |
10 |
Utilitypipes |
Gas/Electricity Equpment |
Many parts
IC PCB containing a WS2811 Constant Current RGB LED driver, where you can connect individual standard LED's to each of the 3 output, to drive standard LED's. No resistor is necesarry, it will output 3 Volt, 16.5 mA on each output.
The LED Filament is used behind the transparent holder for the KFC sign, giving an uniform and very nice light source.
The big KFC sign have 2 pc of 0402 LED's mounted inside a slot in the sign with the wires in the 2.0 mm pipe at the right side of the image. The sign is printed with transparent resin and the slot is filled with transparent resin and hardened with UV light, giving a solid, transparent body so the light is distributed inside the sign.
In the sign I constructed a slot to insert the LED's and wires. I used clear resin and filled the slot with resin after inserting the LED's. Using a infrared light source hardened the resin in seconds. Some sanding and the sign was ready for the graphics.
On top of the sign, the KFC bucket rotate, using a motor with a gear. The speed can be adjusted.
Inside the bucket there is a 0402 LED to lighten up the bucked. The pipe that holds the signs and bucket, are constructed using 3 different brass pipes, 1.0 mm, 1.5 mm and 2.0 mm. The 1.0 mm pipe holds the LED and the wires for the LED. The 1.5 mm pipe rotate the attached bucked and the 2.0 mm pipe hold the other pipes.
The model is printed using my Anycubic Photon Mono 3D-printer, using different resins, colored and transparent. Many of the parts are printed flat on the bed, with many supports added manually. I use the LycheSlicer to prepare the model for printing.
The model is created in real size, scale 1:1. Then the model can be printed in different scales, and not only in 1:220.
Using a microcontroller, like an Arduino type of microcontroller or similar. I have used an ATTINY85, and it works great. Using the microcontroller let you easy control light effects and the speed of the motor.
In the KFC model there are one adresseable LED unit and 2 WS2811 LED drivers, controlling the lights for the sign, one Edison filament LED and one 0402 LED to create the flickering effect to simulate a faulty light tube.
The lights can be turned on/off with a switch and the motor is activated with a movement sensor(PIR-sensor) so the motor is running for a predefined time, like 60 seconds.
Since several thing shall happen at the "same time", I use a State Machine using millis() to simulate the flickering tube.
The Microprosessors
The schematic is created using the electronic schematic part of Fusion 360. Its a complete electronic solution, including the schematic I have used and PCB layout and PDB 3D modeling, used for prototype modeling.
Below an example of the code developed for this project, using an ATTINY85.
Copy Code to ClipBoard
// KFC_restaurant by Svein-Martin Holt, platelayer.com, version 0.1, 2022.12.11
/*
Adresseable LED's used to light the KFC shop interior, the baldakin sign, the signs and the rotating bucket.
Motor running the rotating bucket.
PIR sensor or switch to start the motor in a preset time, like 5 mins running after last trigged.
This is to prevent the motor to run when nobody are watching the model.
The lights can be turned off with a switch.
Program testet on Arduino UNO and NANO.
Program will run on ATTINY85 module
Digispark Kickstarter Micro Development Board ATTINY85/TINY85 Module for Arduino IIC I2C USB
Digistump homepage: http://digistump.com/products/1
http://digistump.com/wiki/digispark/tutorials/basics
Digispark software: http://digistump.com/wiki/digispark/tutorials/connecting
Seller: https://www.aliexpress.com/item/1005002891615682.html
Type A, internal LED on pin PB1(P1)
Pin outs ATTINY85 module:
All pins can be used as Digital I/O
Pin 0 → I2C SDA, PWM (LED on Model B)
Pin 1 → PWM (LED on Model A)
Pin 2 → I2C SCK, Analog In
Pin 3 → Analog In (also used for USB+ when USB is in use)
Pin 4 → PWM, Analog (also used for USB- when USB is in use)
Pin 5 → Analog In
*/
#include <Adafruit_NeoPixel.h>
#define LED_PIN 5 // Pin connected to the LED'strip RGB parts (P3 on ATTINY85/TINY85 Module )
#define SENSOR_PIN 4 // sensor/switch pin to start motor, LOW activate motor
#define LIGHT_SWITCH 5 // turn on/off lights, LOW turn off lights
#define MOTOR_PIN 1 // 1=P1 PWM1 on ATTINY) PWM pin for motor driver
#define POT_PIN A2 // Potentiometer pin to set motor speed, use pin A2 on Arduino
//#define POT_PIN 2 // (2=P4 ADC2, USB- on ATTINY) Potentiometer pin to set motor speed, use pin2 on ATTINY85 module
//#define flashledPin 13 // internal LED
#define NUMPIXELS 3 // Number of pixels in LED strip
Adafruit_NeoPixel pixels(NUMPIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);
// Set brightness on each channel(R,G,B)
// The main light in the shop is a WS2801 RGB Chip
#define BRIGHTNESS_SHOP_RED 10 // RED LED in Shop 0-255
#define BRIGHTNESS_SHOP_GREEN 20 // GREEN LED in Shop
#define BRIGHTNESS_SHOP_BLUE 10 // BLUE LED in Shop
// Set brightness on individual LEDs driven by IC Chip
#define BRIGHTNESS_BUCKET 20 // Bucket LED 0-255
#define BRIGHTNESS_SIGN2_1 20 // Sign 2, LED 1
#define BRIGHTNESS_SIGN2_2 20 // Sign 2, LED 2
#define BRIGHTNESS_BALDAKIN 50 // Baldakin LED Edison element
#define BRIGHTNESS_FLASH 30 // single LED simulatin light with error
#define TIMER_MOTOR 60000 // timer in milliseconds for bucket motor, running in 1 min after activation
int motor_speed = 0;
bool active_state = false;
byte state = 1;
int ledState = LOW;
unsigned long blinkDelay;
unsigned long lastBlinkMillis = 0;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long resetMotorMillis = 0;
int bright_led = BRIGHTNESS_FLASH;
unsigned long STATE_MOTOR_RUN = 0; // 1: Motor running, 0: Motor stop
unsigned long STATE1_TIME; // time flashing
unsigned long STATE2_TIME; // time pause flashing
void setup() {
pinMode(POT_PIN, INPUT); // motor speed
pinMode(SENSOR_PIN, INPUT_PULLUP); // pir sensor OBS: INPUT_PULLUP does not work on ATTINY85/TINY85 Module so a dropdown resistor must be added to the line.
pinMode(LIGHT_SWITCH, INPUT_PULLUP); // light switch
//pinMode(flashledPin, OUTPUT);
pinMode(MOTOR_PIN, OUTPUT); // Motor PWM pin
analogWrite(MOTOR_PIN, 0); // set motor off
pixels.begin(); // INITIALIZE NeoPixel strip object
pixels.clear(); // Set all pixel colors to 'off'
pixels.show();
delay(1000);
}
void loop() {
set_LEDs_ON(); // turn all LEDs on
flashing_light(); // flash ledstrip/ligths
/* if (digitalRead(LIGHT_SWITCH) == HIGH) {
set_LEDs_ON(); // turn all LEDs on
flashing_light(); // flash ledstrip/ligths
} else {
set_LEDs_OFF(); // turn all LEDs off
}
*/
if (digitalRead(SENSOR_PIN) == LOW) { // SENSOR_PIN LOW turn on the motor
STATE_MOTOR_RUN = 1; // Bucket Motor running
resetMotorMillis = millis() + TIMER_MOTOR; // set stop time for motor
}
if (millis() > resetMotorMillis) { // turn motor off
STATE_MOTOR_RUN = 0;
}
// read potmeter value
motor_speed = map(analogRead(POT_PIN), 0, 1023, 0, 255);
// motor_speed = 45;
if (STATE_MOTOR_RUN) {
// set motorspeed
analogWrite(MOTOR_PIN, motor_speed); // set motor speed
// digitalWrite(flashledPin, HIGH);
} else {
analogWrite(MOTOR_PIN, 0);
// digitalWrite(flashledPin, LOW);
}
}
void set_LEDs_ON() {
//Set all LED's in shop and signs
pixels.clear(); // Set all pixel colors to 'off'
// pixels.Color() takes RGB values, from 0,0,0 up to 255,255,255
// RGB LED in shop
pixels.setPixelColor(0, pixels.Color(BRIGHTNESS_SHOP_RED, BRIGHTNESS_SHOP_GREEN, BRIGHTNESS_SHOP_BLUE)); // SHOP RGB LED
// RGB driver: R: Baldakin LED, G: flash LED, B: not used
pixels.setPixelColor(1, pixels.Color(BRIGHTNESS_BALDAKIN, bright_led, 0)); // Baldakin and flash LED's. Blue is not used.
// 1 LED in bucket and 2 LEDS in sign
pixels.setPixelColor(2, pixels.Color(BRIGHTNESS_BUCKET, BRIGHTNESS_SIGN2_1, BRIGHTNESS_SIGN2_2)); // sign and bucket LED's
// pixels.setPixelColor(2, pixels.Color(BRIGHTNESS_BUCKET, BRIGHTNESS_SIGN2_1, 255)); // sign and bucket LED's
pixels.show(); // Send the updated pixel colors to the hardware.
}
void set_LEDs_OFF() {
//Turn off all LED's in shop and signs
pixels.clear(); // Set all pixel colors to 'off'
pixels.show();
}
void ledBlink() {
currentMillis = millis();
if (currentMillis - lastBlinkMillis >= blinkDelay) {
// save the last time you blinked the LED
lastBlinkMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
ledState = !ledState;
// set the LED with the ledState of the variable:
if (ledState) {
bright_led = BRIGHTNESS_FLASH;
} else {
bright_led = 0;
}
pixels.setPixelColor(1, pixels.Color(BRIGHTNESS_BALDAKIN, bright_led, 0)); // Baldakin and flash LED's. Blue is not used.
pixels.show();
// generate new random delay
blinkDelay = random(500);
}
}
void flashing_light() {
currentMillis = millis();
switch (state) {
case 1: // flashing mode
if (currentMillis - previousMillis >= STATE1_TIME) {
previousMillis = currentMillis;
STATE1_TIME = random(2000, 6000); // flash time, 2-6 sek
state = 2; // turn on pause
}
break;
case 2: // pause mode
if (currentMillis - previousMillis >= STATE2_TIME) {
previousMillis = currentMillis;
STATE2_TIME = random(2000, 4000); // pause time, 2-4 sek
state = 1; // turn on flashing
}
break;
}
if (state == 1) { // state=1, flashing led
ledBlink();
}
}
All the different pieces used in this project are available online. Below you will find a listing of some of the items: