PIC RC motorcontroller (en voorbeeld lego robot) (2 / 6 stap)

Stap 2: Software


Deze stap zal gaan door elk onderdeel van de software en uitleggen wat het doet. Als u geen belang hebben bij de aanpassing van de software en wil gewoon om te bouwen van het ding, kan je op naar de volgende stap. Het hex bestand zal het project werken zoals ontworpen.

Fundamentele configureation van chip periferials
#pragma config OSC = INTIO2, WDT = OFF, LVP = OFF
#include < p18f1320.h >

Dit stelt de oscillator op interne en laadt de instellingen voor de 18F1320, als u wilt gebruiken een andere pic die dit is een van de belangrijkste dingen die u moet wijzigen

Setup pinnen PWM invoerfilter
#define ReceiverPin PORTBbits.RB3
#define ReceiverTris TRISBbits.TRISB3

Dit is gewoon een naam geven aan de pin voor de ontvangst van het signaal, dus het is duidelijker om te verwijzen naar.

PWM vangen variabelen
unsigned int PWM1RiseTime = 0; timer waarde aan stijgende rand vastleggen
unsigned int PWM1FallTime = 0; timer waarde bij dalende rand beleg
unsigned int PWM1Width = 0; berekende breedte

unsigned int CH1_width = 0;
unsigned int CH2_width = 0;
unsigned int CH3_width = 0;
unsigned int PWMGap = 0; berekende kloof tussen pulsen

char PWM1Edge = 1; rand 1 momenteel wordt gecontroleerd = stijgende, 0 = vallen

knop variabelen
unsigned char button_1_debounce_wait = 0;

Aangezien het PWM-signaal van de ontvanger communiceert door verzendende pulsen van wisselende breedte variabelen verklaard deze breedtes houden zodra ze worden berekend.

unsigned char calibration_mode = 0;
#define mode_operate 0
#define mode_CH1_high 1
#define mode_CH1_med 2
#define mode_CH1_low 3
#define mode_CH2_high 4
#define mode_CH2_med 5
#define mode_CH2_low 6

unsigned int limit_CH1_high = 2381;
unsigned int limit_CH1_med = 3307;
unsigned int limit_CH1_low = 4286;

unsigned int limit_CH2_high = 2022;
unsigned int limit_CH2_med = 2946;
unsigned int limit_CH2_low = 3983;
unsigned int CH_temp = 0;

Wanneer de kalibratie-modus is op het systeem zal worden resetten van deze "limieten" om aan te passen van het signaal. Dit zijn de standaardwaarden, hoe de kalibratie werkt zal later worden verklaard.

motorische controle variabelen
#define Motor_PWM_Rez 16 //number als verschillende snelheden mogelijk voorwaartse en omgekeerde
#define center_buffer 20 //this is de breuk van het bereik voordat beweging begint

Dit zijn de constanten die u aanpassen kunt als u met verschillende delen. De center-buffer is echt de dode zone in het midden waar de controller de motor ken om het even wat maken zal. De rezolution is hoeveel verschillende snelheden, het systeem zal verdelen het bereik van de controle in.

unsigned char Motor_Phase = 0; //as het cycli dit zal tijd de motoren

unsigned int CH1_range = 2000;
unsigned char Motor_A_Speed = 0; Dit is de snelheid van de motor A, het zal gelijk zijn aan de rezolution 100%
unsigned char CH1_forward_increment = 10; //the breedte van bereik voor elke uitvoer snelheid
unsigned char CH1_reverse_increment = 10;

unsigned int CH2_range = 2000;
unsigned char Motor_B_Speed = 0; Dit is de snelheid van de motor A, het zal gelijk zijn aan de rezolution 100%
unsigned char CH2_forward_increment = 10; //the breedte van bereik voor elke uitvoer snelheid
unsigned char CH2_reverse_increment = 10;

typedef struct
{
niet-ondertekende motor_A_Direction: 1;
niet-ondertekende motor_B_Direction: 1;
niet-ondertekende button_1_last_state: 1;
} BITS;

unsigned char motor_A_inverted = 1; //this aan kalibratie gerelateerde
unsigned char motor_B_inverted = 1;
unsigned char motor_calibration_needed = 1;

vluchtige BITS Bits;

timing variabelen
unsigned char slow_count = 0; Dit wordt gebruikt om het maken van de geschaalde timer voor langzamere evenementen

De bovenstaande variabele zal gewoon een teller zodat een subsectie van de timer onderbreken alleen eenieder uit vele timer teken kan afgaan.

interrupt instellen
VOID low_ISR (void); //prototype
#pragma code low_vector = 0x08 //0X08 IS laag 0X18 IS hoog
VOID low_interrupt (void) {}
_asm goto low_ISR _endasm
}
#pragma code
#pragma interrupt low_ISR

Dit deel is niet de interrupt op zich maar het set up voor de interrupt optreden. De interrupt is gewoon een gebeurtenis waarmee iets te worden geactiveerd, zodat het programma niet hoeft te worden een grote lus.

void main(void)
{
OSCCON = 0X72; 8MHz klok
terwijl (!. OSCCONbits.IOFS); Wachten op OSC tot stabiele

configureren van timer1
PIR1bits.TMR1IF = 0; Hiermee wist u de timer 1 onderbreken vlag
T1CONbits.TMR1ON = 1; inschakelen van de timer
T1CONbits.T1CKPS1 = 0; prescaler instellen
T1CONbits.T1CKPS0 = 0; prescaler instellen

installatie timer2
PIR1bits.TMR2IF = 0; Hiermee wist u de timer 2 onderbreken vlag
PIE1bits.TMR2IE = 1; de interrupt inschakelen
PR2 = 199;
T2CON = 0b00000100; (-) altijd 0 (-) postscale (-) aan/uit (-) prescale

CCP1 configureren
CCP1CON = 0b0000101; configureren van CCP1 voor het vastleggen, stijgende rand
INTCONbits.PEIE=1; inschakelen van perifere interrupts
PIE1bits.CCP1IE=1; CCP1 interrupt ingeschakeld
INTCONbits.GIE=1; inschakelen als u wilt onderbreken vertakking
ReceiverTris = 1; RB3 voor invoer instellen zodat de opname kunt werken.
TRISBbits.TRISB2 = 1; rb2 voor instellenin zodat het kan worden gebruikt om te onderscheiden van de kanalen

De capture module doet al het zware werk hier. Boven deze wordt geïnitialiseerd om te wachten op het signaal te stijgen, later dit verandert dynamisch te vangen pulsbreedte.

poorten configureren
ADCON1 = 0XFF; alle digitale
INTCON2bits.RBPU = 0; poort b zwakke pullups op

Deze zullen motor uitgangen
TRISAbits.TRISA0 = 0;
#define Motor_Pin_A1 LATAbits.LATA0
TRISAbits.TRISA1 = 0;
#define Motor_Pin_A2 LATAbits.LATA1
TRISAbits.TRISA2 = 0;
#define Motor_Pin_B1 LATAbits.LATA2
TRISAbits.TRISA3 = 0;
#define Motor_Pin_B2 LATAbits.LATA3

Deze kunt u instellen dat de pinnen die nodig zijn voor de controle van de motoren om op te treden als uitgang. Dan is de motor pinnen heten voor gemakkelijke toegang.

Deze zullen indicator uitgangen
TRISAbits.TRISA6 = 0;
TRISAbits.TRISA7 = 0;

Dit zal de servo-signaalingang
TRISBbits.TRISB0 = 1;

in eerste instantie het kalibreren van de RC bereiken
motor_calibration_needed = 1;

while(1)
{
}
}

Dit terwijl loops voorkomt dat het programma einde. Laat u niet misleiden door het feit dat het leeg is. Interrupts zal leiden tot gebeurtenissen en de timer is nog steeds actief.

Hieronder is de start van de timer onderbreken. Het afgaat periodiek op de hoogste snelheid die elke functie zijn vereist, voor snelle operaties zoals beslissen als het is tijd om te zetten van de motor in- of uitschakelen, dan is onderverdeeld met tellers te bedienen van de functies die geen dergelijke hoge snelheid vereisen, zoals toezicht op de invoer en te beslissen als de snelheid moet veranderen.

VOID low_ISR(void)
{

Timer 2 vlag (momenteel ingesteld op onderbreken bij 10Khz)
if(PIR1bits.TMR2IF == 1)
{
PIR1bits.TMR2IF = 0; Hiermee wist u de timer 1 onderbreken vlag

Dus wat niet afval tijd doen dingen sneller dan nodig (een goede manier om te kijken naar vele soorten werk) het gedeelte hieronder maakt gebruik van de variabele "slow_count" alleen uitvoeren elke 100 keer de buitenste lus wordt uitgevoerd.

withen deze functie uitvoert op 100 Hz ***
slow_count ++;
if(slow_count > 100)
{
slow_count = 1; //reset tellen voor de volgende keer

Handvat kalibratie knop
if(button_1_debounce_wait > 0) {button_1_debounce_wait--;}
if(PORTBbits.RB0 == 0) {}
Als (Bits.button_1_last_state == 0 & & button_1_debounce_wait == 0) //button enkel gedrukt
{
button_1_debounce_wait = 10; //set debounce graaf
calibration_mode ++;
if(calibration_mode > 6) {calibration_mode = 0;}
}
Bits.button_1_last_state = 1;
}
anders
{
Bits.button_1_last_state = 0;
}
einde van kalibratie knop

Hieronder is de kalibratie daadwerkelijk worden toegepast. Dit gebeurt in de normale werkingsmodus zodat de lichten beide zijn uitgeschakeld. Het programma controleert of het kalibratietraject achterstevoren, hoog lager dan de lage en vice versa is, en zo ja een vlag wordt zo ingesteld dat de richtingen van de motoren dienovereenkomstig zullen handelen.

Omgaan met Led modus indicatoren
if(calibration_mode == mode_operate)
{
LATAbits.LATA6 = 0;
LATAbits.LATA7 = 0;

if(motor_calibration_needed == 1)
{
motor_calibration_needed = 0; markering wissen

kalibratie variabelen voor CH1 herberekenen
if(limit_CH1_low < limit_CH1_high) //speed neemt toe naarmate het aantal toeneemt
{
motor_A_inverted = 0;
}
anders / / snelheid afneemt als er
{
swap hen zo hoog is de grotere waarde
CH_temp = limit_CH1_low;
limit_CH1_low = limit_CH1_high;
limit_CH1_high = CH_temp;

motor_A_inverted = 1;
}

CH1_range = limit_CH1_high-limit_CH1_low;
CH1_forward_increment = (limit_CH1_high-limit_CH1_med--((limit_CH1_high-limit_CH1_med)/center_buffer)) / Motor_PWM_Rez;
CH1_reverse_increment = (limit_CH1_med-limit_CH1_low--((limit_CH1_med-limit_CH1_low)/center_buffer)) / Motor_PWM_Rez;
}

kalibratie variabelen voor CH2 herberekenen
if(limit_CH2_low < limit_CH2_high) //speed neemt toe naarmate het aantal toeneemt
{
motor_B_inverted = 0;
}
anders / / snelheid afneemt als er
{
swap hen zo hoog is de grotere waarde
CH_temp = limit_CH2_low;
limit_CH2_low = limit_CH2_high;
limit_CH2_high = CH_temp;

motor_B_inverted = 1;
}

CH2_range = limit_CH2_high-limit_CH2_low;
CH2_forward_increment = (limit_CH2_high-limit_CH2_med--((limit_CH2_high-limit_CH2_med)/center_buffer)) / Motor_PWM_Rez;
CH2_reverse_increment = (limit_CH2_med-limit_CH2_low--((limit_CH2_med-limit_CH2_low)/center_buffer)) / Motor_PWM_Rez;

}
einde van led modus indicatoren

Onder kalibratie wordt afgehandeld. Telkens wanneer de knop is ingedrukt de kalibratie-modus verandert, die aangeeft dat een nieuwe limiet wordt ingesteld. Het patroon is volledig voorwaarts, CH1 midden rust, volledige achteruit, dan hetzelfde drie posities weer op kanaal twee. De lichte indicatoren voor niet in pronken kalibratie-modus, een op voor forward, de andere voor reverse en zowel voor midden punt rusten. Het is niet een krachtige interface maar het krijgt de klus te klaren.

kalibratie
if(calibration_mode == mode_CH1_high)
{

Al deze LATA spul is gewoon de verlichting wordt ingeschakeld om aan te geven van de modus voor de gebruiker. Zoals u het zien kunt instellen niet eigenlijk de limieten wanneer u de knoop raakt. Het stelt hen gewoon op welke plek ze terwijl in die modus, zijn dus als je duwt de knop weer en die modus eindigt, dat het kalibratiepunt blijft.

LATAbits.LATA6 = 0;
LATAbits.LATA7 = 1;

limit_CH1_high = CH1_width;

}
if(calibration_mode == mode_CH1_med)
{
LATAbits.LATA6 = 1;
LATAbits.LATA7 = 1;

limit_CH1_med = CH1_width;
}
if(calibration_mode == mode_CH1_low)
{
LATAbits.LATA6 = 1;
LATAbits.LATA7 = 0;

limit_CH1_low = CH1_width;
}
if(calibration_mode == mode_CH2_high)
{
LATAbits.LATA6 = 0;
LATAbits.LATA7 = 1;

limit_CH2_high = CH2_width;
}
if(calibration_mode == mode_CH2_med)
{
LATAbits.LATA6 = 1;
LATAbits.LATA7 = 1;

limit_CH2_med = CH2_width;
}
if(calibration_mode == mode_CH2_low)
{
LATAbits.LATA6 = 1;
LATAbits.LATA7 = 0;

limit_CH2_low = CH2_width;

motor_calibration_needed = 1;
}

Nu de motor snelheden worden berekend moeten. De vergelijking wordt de breedte van de puls voor die motor, besluit als het over het middelpunt of niet te beslissen richting, dan vindt er variëren met behulp van de resolutie van de motorische controle binnen het totale bereik van mogelijke breedtes.

berekenen van de motorsnelheid A
Motor_A_Speed = 0;
if(CH1_width > limit_CH1_med+((limit_CH1_high-limit_CH1_med)/center_buffer)) //upper bereik
{
Motor_A_Speed = (CH1_width-limit_CH1_med--((limit_CH1_high-limit_CH1_med)/center_buffer)) / CH1_forward_increment;
Bits.motor_A_Direction = motor_A_inverted;
}
if(CH1_width < limit_CH1_med-((limit_CH1_med-limit_CH1_low)/center_buffer)) //lower bereik
{
Motor_A_Speed = (limit_CH1_med-CH1_width--((limit_CH1_med-limit_CH1_low)/center_buffer)) / CH1_reverse_increment;
Bits.motor_A_Direction =! motor_A_inverted;
}

Bereken motor snelheid B
Motor_B_Speed = 0;
if(CH2_width > limit_CH2_med+((limit_CH2_high-limit_CH2_med)/center_buffer)) //upper bereik
{
Motor_B_Speed = (CH2_width-limit_CH2_med--((limit_CH2_high-limit_CH2_med)/center_buffer)) / CH2_forward_increment;
Bits.motor_B_Direction = motor_B_inverted;
}
if(CH2_width < limit_CH2_med-((limit_CH2_med-limit_CH2_low)/center_buffer)) //lower bereik
{
Motor_B_Speed = (limit_CH2_med-CH2_width--((limit_CH2_med-limit_CH2_low)/center_buffer)) / CH2_reverse_increment;
Bits.motor_B_Direction =! motor_B_inverted;
}
einde van de berekening van de motorsnelheid

} //end van 100hz sectie

Hier de als verklaring en teller die ervoor zorgen dat het bovenstaande alleen uitvoeren bij 100Hz zijn beëindigd en we op de volledige timer-interrupt-frequentie zijn. Het deel onder grepen genereren van het signaal van de motorische controle van de snelheid berekend boven

Contol pulsen motor
Motor_Phase ++;
if(Motor_Phase > Motor_PWM_Rez) {Motor_Phase = 1;}

Motor A
Als (Motor_A_Speed > = Motor_Phase & & Motor_A_Speed < 20) {}
if(bits.motor_A_Direction == 0) {}
Motor_Pin_A1 = 1;
Motor_Pin_A2 = 0;
}
if(bits.motor_A_Direction == 1) {}
Motor_Pin_A1 = 0;
Motor_Pin_A2 = 1;
}
}
else {}
Motor_Pin_A1 = 0;
Motor_Pin_A2 = 0;
}

Motor B
Als (Motor_B_Speed > = Motor_Phase & & Motor_B_Speed < 20) {}
if(bits.motor_B_Direction == 0) {}
Motor_Pin_B1 = 1;
Motor_Pin_B2 = 0;
}
if(bits.motor_B_Direction == 1) {}
Motor_Pin_B1 = 0;
Motor_Pin_B2 = 1;
}
}
else {}
Motor_Pin_B1 = 0;
Motor_Pin_B2 = 0;
}

} //end van timer onderbreken

Hieronder is het begin van de CCP-interrupt. Dit is het deel dat behandelt de pulsbreedte te meten. Eerder was deze op worden geactiveerd door een stijgende rand gezet. Wanneer de stijgende rand wordt gedetecteerd zal het opnemen van de tijd met behulp van CCPR1, dan zal het overschakelen om te letten om te vallen en verander de PWM1Edge variabele aan. Wanneer het detecteert terug te vallen het schakelaars en registreert de tijd.

CCP interrupt
if(PIR1bits.CCP1IF == 1)
{
PIR1bits.CCP1IF = 0; de markering wissen
if(PWM1Edge == 1) //if detecting rising
{
CCP1CON = 0b0000100; //switch te detecteren vallende rand
PWM1Edge = 0; //switch om aan te geven van de dalende rand is volgende
PWMGap = CCPR1 - PWM1FallTime; berekenen van de kloof tussen pulse begint
PWM1RiseTime = CCPR1; //save de lage timer-waarde voor de stijgtijd

if(PWMGap < 10000) {CH2_width = PWMGap;}

}
anders //if opsporen die vallen
{
CCP1CON = 0b0000101; //switch te detecteren stijgende rand
PWM1Edge = 1; //switch om aan te geven van de stijgende rand is volgende
PWM1Width = CCPR1 - PWM1RiseTime; (pwm stijgtijd is het moment dat de opkomst van de pwm optrad)
PWM1FallTime = CCPR1; //save de lage timer-waarde voor de val tijd

Je moet echt te begrijpen van de logica achter dit deel als u wilt wijzigen van de code om te werken op andere ontvangers. De ontvanger van de traxxas die ik gebruikte zet alle van de pulsen rug aan rug. Dit maakte het zodat ik kon niet via slechts één pin lezen omdat de hele reeks van pulsen één lange puls was wanneer gecombineerd. Dus ik ontwierp het programma zodat de chip alleen op elke andere uitvoer aangesloten is, uitgangen in dit geval servo 1 en 3. Op die manier is er een kloof. De korte kloof (degene die minder dan 10000 opgespoord door de als verklaring hieronder) is de tussentijdse en de lengte van de middelste pols, pulse nummer 2. De eerste puls na de lange kloof is pulse nummer 1 en de één na de korte kloof pulse nummer 3 is.

if(PWMGap > 10000) {CH1_width = PWM1Width;}
if(PWMGap < 10000) {CH3_width = PWM1Width;}
}

}
}

Aarzel niet om vragen te stellen. Het zal me dingen duidelijker maken zodat ik waardeer hen helpen.

Zoals ik in die laatste opmerking is dit plan draait van de pulsen die rug aan rug. Sommige ontvangers uitspreiden hen. Als dat het geval was moet u zou niet deze truc om helemaal te doen. In plaats daarvan zou je alleen weten dat na de lange kloof pulse een was, vervolgens na elke extra korte kloof je pulse 2, 3, 4 enzovoort kijkt. U zou enkel Maak een variabele om bij te houden hoeveel pulsen u had gevangen sinds de laatste kloof en resetten wanneer u had de lange, dan gebruiken om te beslissen welk kanaal u een vastgelegde pulsbreedte aan toegeschreven.

Gerelateerde Artikelen

Lego Robot

Lego Robot

mijn vierde Lego robot tot nu toe. Vergeet dan niet om de favoriet en ook mij te volgen want dat me een hoop helpen.Stap 1: Deel graaf Stap 2: Lichaam en armen The last pic is of what you should now haveStap 3: hoofd Stap 4: Benen en voeten Make this
Hond Bot: Lego Robot Rover met Webcam

Hond Bot: Lego Robot Rover met Webcam

Hier is hoe te maken van een Lego robot u vanuit een willekeurig scherm via wifi kunt. Het heeft ook een webcam, zodat u kunt zien waar uw lopende en LED verlichting voor ogen! Dit is een groot project te doen met uw kinderen als ze het logo gebouw d
Lego Robots

Lego Robots

deze zijn de Lego robots ik belooft zo lang geleden. Het spijt me voor het niet posten, ik heb geen excuus. Ik hoop dat u dit als mijn verontschuldiging accepteert. Geniet van!Stap 1: De voeten Dit is hoe het bouwen van de voeten.Stap 2: De benen Sim
Mini Lego Robots

Mini Lego Robots

In dit instructable ik ben tonen u een eenvoudige eenvoudig discingStap 1: De stukken Dit kunnen elke kleur die u zou zij wiltStap 2: Nemen dit raar stukStap 3: En sommige van dezeStap 4: En leg ze op de zijkantenStap 5: Nog eens en plaats deze op de
Gemakkelijk om te bouwen van Lego Robot

Gemakkelijk om te bouwen van Lego Robot

Stap 1: Onderdelen die nodig zijnStap 2: Alle stappen geïllustreerd In foto 's Stap 3: En Bam! Een gemakkelijk op te bouwen Lego Robot Kleuren hoeft niet wedstrijd
ZNAP Lego Robot

ZNAP Lego Robot

Deze tutorial dient als een gids om te bouwen en programmeren van de robot van de kleine, felle en autonome monster Znap. Door middel van het project leert u niet alleen lego constructie maar EV3 programmering zo goed. Zorg ervoor dat elke stap zorgv
Lego Robot dat lost A Rubik Cube

Lego Robot dat lost A Rubik Cube

deze robot is gemaakt van een lego-mindstromStap 1: materialen 1. Lego mindstrom 2. Een computer 3. Een rubik kubusStap 2: gebouw Ga naar http://tiltedtwister.com/tiltedtwister2.html en ontvang de instructies dan de instructies downloaden en bouwenSt
Vier graden van vrijheid Lego Robot Arm gemaakt van twee Thymio Robots

Vier graden van vrijheid Lego Robot Arm gemaakt van twee Thymio Robots

deze 4-graad van vrijheid robotarm bestaat uit twee Thymio Robots en tal van lego.  De kleine lego wielen draait tegenover de nabijheid sensoren voor het meten van de werkelijke afstand reisde.Deze robotarm is gemaakt door: Dr. Stéphane Magnenat of E
Lego robot voor beginers

Lego robot voor beginers

ik eerst raakte in Robotica, toen kreeg ik een Lego erg stormers kit voor KerstmisIk snel gebouwd alle robots in het boek en werd vastgehaakt op RoboticaVoor mij het beste deel was de mogelijkheid om een robot ontworpen om te doen een ding en het pro
Lego Robot en RPG

Lego Robot en RPG

Stap 1: Onderdelen die nodig zijn (robot) Stap 2: Het bouwen van de Robot Stap 3: gedaan!Stap 4: Onderdelen Required(RPG)Stap 5: Gebouw de RPG Stap 6: En weer gedaan!Hier gaat u kerels! Een koele robot en RPG alles in één. Vergeet dan niet naar favor
Lego Robot bestrijding

Lego Robot bestrijding

Door Thawarat Karn PanusokulJoe MarucaStap 1: Materiaal en Tools1. LEGO2. Arduino3. 2 bottom-switch4. de balsahout5. 2 RadioShack No. 27307666. 9V batterij packs10. veel van draad11. externe batterij13. superlijmStap 2: Dragon Lore BABY!1. Maak 2 ver
Eenvoudige en goedkope 6 benen Spider Lego Robot

Eenvoudige en goedkope 6 benen Spider Lego Robot

Sorry voor de soort rush voor dit document.Dit is een eenvoudige 6 benen, 12 mini servo spin en maakt gebruikt van Lego plaat, kunt u meer lego op uw definitieve ontwerp. De kosten is slechts 12 mini servos + 3d gedrukte Lego mount uw LegoStap 1: Voo
Hoe maak je een Lego Robot Mech

Hoe maak je een Lego Robot Mech

moet u een Lego-mech om te vernietigen van een stad, bestrijding van een slechte vent of iets anders, is hier een goeie om te bouwen.Stap 1: materialenStap 2: lichaam Stap 3: benen Stap 4: hoofd Stap 5: Claw Arm Stap 6: Flamethrower Arm Stap 7: Het a
MIN stoom PUNK / DIESEL LEGO ROBOT CRUSHER MIN

MIN stoom PUNK / DIESEL LEGO ROBOT CRUSHER MIN

dit WAS een ander WEEKENDER PROJECT.IN PRINCIPE ALS DE LAATSTE PAAR MINIATUUR STOOM PUNK STIJL ROBOT.GEBOUWD UIT CD PALYER DELEN. HEAD IS DE DUAL LENS-LEZER.LICHAAM EN ARMEN ZIJN ANDERE DELEN VAN DE CD-SPELER EN CASSTE DEKKEN.AL ZITTEND OP EEN CD VOO