Skip to content

Final Project

Video Video for final presentation

Slide Slide for final presentation

This weeks design
schematic board sch
pcb board pcb
arms Light f3d
base f3d
light 3d f3d
light add on f3d
sonar 3d part stl
light 3d stl
headlightsad stl
light add on cap stl
baseplexi dxf
base dxf
accrilic plate svg
atmega328 datasheet pdf
individual LED ino
2 sonar from week 14 ino
presentation code ino
integrated code ino
finalcode ino

The introvert Light

There are online a lot of light designs working with the same principle. I hope to give the concept a own twist. My ambition is to create a light you can get a connection with. A lamp with a own karakter. I want to program the light as being a introvert light and with some love, attention and coding you can alter the light to have a different karakter. More outgoing, rough, gracius. I hope the project does not stop here. My project is opensource and i hope people will change the code to start playing with this design. I think it can be a cool introduction in coding for people since you have sonar and button as input and three servo’s and 20 rgb neopixel as output.

Licence: Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)

BOM Bill of material

  • acrifix-192-acrylaat-lijm-tube-100-gram: (Dokter Plexiglas) €15.95
  • Acrylic frost 5.8 mm 50 cm by 50 cm: (Dokter Plexigas) €40.-
  • Multiplex wood 136 cm by 38 cm: (Houthandel Schmidt Amsterdam) €24
  • 3 TowerPro MG958 Servo A €12.95 (Hobby electronica) €38.85
  • 2 HC SR04 SONAR A €2.95 (Radio rotor Amsterdam) €5.90
  • 1 5v 3A Adapter VOLTCRAFT (Conrad) €7.75
  • WS2812b neopixel (ledkoning) €22.90

cost: €155.35

  • Filament yellow pla Waag fablab inventory €14.-
  • Atmega 328 P au Waag fablab inventory €1.63
  • avrismpd Waag fablab inventory €0.87
  • Ftdi header Waag fablab inventory €0.53
  • Capicitor 1 uF Waag fablab inventory €0.26
  • 4 X capicitor 100 uF Waag fablab inventory €1.04
  • micro usb connector Waag fablab inventory €0.62
  • Male connectors Waag fablab inventory €0.89
  • 20 Mhz resonator Waag fablab inventory €0.75
  • Led RED Waag fablab inventory €0.14
  • resistor 10 K Waag fablab inventory €0.025
  • Resistor 1 K Waag fablab inventory €0.03
  • Resistor 330 OHM Waag fablab inventory €0.02
  • Resistor 0 OHM Waag fablab inventory €0.02
  • 6 mm switch button Waag fablab inventory €0.65

Cost fablab €21.75

Total Cost: €177.10

The prices of the fablab inventory i looked on the site of farnell There could be a difference in actual pricing of the components. But it gives me a understanding of prices for electronics.

What parts and systems were made? What processes were used? What questions were answered? How was it evaluated? What are the implications?

lamp cool design

pixellight other cool design

renderparts My first idea of the light

The parts

The arms The base The sonar cover The headlight The add on The accrilic light cover

Rethinking my design

During machineweek i made a marble track and this gave me a new idea how to create the light. With my initial idea the light would move as a robotic arm. What i did not like about that design was the difficulty in hiding the servo. With my designs the servo kept sticking out which i did not find beautiful.

The arm frames

The biggest challenge with the new idea is making the light not to big. The problem with the servo is that the rotating gear is not centered in the middle. The turning disc have to be calculated from the rotating gear and the whole servo should be placed within the pipe. Further i need space for the wires to go though even when the arm is rotating.

change Changing from robotic arm to tubes

Determine the angle. I want to design the arm in such a way i can make a mold for the composites to fit both sides. A circle seem to be most fitting for this. To have not a use angle i dersign a large circle so i could use a small part of it.

angledeterme

angleright Trying to make the design look nice

Had to rethink my design and in the meantime i used the laser cutter for some test for the inside frame. Before actually making a mold it is important the structure of the arm function as expected. I designed my frame for a accrylic plate i had at home of 5.8 mm. I assume this would be strong enough to hold the parts in place. I designed it pressfit and intent to use accrilic glue to make a strong connection. To use not to much material for the test i only cutted the important circles for the design and the endpart of the pieces holding everything together. Some parts needed to be ingraved for the rotor and the magnet parts. For the cutting i used power 100 and speed 10. Previous test showed a good result. The engraving i did on speed 50 and power 100. This way it engraved deep enough for the rotor

lasercuttest Cut out the board. The red is engraving

One part did not came out well and had to redo it this time with speed 8 and power 100. I was able to connect the parts together with the servo inside. I see some minor adjustment i need to make but it fit well and the rotor can spin freely.

testworked the parts assembled

After doing the test i felt more confident this might work and started redesigning my frame. One thing i want to improve is to give more support to the rails and connection parts. It has to endure tension from spinning and weight so the more support the better.

moresupport On the left is my initial support. The right should provide more support

I want the frame to look ecstatic on it own without a possible composite shell around it. The holes in the frame i placed for two purposes. Ecstatic and weight. With the holes i reduce weight and keeps the structure strong. I deliberate placed the holes around the centre and not to close to edges.

Now i have all seperate parts to assemble my frame. In inkscape i placed the parts in a efficient to reduce the material needed. The whole design is made for the plate accrilic frost i had laying at home of 5.8 mm thick.

settingsframe Using lasercut 5.3 software to cut my pieces

The order of cutting i worked inside out. The first job was the engraved parts for the rotor and the magnets. speed 50: power 100 Next up are the inside cut outs speed 10: power 100 and last the outside cut with the same setting.

cutout Job done

partsassemble The parts ready to assemble

Next step is to assemble the parts together. to create a strong connection i used a special glue for accrylic. acrifix This glue is used to welt acrylic connections. With a uv light the glue melts the two surfaces together. It is best to use this glue in a ventilated space and wearing rubber gloves. More info can be found on the safetysheet

acrifix Glue and uv light for assembly

It is important to bring the glue evenly on the parts. If not done well you will see white residue on the design. I used cotton swab to spread the glue evenly over the acrylic. In uv light it welts the parts quickly to each other. I hold every glued part in place till the connection was dried by the uv light.

doneassemble The two parts assembled with the servo’s installed inside

The Base

For the base i was long in doubt what is should do. I understand the impartance of a heavy base to counter the movement of the moving arms. I wanted first to make a base of cement by making a two sided mold. Cnc the mold of foam and then pour the cement in the mold. I only was not confident in how the end result would be. I am working with a tight schedule towards the end of the fab academy and this method would be time consuming to archieve with no guarantied results.

A more practical approach was to make a base using the cnc machine of wood. I search a nice piece of heavy multiplex to make the base from. The thickness is 24 mm and the idea is to place three segments on top.

Baseexplained Three parts for the base

I made three circle with the diameter of 25 cm. The reason i use such a big base is the extra weight. The idea is that the different parts are pressfit and easy to put together. The top part has a hole in the middle. The idea is that there the arm will be connected to the base. I added two holes with the size of the buttons. I want to use one button to turn on and of the machine. And the other button to change the color of the light. The connection pieces are to place the top part to the midle part. To archieve this i need to

The middle board has a hole to create space for the wiring, servo and pcb board. The ring around will be engraved 5.8 mm to hold a accrilic plate in place. The ring have four circles sticking out. This is mend to prevent the acrylic to rotate. The connection part will be cut out. This way the top and bottom can be placed in the middle part. There are two empty space of 45 mm width. Here will be the sonars placed.

The bottom will be engrave to create the connection points. The middle circle will be engraved more to create space for all the electronic parts.

The challenge was to calculate the space i need for the servo. For the arms to function and able to rotate the distance from the servo and the next component need to be excact 14 mm. On the top base i needed that information to decide how deep to engrave. The issue with wood is that its never excact the same thicknes around. Some places the thicknes was 24 mm, other 23.95 mm or 24.10 mm. I decided to stick with 24 mm.

When the design was ready i imported the file as a dxf in partworks to make the file ready for the cnc. In partwork i first selected the workfield dimensions. The wood i had placed with the length on the x axis and secured the wood with screws on the edges of the board. The workfield dimensions i based on that. I always leave at least 3 cm space between the cutting workfield and where the screws are connected. This gives me more safe feeling about the job. Futher i choose the thicknes of the wood and the startingpoint of the job i set at left bottom.

Somehow the dimensions of dxf files seems to change when working in partworks. There are other ways of importing the file like pdf but in my experience i encounted other issues with that format. It became routine always to double check the dimensions of the dxf and change the size when needed.

With deciding the toolpath i choose to work piece by piece. First all the paths of the top base and then continue to the middle part and lastly the bottom. I did not had time to do all the cutting at once and this way it was easier for me to separate the files and make them separate jobs.

cncpartworks Working in partworks

For the top base i started out with the pocket cuts and set them first on 10 mm deep pockets. The cutting depth was 2.8 mm and would need four rounds to engrave this parts. When i calculated the paths the time it would take was to long. So i changed the depth to 8 mm. This way the pocket cut would be much faster. As a mill i used the 5 mm end mill.Next was the inside circles. Here i use the cut through path tool. The cutting should be on the inside of the circles and needs to get through the material so i set the cuttingdepth on 24.2 mm. This to ensure the mill gets trough the whole material. Lastly the outside cut cutting outside the path with the same cutting depth of 24.2 mm.

millsetting Selecting the 5 end mill and other settings

The midlle part i first selceted the connection parts with a inside cut of 24.2 mm. then selected the pocket cut. Here will be the acrylic board placed upon and needed a engraving depth of 5.8 mm. Next a outside cut of 24.2 mm on the outline.

The base i engraved 8 mm around the connection parts and the middlepart and the rectangle a engraving depth of 14 mm. This to ensure there is place for the servo and electronic. The rectangle is for the cable to go out of the base.

simulationcnc Simulation of the toopaths

When all was set in partworks i saved the toolpaths of each part individual so i had one job at the time. On the cnc machine placed the 5 mm mill. Then i turned on the machine to be able to move the axis. Also i opened the software for the shopbot. For a detailed explainition of the software and machine check out week 8 where i explain in detail the procedure. Then i send the machine to the absolute X/Y origin and moved it afterward to the desired starting point. Before setting this as x/y origin i made a picture of the position so i could continue at a later time with exact the same origin. For the Z axis i moved the mill to a centerpoint of the job. Placed the metal bar underneath after checking if the software detect the metal bar and did the z axis calculation.

Spindle speed: 18.000
Feedrate: 25mm/second
Plungerate 25 mm/second

I chose to start the job with a low feedrate to see how the machine and the material responds and manual turn up the speed if it was possible. The cutting i left on these setting but the pocket cuts i moved the feed rate eventually to 60 mm per second.

cutout Milling the parts

When all the parts were cut out i needed to do some grinding to get a better finish and to be able to connect the parts together. Revealed to see that the fitting was perfect. Is a strong connection and still loose enough to disassemble the parts when needed.

Acrylic base parts

The idea is that in the wooded base the first servo will be installed. For this i used the same acrylic plate. I designed it so i would fit in the engraved part of the middle base. Also in this design i left space for the wiring to go through.

acrilbase *Settings Lasercut 5.3 for accrylic *

In the setting i first choose the engraving part. Afterwards the inside cutting and the outline last.

fitlikea Testing how it fits in the middle base

In my eagernes to work quickly i made two mistakes with this design. The accrylic support i made to big so that it would overlap the opening for the wiring cables and second i forgot to add the holes for the buttons to be placed. A stupid mistake happened by the time pressure and not thinking the design well enough. A a result i had to redesign so it took longer then if i would have though my plan more thoroughly.

baseplexi redesign with holes and better connection parts

Now i had all the parts for the base and time to assemble. I first checked if everything fitted well and then i used acryfix glue and Uv light to mount the acrylic plate.

acryglue glue the accriliic base after testing all the parts

When the accrilic was glued well i start assembling the base to the arms. Now finally my design is getting shape. Very rewarding to see the important parts in place. The base turned out heavy enough to carry the light.

basedone Slowly it start looking as a light

3d design for 3d print

In my design there are a few parts i want to 3d print. The headlight and the parts to cover the two sonar devices.

To intergrate the two sonar i use for my project in the base i designed a simple shield to cover the sonar device. The base of the light is round and i like to make the cover that follows the round shape of the base. I used the sketch for the base to get started with designing. The outline of the middle base i used to create the outline. I measured the dimension of the sonar and 3d designed it to make the cuts in the outline.

basesonar
Designing a 3d file to cover sonar

This was a simple quick design for a better finish. When i was done designing i exported the file as a STL and printed it with our prusa mk3. The fablab recently ugrade the prusa to be able to print with 5 different colors. Normally i prepare the stl in Cura for the lasercutter but because of the upgrade i downloaded prusaslicer. It is a nice software to prepare prints for the 3d printer. Because of the shortage of time i haven’t dived in to all the possibilities but it worked nice to get the print ready. I placed the object on its side and created support around the design.

Speed support: 80
Speed outside: 80
Layerthicknes .2mm
nozzle temperature: 215
bed temperature: 60

sonarprint
3d print with support

sonarprint
placed on base. Fits like a charm

My first print was done in black but i deided to go for more happy colors and reprinted the design in yellow. The same color of the light.

Now it was time to design my headlight. Of practical reasons i decided to design the top in two parts. The main part containing the led covered with plexiglas and a clickable add on. The main part need to rotate and have space for the wiring. I had to design this part in a way that i was able to mount it on the arm of the light.

lightbase1
Sketching on angles planes

I designed the base to be the same size as the arm connecting parts. 85 mm width. The connection part i had to redesign since i only had a different rotor laying around. I wanted to be clear to see when the light is turning so the end part i made more oval shape. This way the rotational spin would be more visible. To be able to attach the head to the arm i needed the center to be freely accessible. I also wanted a small angle in the headlight to make it more expressible.

With the use of the loft tool i created the shape between the base and top. I turned in a solid model. By using the loft tool on the inside i created the hollow shape.

The centre ring on the oval sketch i extruded 5.8 mm so i could place the accrilic plate for the light on the inside while using the outside to connect the nest part upon.

topdone Headlight part 1

prusahead the light in prsa slicer

For the print i used a infill of 5% and no supporrt. The best temperature for pla filament we have is 215 degrees. The print took around 3 hours to Finnish.
printlight 3d print the parts

On the top you see a one of the connection holes. I placed one on the top and one at the bottom to assemble the connection parts to it. The next part should click solid in this part to ensure it stays put.

For the click able part i used the same sketch and gave it a ofset of .05 mm. This way the part will be able to slide on and still be tight enough to stay in place. This part also have to keep the acrylic plate in place. On the inside it i made it 5 mm smaller for this reason.

nextpart2 The clickeble add on

I designed the shape to resemble the eyes of the light. Again i used the loft tool to archive this. The part will be 3d printed so i designed the click on connection part with a small cut out. This way this part is slightly bendable and can be placed on the base light.

frontaddon Front view

I designed two other clickeble part to be placed on the light Now it was easy since i had the base to design the parts on. One design i made more neutral looking and the other one i designed more tough looking. The idea of the light is that you can reprogram the behaviour. Starts out a shy intorvert light and can be made more tough.

neutral neutral add on

tough Tough add on

Accylic plate for LED

Now i had the shape of the light it was time to create the plate for the led. The dimension of the plate should come in the inside of the light. I wanted the plate to be pressfit. I exported the sketch from the 3d file to inkscape and prepared it for the lasercutter. Since the laser will burn away a minimal amount i designed the oval shape with a ofset. I had to do a few test cuts to get the perfect size.

perset Best ofset was .125 mm

When i had the correct size i measure my neo pixels how much i could place on the plate. The best way to equally distribute them was 6-7-6. This way i could cut them in three parts. I wanted a small engraving for the led to fit in. When measured and designed i took one of the accrlic test cases whe have at the lasercutter and decided the depth of the engraving. It could only be a minimal engraving since there are capacitors placed on the neopixels.

engrave Setting lasercut 5.3 for engraving and cutting

When done i tested if the neopixels witted nicely on the base. Look pretty good.

neo neopixel behind base

When this was done most of the external design was done. I assembled the parts to see how the parts fit together.

lightassemble All parts together. I am pleased with the result

Mechanical

Deciding on the motor to use for the design

My most confusing adventure was searching the correct motor for the design. The torque needs to be strong enough to carry the lamp and do the rotation. -Often torque is indicated with g/cm, g/mm, etc. Still that does not ring a bell. I found that there are calculators to convert it to newton meter. This seems to be the information i was searching for.

Newton Newton metre explained

Still have doubt in which one to take but this one i found for a reasonable prices are the nema 17 stepper motor which have 5 kg/cm.

4stepper stepper with holding torgue of 5kg/cm

With the calculator it shows that it would be 0.49 n-m. Which would be almost a halve a kilo on 1 meter. My lamp is smaller then this but there are two steppers in the design with a weight of 360 gram each. Have to some more research.

After long research i decided not to go with the stepper motors for my design. The steppers i researched were heavy and had not enough torque. Also when power is of they don’t hold position which i prefer to have in my lamp design. On last concern with stepper motor is the h-bridge i have to use. I chose for the servo motor to do the job. They are more light weight and easier to control.

digitalservo Bought these servo to do the job

The servo i have bought have metal gears and a holding torque of around 20 kg/cm. This was my biggest concern the holding torque of the stepper/servo. The cool thing about these servo is that the are geared. So also when the power is off they hold their position. Before i have done research on different types of servo’s and steppers. This servo is light and have a good holding torque.

specs Specs of the servo motor

With the help of newton meter converter i was able to calculate the amount of kilo the servo can handle over a distance of a meter. 20 kg/cm is around 1.9 kilo. Now i don’t have to be concerned to much about the weight. My design will be smaller with less load.

Newton Meter the converter to newton meter

Testing the servo

I like to study how the servo motors respond. To get a good idea of how to control them i made a simple construction in the shape of my light to test the movement and potential issues. I quickly designed a structure in fusion 360 to put my servo to the test. I measured the size of the servo to make a good tight construction around it. I created a base and three arms to practice the movement.

cutoutservo Inkscape layout pieces for testing

Then it was time to assemble my testcase. My measurement where correct and the servo fitted perfect in the holes. The rotors i screwed on the wood in the hope it would stay put. Now it is time to put it to the test.

construct The test construction

Using arduino board to test code

since i want to control multiple servo motors i need to import the library to do so. server.h i need to control multiple servo at the same time.

servolib The libray for controlling multiple servo’s

Another thing to keep in mind is that servo need to be controlled by pwm pins. On the arduino they are located on pin 3, 5, 6, 9, 10, and 11.

pwm how servo is controlled

servopowerbench testing the servo with 5 volt and max 1.5 Ampere

The servo’s were very unrilable in the first test. Sometime it did not spin while the next moment it moved accordantly to the code. Someone gave me the advice to use capicitors to deal with the sudden power changes.

Electronics

For my final design i am using high torque servo’s for the rotation of the light. These will be controlled using two sonar measuring the distance and for the light i am intending to use rgb neopixels. I first did research in what the different parts need to be able to work.

The high torque servo’s have three connection. Gnd, Vcc, and the signal pin. The servo have to be connected to a PWM pin to be controlled.

pwmservo Control servo using pwm signals

After some research i decided to use capicitors for better functioning of the servo’s. Using capicitors for servo The recommended capicitors are 470 uF. At the fablab the higest available capicitor i was able to find was 100 uF. I decided to use these instead in my pcb design.

The rgb neopixel led is controlled by three pins. Vcc, Gnd and signal. The led are controlled by one pin from the microprocessor with PWM. Online i found a nice instruction how to use WS2812b neopixels. neopixel resitor and capicitor Based on this information i decided to use a 330 ohm resistor and the biggest capicitor avalable at fablab Waag 100 uF capicitor

The Hcsr04 sonar i have used before and i knew that i could connect them straight to the microprocessor with the use of resitors or capicitor. They have four pins. Gnd, Vcc, Trig and echo. The trig and echo need to be connected to a I/O pin on the processor.

For the micro controller i choose for the atmega 328P.

atmegapin Pin function atmega

I choose this microcontroller to ensure i have enough free pins to contol my light and that i could optionally place new features to my design. Also i need four pwm pins to control the rgb and servo’s.

The schematics

At first i had the idea to power the microprocessor and the servo’s seperate and i made this schematic for the board. I bit orthodox i decided to call the second power suppy vcc1. the design have still have errors. One of them i thought to connect vcc1 also to the microprocessor.

scematicfirst First efford designing the schematic

After seeking advice i decided to control the board and the servo’s on the same powersupply.

scematicdone Final design for electronics

The zero ohm resitors where not intended to incorporate in the design. When possible you try to design the board so it does not need zero ohm resistors. I had to add them when i had trouble making the traces connect. All the different parts will be connected through the male connectors placed on the board. 3 pin connectors for the rgb and servo and 4 pin connector to control the hc sr04 sonar.

To be able to program the board using a usb tiny i added a spi header. To be able to read the distance of the sonar i placed a ftdi header for serial communication. I decided to us not a crystal but a 20 mhz resonator. Which turned out not the best choice since you need to find a special bootloader to function. Later more about this.

When programming the micrcontroller i want a pushbutton for reset for more control over the board. I want to be able to reset a quick as possible when the light is out of control. Later on i like to have the option using pushbuttons to reset, control the RGB and power. To achieve this i used male connectors so in a later stadium i could add control buttons on there. In the meanttime the power will be able to go through thanks to the use of jumpers.

For practical reason i used a red led between the spi and microcontroller. This way i am able to see if the signal is send when coding. I added a 1 k resistor on this line.

For the RGB neopixel i used a 330 ohm resistor and a 100 uF capicitor. The servo’s have as well each a 100 uF capicitor. I was not able to find the foorprint for the capicitor so i designed it with the standard c1012fab footprint so i cold later manually change the footprint in inkscape

To power the device i am using a 5 volt, 3 ampere micro usb adapter. In the fablab we have DX4R005HJ5R2000 micro connectors. I had to download the correct footprint and place it in the kicad folder. I added it in the kicad library in scematics and footprint.

When i placed all components and labeled the wires. I used the crossed to cancel the pin i am not using. i annotate the scematic to get order in the components. r1,r2,r3, etc. Then i used the electric ruler check for fault in my design and recieved the know error 3. This is caused since i don’t select a power supply.

electricruler The electrical rules check

Lastly i had to assign the footprint to the design.

footprintdone Selecting the footprint

When this was done i saved the schematic and created a netlist. I opened the pcbnew menu and uploaded the netlist. I always begin hopefull in creating the traces and end up in frustration to get all the paths selected.

The capicitor i am using are much bigger in size then the ceramic capicitors i used before. I knew i had to leave enough space around them to be placed. Since i did not find a footprint i measured the size of the capacitors and created a circle of that diameter around the foot print of the c1012fab footprint. This to ensure that there would not be a overlap.

The capacitors i placed close to the rgb led and servo’s. For practical reasons i place the ftdi header and microusb close to each other so i could power and program the board more easy when it is later locked in the base.

pcbcap Placing circle around the capicitors

On the other side of the boar i place the connectors for the sonar so that the wiring does not have to go over the pcb board. I was working for a long time to connect al the wiring. I placed the components for a reason in a certain position but that did resulted in difficulties in connecting all the wires. After trying to fix the wiring for a long time i decided to use zero ohm resistors to connect all paths.

pcb2 The other side

The yellow and blue lines are for reference. The blue line is indicating the max width the board can have to fit in the base next to the servo. The yellow circle show the diamater of the base. I wanted to use inkscape to create the path around. The white lines remaining are for the zero ohm resistors and connection for the buttons which is first gonna be closed by jumpers.

pcbaf complete pcb

In inkscape i designed the footprints for the capicitor and made a outline to fit in the base. As a extra i added the name of the project and my name to the design.

pcbinkscape Designing the board in inkscape. I enlarge the trace for the capacitor

I uploaded the inside and outside seperate as svg file and in gimp i set the resolution on 1000 bpi and removed the alpha channel. I exported the file as png and now it was time for the milling part.

Milling the pcb

I first uploaded the inside png in mods. I inverted the png and selected the mill traces to be .4 mm. The speed i changed to 1 mm per second. In previous experience is it wise to set the speed low. A higher speed resulted in breaking the mill.

mods inverted png

I mounted a new copper plate on the board with dubbel sided tape. I pressed with a towel the copper plate to the sacrificial layer til it looka flat surface. I open the connection between the Roland MDX 20 and mods and set the origin. Carefully i placed the .4mm mill in the machine. When this was set i pressed calculate.

trace
Path of the mill

I looked at the prediction quickly and the traces looked good on forhand so i started the milling job. With a pcb this size and the speed of 1 mm it takes a long time for the board to be ready. When the job was over halve way after three hours i noticed the milling bit did brake.. I had to place a new bit and redo the milling for another 4.5 hours. I usedd the same trace to continue.

milling Milling the pcb board

When the job was done i quickly expeted the trace and was please with the result. I did a outline cut using a .8 mm mill and gently took the board out of the machine. I washed the board with soap to get rid of residues and prepared the soldering station for the next step. till..

Looking at the board again i realized a stupid mistake. The distance on my footprint of the atmega328p had a distance of less then .4 mm. As a result the machine did not cut out the pins of the atmega 328p. A wasted day due my own mistake. In the picture of the path i should have seen this. Somehow i overlooked and looked only at the traces of the paths. A wasted effort..

milling No cut out at micro processor

I tried first to cut out the path with a hobby knife. I checked the path and the was no short. Without much confidient i tried to solder the microprocessor. But quickly i saw it was better to redo the job.

for time management i decide to change the footprint of the atmega 328 p manual in inkscape and redo the job. This time i paid extra attention at the image of the path calculation to ensure the job would be good. Also in this job halve way the mill broke and had to redo the job. All in all it took me much longer then anticipated to Finnish the pcb. But it was finally there. Time to start soldering. I did make one mistake with redesigning. Forgot to add the bigger footprint for the capacitors. But this could be resolved.

solderingproces Started soldering inside out. I always start with the micro controller

Soldering still takes time for me. i am not good in the small precise work. My hand is unfortanly not to steady. But when i take the time i manage to get all components on the board. I only was not able to get the micro usb on place. Here i noticed a design error. I did not had anticipated that the cable might not fit when the micro usb is not n the side of the board. I decided to place male connectors for the power. This would be more easy. All in all i was happy with my soldering work.

solderdone Board ready except the micro usb

Programming the board

Now it was time to do a boatloader on my device. I attached the board with spi to my attinyusb and opened the arduino IDE. I selected the arduino Uno as device and upload using programmer. then i performed the bootloader.

bootloaderror error using bootloader

I got a error and the bootloading could not be done. With the multimeter i rechecked all connections and all parts seemed connection and the was no shorts to be found. After trying for a while and getting scared that i designed my board wrong i found my mistake. I designed a connector to place in a later stadium a button on. Now i had to use a jumper for the connection. Very silly mistake.

bootsuc Then i had a succesfull bootloader

I have to say that these are one of the most rewarding things that i experience in the fabacademy. A own designed board and milled and soldered to see the device is now ready to be programmed.

The next step was testing if i was able to put code on the device. Since i am working with sonars i had still code from week 14 for two sonar i could use for this board. I had to change the echo en trig pin of the two sonar to correspond with the new designed board. After this i uploaded the code using the programmer. It Worked!!

//#include <SoftwareSerial.h> // import another program, a library, to communicate
//#define rxpin 0 
//#define txpin 1

//SoftwareSerial serial(rxpin,txpin);

int rxPin = 0; // this is simular to the int = setting, however this is linked to the library
int txPin = 1;
int trig = 16; 
int echo = 17; 
int trig1 = 18; 
int echo1 = 19; 
long lecture_echo; 
long cm;
int timeout = 1000;

In the code you see the changes of the pin.

arduinos First code uploaded

When this was done i connected the board with my laptop using the ftdi cable. I placed the sonars and opened the serial communication. There was information coming in but i gave me weird signals.

sonarg Weird input on my device

I started with changing the the rx and tx cable to see if this would fix my issue. Now there was not communication. I read online Arduino often programmen with baudrate 115200. I changed this in the code and serial monitor. Still it gave weird signals as feedback. I was nnot sure what this was and how to solve it. I tried using one sonar and still same feedback. My fellow student Joey mentioned i was using a 20 mhz resonator while the atmega is mend for max 16 mhz. There are some tweak around but best was to install a new boatloader using the internal clock of the atmega 328 P This site was very helpfull in choosing the right boot loader.

internal clear instructions how to pick the correct internal clock

When this was set i recieve actual input from the two sonar. One step further.

inputsonar Recieving data

rgb lED

My next challenge is to control the rgb neopixel strip using my board. I found a nice tuturial online how to test rgb led strips. tutorial I had to download the adafruit neopixel library in arduino. Using the following code i was able to control my rgb led.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif


#define LED_PIN    3


#define LED_COUNT 20


Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)

void setup() {
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)
}


// loop() function -- runs repeatedly as long as board is on ---------------

void loop() {
  // Fill along the length of the strip in various colors...
  colorWipe(strip.Color(255,   0,   0), 50); // Red
  colorWipe(strip.Color(  0, 255,   0), 50); // Green
  colorWipe(strip.Color(  0,   0, 255), 50); // Blue

  // Do a theater marquee effect in various colors...
  theaterChase(strip.Color(127, 127, 127), 50); // White, half brightness
  theaterChase(strip.Color(127,   0,   0), 50); // Red, half brightness
  theaterChase(strip.Color(  0,   0, 127), 50); // Blue, half brightness

  rainbow(10);             // Flowing rainbow cycle along the whole strip
  theaterChaseRainbow(50); // Rainbow-enhanced theaterChase variant
}

void colorWipe(uint32_t color, int wait) {
  for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(wait);                           //  Pause for a moment
  }
}


void theaterChase(uint32_t color, int wait) {
  for(int a=0; a<10; a++) {  // Repeat 10 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in steps of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show(); // Update strip with new contents
      delay(wait);  // Pause for a moment
    }
  }
}

void rainbow(int wait) {

  for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...

      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());

    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}


void theaterChaseRainbow(int wait) {
  int firstPixelHue = 0;     // First pixel starts at red (hue 0)
  for(int a=0; a<30; a++) {  // Repeat 30 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)

      for(int c=b; c<strip.numPixels(); c += 3) {

        int      hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show();                // Update strip with new contents
      delay(wait);                 // Pause for a moment
      firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
    }
  }
}

The upload went well and i placed the wiring for the led. On on vcc, gnd and sinal on pin 3. When i tried the rgb using the powerbench i did not recieve light. Not sure how come but i had to do some trouble seeking. It turned out i soldered the neopixels wrong. The neopixels have a di and a do side. The di should be connected to the do otherwise it does not work. I resoldered the neopixel and this time i recieved the desired result.

dido The do in the di

rgbwork Rgb working using the powerbench

rgbcool Rewarding to see finally a light

Testing the servo’s

The last devices needed to be checked were the high torque servo’s. I used the code i tried before to test the servo’s using a arduino.

#include <Servo.h>

Servo myservo;
int pos = 0;
const int SERVO_MAX = 160;
const int SERVO_MIN = 20;


void setup()
{
  Serial.begin(9600);
  myservo.write(SERVO_MIN);
  myservo.attach(9);
  Serial.println(F("Beginning of program."));
}

void loop()
{
  Serial.println(F("From minimum to maximum."));
  for (pos = SERVO_MIN; pos < SERVO_MAX; pos++)
  {
    myservo.write(pos);
    delay(10);
  }
  Serial.println(F("From maximum to minimum."));
  for (pos = SERVO_MAX; pos > SERVO_MIN; pos--)
  {
    myservo.write(pos);
    delay(10);
  }
  Serial.println(F("Restarting Loop"));
}

and it did not work this time.The servo’s made a clicking sound but the rotors where not moving at all. For power i used 5 volt and 3 ampere. This because the adapter i purchased to control the servo’s. Not sure what could be the problem. I unplugged the wires and retried the test using a arduino uno. I gave the servo’s a different power supply then the arduino but still i did not recieve the desired output.

I checked all connection using the multimeter and there seemed no issues. All connections seemed solid and i could not find any shorts. After a long time trouble seeking looking at the code, rechecking connections i still could not find a issue. The solution turned out connecting the servo straight to the powersupply and not using the breadboard to do this. Somehow power seemed to get lost by using the breadboard.

The problem is that i have designed my board for one power supply for all the different devices. Lucky during network week i have made a add on for the satcha kit i made. During that week i found the one pin for power and one for gnd so minimal. Plus the board i designed did not had a spi connector or i2c. I did not constantly have to think about wiring the satcha and made this board. Happy about that decision.

addon Extra board thanks to satcha kit

The next problem occurred. Before i shortened my cables to fit better in the base. For testing this proved far from ideal. You constantly remove and change connections to check different parts. So i resoldered the connection to have enough space to test the board with the pcb out of the base. I used that time to resolder the buttons using a more flexible wire.

resolder resoldering the lines

Now i could do the test again with the servo’s hoping for a better outcome.Using the extra board i connected power to the addon first and from there to the pcb design. I powered the deviced through the powerbench with 5 volt and 3 ampere. I tried the servo’s and they were working except the bottom one. Still a bit shocky but i now do not use capicitors for the test And i have to tweak the code still for optimal result. Luckily my first concept for a light design contained four servo and i my new design just 3 so i had a spare one. I tested this one and it worked well.

sonar1 from Rutger Oomkes on Vimeo.

Servo 1

sonar2 from Rutger Oomkes on Vimeo.

servo2

sonar3 from Rutger Oomkes on Vimeo.

Servo3

Now time to test multiple servo’s at one. I used the same code and copied twice and renamed the Servo myservo, Servo myservo1, Servo myservo2 and placed them at the pin 9, 10 and 5.

3servo the ratsnest of cables for the test

This test did not so good. I saw a extreme voltage drop on the powerbench. I retried with disconnecting one servo. Still te same result My best guess at the moment is that i have to add capicitors between the GND and Vcc on each servo. I bought some 470 uH capicitors which i will try tomorrow.

voltagedrop The volt drops from 5 v to 2.33

The next day i reconnected the device and did not recieve a voltage drop. It might have been the cable connection the day before. The servo’s were still not running at the same time though. One at the time worked perfect for me but the moment i tried to connect more servo’s at ones the lamp did nothing. The problem layed in the code. The example sweep i used for the servo i made the delay higher so that the servo’s where rotating in a slower pace. This big delay seemed to disrupt the code when controlling multiple servo’s. When i turned of the delay all servo’s where rotating in a quick pace.

adhd from Rutger Oomkes on Vimeo.

Code

The next challenge was to control the rgb led individual. I did use the Adafruit neopixel strand test but i like to control the led individual to create more expresion in the light. My ambition is to give the light eyes that react on distance. To archieve this i looked online in how to control them piece by piece. Most examples make all the rgb led light up in a loop. I want to have one solid color and a few indiviual led have a different set of color. In the end i found online a way to control each pixel on it selve. With some tweaking i created the look i wanted from the light. Most likely the the most efficient way of coding but it seemed to work for my project.

#include <Adafruit_NeoPixel.h>
#define PIN 3
#define NUM_LIGHTS  20

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LIGHTS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
 // uint32_t low = strip.Color(0, 0, 0); 
  //  uint32_t high = strip.Color(255, 255, 255);

    strip.setPixelColor(0, 229, 142, 13); 
    strip.setPixelColor(1, 229, 142, 13); 
    strip.setPixelColor(2, 229, 142, 13); 
    strip.setPixelColor(3, 229, 142, 13); 
       strip.setPixelColor(4, 229, 142, 13); 
    strip.setPixelColor(5, 229, 142, 13); 
    strip.setPixelColor(6, 229, 142, 13); 
    strip.setPixelColor(7, 229, 142, 13); 
  strip.setPixelColor(8, 0, 0, 255);
 strip.setPixelColor(9, 229, 142, 13); 
    strip.setPixelColor(10, 229, 142, 13); 
    strip.setPixelColor(11, 229, 142, 13); 
    strip.setPixelColor(12, 0, 0, 255); 
   strip.setPixelColor(13, 229, 142, 13); 
      strip.setPixelColor(14, 229, 142, 13); 
 strip.setPixelColor(15, 229, 142, 13); 
    strip.setPixelColor(16, 229, 142, 13); 
    strip.setPixelColor(17, 229, 142, 13); 
   strip.setPixelColor(18, 229, 142, 13); 
    strip.setPixelColor(19, 229, 142, 13);    

    // Turn them off
    for( int i = 0; i<NUM_LIGHTS; i++){
//        strip.setPixelColor(i, high);
        strip.show();
    }   
    delay(1000);

    for( int i = 0; i<NUM_LIGHTS; i++){
//      strip.setPixelColor(i, low);
        strip.show();
    }   

     delay(1000);
}

Here i set the color to yellowish use the rgb matrix. I have two dots that show blue showing the eyes.

smallereyes hard to see but two light are blue indicating the eyes

       strip.setPixelColor(0, 229, 142, 13); 
    strip.setPixelColor(1, 0, 0, 255); 
    strip.setPixelColor(2, 0, 0, 255); 
    strip.setPixelColor(3, 229, 142, 13); 
       strip.setPixelColor(4, 229, 142, 13); 
    strip.setPixelColor(5, 0, 0, 255); 
    strip.setPixelColor(6, 0, 0, 255); 
    strip.setPixelColor(7, 0, 0, 255); 
  strip.setPixelColor(8, 0, 0, 0);
 strip.setPixelColor(9, 0, 0, 255); 
    strip.setPixelColor(10, 229, 142, 13); 
    strip.setPixelColor(11, 0, 0, 255); 
    strip.setPixelColor(12, 0, 0, 0); 
   strip.setPixelColor(13, 0, 0, 255); 
      strip.setPixelColor(14, 0, 0, 255); 
 strip.setPixelColor(15, 0, 0, 255); 
    strip.setPixelColor(16, 229, 142, 13); 
    strip.setPixelColor(17, 229, 142, 13); 
   strip.setPixelColor(18, 0, 0, 255);   
      strip.setPixelColor(19, 0, 0, 255); 


    // Turn them off
    for( int i = 0; i<NUM_LIGHTS; i++){
//        strip.setPixelColor(i, high);
        strip.show();
    }   
    delay(1000);

    for( int i = 0; i<NUM_LIGHTS; i++){
//      strip.setPixelColor(i, low);
        strip.show();
    }   

     delay(1000);
}

In this code i set more pixels to blue so the eyes become bigger. When someone comes close the first reaction is that the eyes get big and then the light moves away from you.

eyesbig Bigger eyes

When i had this working i was able to control the rgb led indiviual, make the servo’s rotate and read the data from the sonar on the serial port. Now i had to combine the code and make my light interactive. Coming from zero knowledge before the fabacedemy i was proud i had the several parts working. Combining them i a functional code turned more tricky then hoped for. Being exhausted from the last few weeks i had much difficulties in writing a functional code. I uploaded the combined code and i could read data from the serial port and my servos’s where rotating but then the leds where not showing. Not sure if the problem was in the code or voltagedrop caused by the moving servo’s. I wanted to check if i would have more control using 470 uF Capicitors for my servo’s. Since i was not sure if this could provide me with the sulotion i used arduino wires to mount the capacitor on. This way if it would have not the desired result i still could take them of easy.

capicitor Soldering the capicitor on a arduino wire

I was worried that the gnd and vcc might touch each other when connecting so i used shrink sleeve to prevent that happening. Further i used a little tape to recognized the vcc. This way i would not mistakenly mis connect them in my pcb board I was hoping this would resolve my issue and that now all different parts would work. I reconnected all the wires and gave it a new try.

choas Connecting wires with capacitor in pcb

It did not had the desired result. Most likely my issue was in the coding itself so i now started focusing on the the combined code. I used all the different codes that worked separately from each other and combined them. To adress the led individual worked and the code for the sonar was from week 11 during input week and that code worked as well. I had to fine tune my existing code to get the result i was hoping for. Underneath is my failed code.

Combining all the code

//Servo installed
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
Servo myservo1; 
//Servo myservo2; 
//Servo myservo1;
// twelve servo objects can be created on most boards 

int pos = 90;    // variable to store the servo position

#include <Adafruit_NeoPixel.h>
#define PIN 3
#define NUM_LIGHTS  20

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LIGHTS, PIN, NEO_GRB + NEO_KHZ800);

//Sonar installed

int rxPin = 0; // this is simular to the int = setting, however this is linked to the library
int txPin = 1;
int trig = 16; 
int echo = 17; 
int trig1 = 18; 
int echo1 = 19; 
long lecture_echo; 
long cm;
int timeout = 1000;

void setup() 
//Servo setup
{
  myservo.attach(10);
  myservo1.attach(9);
 // myservo2.attach(5);
 // myservo1.attach(10);// attaches the servo on pin 9 to the servo objec

//sonar setup
  pinMode(trig, OUTPUT); 
  digitalWrite(trig, LOW); 
  pinMode(echo, INPUT);  

  pinMode(trig1, OUTPUT); 
  digitalWrite(trig1, LOW); 
  pinMode(echo1, INPUT); 

  Serial.begin(9600);

   strip.begin();
  strip.show(); // Initialize all pixels to 'off'   
}

void loop() {
{
digitalWrite(trig1, HIGH); 
delayMicroseconds(10); 
digitalWrite(trig1, LOW); 
lecture_echo = pulseIn(echo1, HIGH, timeout*1000); //timeout in micro seconden
cm = lecture_echo / 58; 
Serial.print(cm); 
Serial.println(" cm");
delay (500);
}




if(cm > 0 && cm < 50 )

{
 // in steps of 1 degree
    myservo.write(160);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  myservo1.write(20);              // tell servo to go to position in variable 'pos'
    delay(15);  
     myservo1.write(90);              // tell servo to go to position in variable 'pos'
    delay(15);    
     myservo1.write(20);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position  
  }
if(cm > 0 && cm < 50 )
{
    strip.setPixelColor(0, 229, 142, 13); 
    strip.setPixelColor(1, 229, 142, 13); 
    strip.setPixelColor(2, 229, 142, 13); 
    strip.setPixelColor(3, 229, 142, 13); 
       strip.setPixelColor(4, 229, 142, 13); 
    strip.setPixelColor(5, 229, 142, 13); 
    strip.setPixelColor(6, 229, 142, 13); 
    strip.setPixelColor(7, 229, 142, 13); 
  strip.setPixelColor(8, 0, 0, 255);
 strip.setPixelColor(9, 229, 142, 13); 
    strip.setPixelColor(10, 229, 142, 13); 
    strip.setPixelColor(11, 229, 142, 13); 
    strip.setPixelColor(12, 0, 0, 255); 
   strip.setPixelColor(13, 229, 142, 13); 
      strip.setPixelColor(14, 229, 142, 13); 
 strip.setPixelColor(15, 229, 142, 13); 
    strip.setPixelColor(16, 229, 142, 13); 
    strip.setPixelColor(17, 229, 142, 13); 
   strip.setPixelColor(18, 229, 142, 13); 
    strip.setPixelColor(19, 229, 142, 13);    
 } 


else 
{

    // in steps of 1 degree
    myservo.write(90);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position



    // in steps of 1 degree
    myservo1.write(90);             // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }

 { 
       strip.setPixelColor(0, 229, 142, 13); 
    strip.setPixelColor(1, 0, 0, 255); 
    strip.setPixelColor(2, 0, 0, 255); 
    strip.setPixelColor(3, 229, 142, 13); 
       strip.setPixelColor(4, 229, 142, 13); 
    strip.setPixelColor(5, 0, 0, 255); 
    strip.setPixelColor(6, 0, 0, 255); 
    strip.setPixelColor(7, 0, 0, 255); 
  strip.setPixelColor(8, 0, 0, 0);
 strip.setPixelColor(9, 0, 0, 255); 
    strip.setPixelColor(10, 229, 142, 13); 
    strip.setPixelColor(11, 0, 0, 255); 
    strip.setPixelColor(12, 0, 0, 0); 
   strip.setPixelColor(13, 0, 0, 255); 
      strip.setPixelColor(14, 0, 0, 255); 
 strip.setPixelColor(15, 0, 0, 255); 
    strip.setPixelColor(16, 229, 142, 13); 
    strip.setPixelColor(17, 229, 142, 13); 
   strip.setPixelColor(18, 0, 0, 255);   
      strip.setPixelColor(19, 0, 0, 255);    

}
   }

combinedcode

In the last day i spend my time configuring the code for the code to work. In my last attempted i placed the rgb code in the setup. This way all the different parts worked together and i was able to read the sonar. I still have to spend some time improving the code and make it react in a smooth way with the distance of the sonar. I used for now one sonar and two servo’s. The time it takes to recieve input from the sonar still takes a lot of time. I expect i need to do some more research in how to smoothen the movement of the servo. How to incorporate the neo pixel led in a nice ecstatic way and to get a reliable input from the sonar.

The servo’s are power and gnd are connected to the add on board. For the led and sonar to work i placed them on my designed pcb and powered the separately by usb. This way all the parts of the design worked.

For the presentation i used the following code. Was not yet interacting on the sonar but there wwas movement and light.

Working code arduino presentation

#include <Adafruit_NeoPixel.h>
#define PIN 3
#define NUM_LIGHTS  20

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LIGHTS, PIN, NEO_GRB + NEO_KHZ800);


//Servo installed
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
Servo myservo1; 
//Servo myservo2; 
//Servo myservo1;
// twelve servo objects can be created on most boards 

int pos = 90;    // variable to store the servo position

//Sonar installed

int rxPin = 0; // this is simular to the int = setting, however this is linked to the library
int txPin = 1;
int trig = 16; 
int echo = 17; 
int trig1 = 18; 
int echo1 = 19; 
long lecture_echo; 
long cm;
int timeout = 10;
long previoustime = 0;

void setup() 
//Servo setup
{
    strip.begin();
  strip.show();
  myservo.attach(10);
  myservo1.attach(9);
// myservo2.attach(5);
 // myservo1.attach(10);// attaches the servo on pin 9 to the servo objec

//sonar setup
  pinMode(trig, OUTPUT); 
  digitalWrite(trig, LOW); 
  pinMode(echo, INPUT);  

  pinMode(trig1, OUTPUT); 
  digitalWrite(trig1, LOW); 
  pinMode(echo1, INPUT); 

  Serial.begin(9600);   

    strip.setPixelColor(0, 229, 142, 13); 
    strip.setPixelColor(1, 229, 142, 13); 
    strip.setPixelColor(2, 229, 142, 13); 
    strip.setPixelColor(3, 229, 142, 13); 
       strip.setPixelColor(4, 229, 142, 13); 
    strip.setPixelColor(5, 229, 142, 13); 
    strip.setPixelColor(6, 229, 142, 13); 
    strip.setPixelColor(7, 229, 142, 13); 
  strip.setPixelColor(8, 0, 0, 255);
 strip.setPixelColor(9, 229, 142, 13); 
    strip.setPixelColor(10, 229, 142, 13); 
    strip.setPixelColor(11, 229, 142, 13); 
    strip.setPixelColor(12, 0, 0, 255); 
   strip.setPixelColor(13, 229, 142, 13); 
      strip.setPixelColor(14, 229, 142, 13); 
 strip.setPixelColor(15, 229, 142, 13); 
    strip.setPixelColor(16, 229, 142, 13); 
    strip.setPixelColor(17, 229, 142, 13); 
   strip.setPixelColor(18, 229, 142, 13); 
    strip.setPixelColor(19, 229, 142, 13);

    for( int i = 0; i<NUM_LIGHTS; i++){
//        strip.setPixelColor(i, high);
        strip.show();
    }   
    delay(100);

//    for( int i = 0; i<NUM_LIGHTS; i++){
//      strip.setPixelColor(i, low);
 //       strip.show();
}

void loop() {
for (pos = 20; pos <= 160; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(45);                       // waits 15ms for the servo to reach the position
  }
 for (pos = 20; pos <= 160; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo1.write(pos);              // tell servo to go to position in variable 'pos'
delay(30);  

 // for (pos = 20; pos <= 160; pos += 1) { // goes from 180 degrees to 0 degrees
 //   myservo2.write(pos);              // tell servo to go to position in variable 'pos'
//delay(30);                       // waits 15ms for the servo to reach the position
 // }

 } 
  for (pos = 160; pos >= 20; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
   delay(30);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 160; pos >= 20; pos -= 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo1.write(pos);              // tell servo to go to position in variable 'pos'
delay(30);                       // waits 15ms for the servo to reach the position
  }
 // {
 // for (pos = 160; pos >= 20; pos -= 1) { // goes from 180 degrees to 0 degrees
//    myservo2.write(pos);              // tell servo to go to position in variable 'pos'
//delay(45);                       // waits 15ms for the servo to reach the position
 // }




//sonar loop

if( millis()- previoustime > 1000){
previoustime = millis();
 digitalWrite(trig, HIGH); 
 delayMicroseconds(10); 
 digitalWrite(trig, LOW); 
 lecture_echo = pulseIn(echo, HIGH,  timeout*1000); 
 cm = lecture_echo / 58; 

 Serial.print ("sonar 1 in cm: "); 
 Serial.println(cm); 
// sonarafstand(cm);
delay (20);

digitalWrite(trig1, HIGH); 
delayMicroseconds(10); 
digitalWrite(trig1, LOW); 
lecture_echo = pulseIn(echo1, HIGH, timeout*1000); //timeout in micro seconden
cm = lecture_echo / 58; 

//Serial.print ("sonar 2 in cm: "); 
//Serial.println(cm); 
//delay (500);

//  delay(100); 
}

}

void sonarafstand(int afstand){
 if(cm > 10 && cm < 50 ){
 //servo loop   

  for (pos = 20; pos <= 160; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(45);                       // waits 15ms for the servo to reach the position
  }
 for (pos = 20; pos <= 160; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo1.write(pos);              // tell servo to go to position in variable 'pos'
delay(30);  

 // for (pos = 20; pos <= 160; pos += 1) { // goes from 180 degrees to 0 degrees
 //   myservo2.write(pos);              // tell servo to go to position in variable 'pos'
//delay(30);                       // waits 15ms for the servo to reach the position
 // }

 } 
  for (pos = 160; pos >= 20; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
   delay(30);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 160; pos >= 20; pos -= 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo1.write(pos);              // tell servo to go to position in variable 'pos'
delay(30);                       // waits 15ms for the servo to reach the position
  }
 // {
 // for (pos = 160; pos >= 20; pos -= 1) { // goes from 180 degrees to 0 degrees
//    myservo2.write(pos);              // tell servo to go to position in variable 'pos'
//delay(45);                       // waits 15ms for the servo to reach the position
 // }

 }else {


 }
}

Site for smoothing the servo without using delay function

Other site for smoothing servo’s

Servo easing

After the presentation i went on writing code for the lamp. I searched online different methods in slowing the servo’s so that it would be more predictable and appearing as being a shy light. The previous code i used i combined different code in hope for a good outcome. I realized i had to go back to scratch and slowly adding extra code to it. So i started of again with the code i used in week 14 for controlling the two sonar and slowly building from that. Just the sonar worked fine and i started adding movement of the servo’s to the code. My light kept reacting unpredictably to the code. After trying lots of differennt code with the same outcome i started doubting my powersource. The 5 volt adapter and 3 ampere output. I used the powersupply to power my device and my code was working this time. The setting i used are the same as my adapter but somehow the adapter did not function as anticipated. With my light connected to the power benchi finally was able to Finnish my code and put it to the test.

//Sonar
int rxPin = 0; // this is simular to the int = setting, however this is linked to the library
int txPin = 1;
int trig = 16; 
int echo = 17; 
int trig1 = 18; 
int echo1 = 19; 
long lecture_echo; 
long cm;
int timeout = 1000;

In the first part i declare rx and tx for communication and set the pins for the sonar.

#include <Adafruit_NeoPixel.h>
#define PIN 3
#define NUM_LIGHTS  20

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LIGHTS, PIN, NEO_GRB + NEO_KHZ800);


//Servo
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
Servo myservo1; 
Servo myservo2; 

I include to libraries in my code. The adafruit neopixel to control the rgb led and the servo library to control my three servo’s.

void setup() 
{

  pinMode(trig, OUTPUT); 
  digitalWrite(trig, LOW); 
  pinMode(echo, INPUT);  

  pinMode(trig1, OUTPUT); 
  digitalWrite(trig1, LOW); 
  pinMode(echo1, INPUT); 

  Serial.begin(9600); 

//servo pins    
  myservo.attach(10);
  myservo1.attach(9);
myservo2.attach(5);

The setup i set the pin as output or input. Further i declared the pin of the servo to 10,9 and 5 which are pwm pins.

}
void loop() 
{ 


 digitalWrite(trig, HIGH); 
 delayMicroseconds(10); 
 digitalWrite(trig, LOW); 
 lecture_echo = pulseIn(echo, HIGH,  timeout*1000); 
 cm = lecture_echo / 58; 

 Serial.print ("sonar 1 in cm: "); 
 Serial.println(cm); 


digitalWrite(trig1, HIGH); 
delayMicroseconds(10); 
digitalWrite(trig1, LOW); 
lecture_echo = pulseIn(echo1, HIGH, timeout*1000); //timeout in micro seconden
cm = lecture_echo / 58; 

Serial.print ("sonar 2 in cm: "); 
Serial.println(cm); 

  delay(timeout); 

The loop i start of with the sonar. When writing and testing code i noticed its in this case best to start with the sonar since i use delays in the loop which had influence on the sonar reading.

 if(cm > 0 && cm < 50 ){

  myservo.write(45);              // tell servo to go to position in variable 'pos'
    delay(500);
    myservo1.write(0);              // tell servo to go to position in variable 'pos'
    delay(500);
      myservo2.write(180);              // tell servo to go to position in variable 'pos'
    delay(500);
 myservo2.write(90);              // tell servo to go to position in variable 'pos'
    delay(500); 
    myservo2.write(180);              // tell servo to go to position in variable 'pos'
    delay(500);
     myservo2.write(90);              // tell servo to go to position in variable 'pos'
delay(500);

      strip.begin();
  strip.show(); 

       strip.setPixelColor(0, 229, 142, 13); 
    strip.setPixelColor(1, 0, 0, 255); 
    strip.setPixelColor(2, 0, 0, 255); 
    strip.setPixelColor(3, 229, 142, 13); 
       strip.setPixelColor(4, 229, 142, 13); 
    strip.setPixelColor(5, 0, 0, 255); 
    strip.setPixelColor(6, 0, 0, 255); 
    strip.setPixelColor(7, 0, 0, 255); 
  strip.setPixelColor(8, 0, 0, 0);
 strip.setPixelColor(9, 0, 0, 255); 
    strip.setPixelColor(10, 229, 142, 13); 
    strip.setPixelColor(11, 0, 0, 255); 
    strip.setPixelColor(12, 0, 0, 0); 
   strip.setPixelColor(13, 0, 0, 255); 
      strip.setPixelColor(14, 0, 0, 255); 
 strip.setPixelColor(15, 0, 0, 255); 
    strip.setPixelColor(16, 229, 142, 13); 
    strip.setPixelColor(17, 229, 142, 13); 
   strip.setPixelColor(18, 0, 0, 255);   
      strip.setPixelColor(19, 0, 0, 255);

  for( int i = 0; i<NUM_LIGHTS; i++){
  //strip.setPixelColor(i, high);
        strip.show();
    }   
    delay(100); 

}

The if statement i use to make the light interact on distance. In my reading of the distance i noticed some false reading of 0. In this if statement it should react when it is larger then 0 and less than 50 cm. First i declare the rotation of the servo which has a max angle of 180 degrees. I use 90 as default and from there it rotates max 90 degree. The rgb led code is for making the “eyes” big when someone come to close.

else
{  myservo.write(90);              // tell servo to go to position in variable 'pos'
    delay(500);
    myservo1.write(90);              // tell servo to go to position in variable 'pos'
    delay(500);
      myservo2.write(90);              // tell servo to go to position in variable 'pos'
    delay(500);


   strip.begin();
  strip.show();

   strip.setPixelColor(0, 229, 142, 13); 
    strip.setPixelColor(1, 229, 142, 13); 
    strip.setPixelColor(2, 229, 142, 13); 
    strip.setPixelColor(3, 229, 142, 13); 
       strip.setPixelColor(4, 229, 142, 13); 
    strip.setPixelColor(5, 229, 142, 13); 
    strip.setPixelColor(6, 229, 142, 13); 
    strip.setPixelColor(7, 229, 142, 13); 
  strip.setPixelColor(8, 0, 0, 255);
 strip.setPixelColor(9, 229, 142, 13); 
    strip.setPixelColor(10, 229, 142, 13); 
    strip.setPixelColor(11, 229, 142, 13); 
    strip.setPixelColor(12, 0, 0, 255); 
   strip.setPixelColor(13, 229, 142, 13); 
      strip.setPixelColor(14, 229, 142, 13); 
 strip.setPixelColor(15, 229, 142, 13); 
    strip.setPixelColor(16, 229, 142, 13); 
    strip.setPixelColor(17, 229, 142, 13); 
   strip.setPixelColor(18, 229, 142, 13); 
    strip.setPixelColor(19, 229, 142, 13);

   for( int i = 0; i<NUM_LIGHTS; i++){
    //  strip.setPixelColor(i, high);
        strip.show();
    }   
    delay(100); 
}
}

The else statement i use as the default setting. All servo rotate to position 90 and the ‘eyes’ get small again.

When testing the code and see it was working i wanted to assemble the light. Something went wrong in the proces.. I wanted to connect on of the sonar and the path underneath broke. Extremely disappointed it happened when everything was tested and was working. I looked at the traces and to my releaved to see that the traces to the other sonar were still intact. The light still function but for now only with one working sonar.

breaksonar One sonar broke when assembling the light

works from Rutger Oomkes on Vimeo.

I am proud of my design and see it is working. For now i have a simple code and movement but when i have some more time i like to experiment with the possibilities and creating more character in the light. I am bummed that the sonar came loose at the last moment but the light is working. With the lessons learned from this assigment i would like to redesign my circuit. Looking back i made a few errors in designing the circuit. So was my intention to use the buttons to change lights and reset. I placed the connectors wrong in my circuit and therefor are the buttons useless. Also i would use seperate power suply for the servo’s. But this will be for a later time.

finaldone Proud of the design

Perfectionizing the design

I fell in love with my design and i enjoy continuing working on it after the fabacademy. I like how it is still inmproving an i like to show how. In the mean time i fixed both sonars and been working improving the code. Where the light only react within one distance it now reacts differently depending how close you are and which sonar register the distance. After research i imported two library for arduino to have a more smooth servo movement and control of the individual lights. The varspeedservo for controlling speed of the servo. With this library i have mmost control over speed setting. For the neopixel i used adafruit. I renamed the distance for the sonar cm and cm1. This way i am able to use both distances for the code.

//Sonar
int rxPin = 0; // this is simular to the int = setting, however this is linked to the library
int txPin = 1;
int trig = 16; 
int echo = 17; 
int trig1 = 18; 
int echo1 = 19; 
long lecture_echo; 
long cm;
long cm1;
int timeout = 1000;

#include <VarSpeedServo.h> 

VarSpeedServo myservo1; 

VarSpeedServo myservo2;

VarSpeedServo myservo3;

const int servoPin1 = 9; 
const int servoPin2 = 10; 
const int servoPin3 = 5; 


#include <Adafruit_NeoPixel.h>
#define PIN 3
#define NUM_LIGHTS  20

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LIGHTS, PIN, NEO_GRB + NEO_KHZ800);


void setup() { 

  myservo1.attach(servoPin1); 
  myservo2.attach(servoPin2);
  myservo3.attach(servoPin3);  


pinMode(trig, OUTPUT); 
digitalWrite(trig, LOW); 
 pinMode(echo, INPUT);  

  pinMode(trig1, OUTPUT); 
  digitalWrite(trig1, LOW); 
  pinMode(echo1, INPUT); 

  Serial.begin(9600); 

    strip.begin();
  strip.clear(); 
  strip.show(); 


} 

void loop() {

  digitalWrite(trig, HIGH); 
delayMicroseconds(10); 
 digitalWrite(trig, LOW); 
lecture_echo = pulseIn(echo, HIGH,  timeout*1000); 
 cm1 = lecture_echo / 58; 

Serial.print ("sonar 1 in cm: "); 
 Serial.println(cm1); 

  digitalWrite(trig1, HIGH); 
delayMicroseconds(10); 
digitalWrite(trig1, LOW); 
lecture_echo = pulseIn(echo1, HIGH, timeout*1000); //timeout in micro seconden
cm = lecture_echo / 58; 

Serial.print ("sonar 2 in cm: "); 
Serial.println(cm); 

  delay(1000); 

 if(cm > 110 && cm < 150 ){

      strip.setPixelColor(0, 0, 0, 0);  
    strip.setPixelColor(1,  0, 0, 0); 
    strip.setPixelColor(2, 0, 0, 0); 
    strip.setPixelColor(3, 0, 0, 0);
       strip.setPixelColor(4, 0, 0, 0);   
    strip.setPixelColor(5, 0, 0, 0); 
    strip.setPixelColor(6, 0, 0, 0); 
    strip.setPixelColor(7, 0, 0, 0);
  strip.setPixelColor(8, 0, 0, 255); 
 strip.setPixelColor(9, 0, 0, 0); 
    strip.setPixelColor(10, 0, 0, 0);
    strip.setPixelColor(11, 0, 0, 0);
    strip.setPixelColor(12, 0, 0, 255); 
   strip.setPixelColor(13, 0, 0, 0); 
      strip.setPixelColor(14, 0, 0, 0);   
 strip.setPixelColor(15, 0, 0, 0); 
    strip.setPixelColor(16, 0, 0, 0); 
    strip.setPixelColor(17, 0, 0, 0); 
   strip.setPixelColor(18, 0, 0, 0);   
      strip.setPixelColor(19, 0, 0, 0);
strip.show(); 

 myservo1.write(30,10,true);  
  myservo3.write(170,50,true);
 delay(500);
 }

  if(cm1 > 110 && cm1 < 150 ){

      strip.setPixelColor(0, 0, 0, 0);  
    strip.setPixelColor(1,  0, 0, 0); 
    strip.setPixelColor(2, 0, 0, 0); 
    strip.setPixelColor(3, 0, 0, 0);
       strip.setPixelColor(4, 0, 0, 0);   
    strip.setPixelColor(5, 0, 0, 0); 
    strip.setPixelColor(6, 0, 0, 0); 
    strip.setPixelColor(7, 0, 0, 0);
  strip.setPixelColor(8, 0, 0, 255); 
 strip.setPixelColor(9, 0, 0, 0); 
    strip.setPixelColor(10, 0, 0, 0);
    strip.setPixelColor(11, 0, 0, 0);
    strip.setPixelColor(12, 0, 0, 255); 
   strip.setPixelColor(13, 0, 0, 0); 
      strip.setPixelColor(14, 0, 0, 0);   
 strip.setPixelColor(15, 0, 0, 0); 
    strip.setPixelColor(16, 0, 0, 0); 
    strip.setPixelColor(17, 0, 0, 0); 
   strip.setPixelColor(18, 0, 0, 0);   
      strip.setPixelColor(19, 0, 0, 0);
strip.show(); 

 myservo1.write(150,10,true);  
  myservo3.write(10,50,true);
 delay(500);
 }

 if(cm > 80 && cm < 110 ){

      strip.setPixelColor(0, 0, 255, 208);  
    strip.setPixelColor(1,  0, 255, 208); 
    strip.setPixelColor(2, 0, 255, 208); 
    strip.setPixelColor(3, 0, 255, 208);
       strip.setPixelColor(4, 0, 255, 208);   
    strip.setPixelColor(5, 0, 255, 208); 
    strip.setPixelColor(6, 0, 255, 208); 
    strip.setPixelColor(7, 0, 255, 208);
  strip.setPixelColor(8, 0, 0, 255); 
 strip.setPixelColor(9, 0, 255, 208); 
    strip.setPixelColor(10, 0, 255, 208);
    strip.setPixelColor(11, 0, 255, 208);
    strip.setPixelColor(12, 0, 0, 255); 
   strip.setPixelColor(13, 0, 255, 208); 
      strip.setPixelColor(14, 0, 255, 208);   
 strip.setPixelColor(15, 0, 255, 208); 
    strip.setPixelColor(16, 0, 255, 208); 
    strip.setPixelColor(17, 0, 255, 208); 
   strip.setPixelColor(18, 0, 255, 208);   
      strip.setPixelColor(19, 0, 255, 208);
strip.show(); 

 myservo1.write(50,20,true);
 myservo2.write(130,20,true);  
  myservo3.write(130,20,true);
 delay(500);

 myservo3.write(50,20,true);  
 myservo1.write(130,20,true);
 myservo2.write(50,20,true);  
delay(500);
 myservo1.write(50,20,true);
 myservo2.write(130,20,true);  
  myservo3.write(130,20,true);
 delay(500);

 myservo3.write(50,20,true);  
 myservo1.write(130,20,true);
 myservo2.write(50,20,true);  
 delay(500);

 }
 if(cm1 > 80 && cm1 < 110 ){

      strip.setPixelColor(0, 255, 173, 196);  
    strip.setPixelColor(1,  255, 173, 196); 
    strip.setPixelColor(2, 255, 173, 196); 
    strip.setPixelColor(3, 255, 173, 196);
       strip.setPixelColor(4, 255, 173, 196);   
    strip.setPixelColor(5, 255, 173, 196); 
    strip.setPixelColor(6, 255, 173, 196); 
    strip.setPixelColor(7, 255, 173, 196);
  strip.setPixelColor(8, 0, 0, 255); 
 strip.setPixelColor(9, 255, 173, 196); 
    strip.setPixelColor(10, 255, 173, 196);
    strip.setPixelColor(11, 255, 173, 196);
    strip.setPixelColor(12, 0, 0, 255); 
   strip.setPixelColor(13, 255, 173, 196); 
      strip.setPixelColor(14, 255, 173, 196);   
 strip.setPixelColor(15, 255, 173, 196); 
    strip.setPixelColor(16, 255, 173, 196); 
    strip.setPixelColor(17, 255, 173, 196); 
   strip.setPixelColor(18, 255, 173, 196);   
      strip.setPixelColor(19, 255, 173, 196);
strip.show(); 

 myservo1.write(50,20,true);
 myservo2.write(130,20,true);  
  myservo3.write(130,20,true);
 delay(500);

 myservo3.write(50,20,true);  
 myservo1.write(130,20,true);
 myservo2.write(50,20,true);  
delay(500);
 myservo1.write(50,20,true);
 myservo2.write(130,20,true);  
  myservo3.write(130,20,true);
 delay(500);

 myservo3.write(50,20,true);  
 myservo1.write(130,20,true);
 myservo2.write(50,20,true);  
 delay(500);

 }

 if(cm > 55 && cm < 80 ){
strip.setPixelColor(0, 229, 142, 13); 
    strip.setPixelColor(1, 229, 142, 13); 
    strip.setPixelColor(2, 229, 142, 13); 
    strip.setPixelColor(3, 229, 142, 13); 
       strip.setPixelColor(4, 229, 142, 13); 
    strip.setPixelColor(5, 229, 142, 13); 
    strip.setPixelColor(6, 229, 142, 13); 
    strip.setPixelColor(7, 229, 142, 13); 
  strip.setPixelColor(8, 0, 0, 255);
 strip.setPixelColor(9, 229, 142, 13); 
    strip.setPixelColor(10, 229, 142, 13); 
    strip.setPixelColor(11, 229, 142, 13); 
    strip.setPixelColor(12, 0, 0, 255); 
   strip.setPixelColor(13, 229, 142, 13); 
      strip.setPixelColor(14, 229, 142, 13); 
 strip.setPixelColor(15, 229, 142, 13); 
    strip.setPixelColor(16, 229, 142, 13); 
    strip.setPixelColor(17, 229, 142, 13); 
   strip.setPixelColor(18, 229, 142, 13); 
    strip.setPixelColor(19, 229, 142, 13);

    strip.show();


  myservo3.write(135,20,true);
 myservo3.write(45,20,true);  
  myservo3.write(135,20,true);
 myservo3.write(45,20,true);  

 }

 if(cm1 > 55 && cm1 < 80 ){
strip.setPixelColor(0, 229, 142, 13); 
    strip.setPixelColor(1, 229, 142, 13); 
    strip.setPixelColor(2, 229, 142, 13); 
    strip.setPixelColor(3, 229, 142, 13); 
       strip.setPixelColor(4, 229, 142, 13); 
    strip.setPixelColor(5, 229, 142, 13); 
    strip.setPixelColor(6, 229, 142, 13); 
    strip.setPixelColor(7, 229, 142, 13); 
  strip.setPixelColor(8, 0, 0, 255);
 strip.setPixelColor(9, 229, 142, 13); 
    strip.setPixelColor(10, 229, 142, 13); 
    strip.setPixelColor(11, 229, 142, 13); 
    strip.setPixelColor(12, 0, 0, 255); 
   strip.setPixelColor(13, 229, 142, 13); 
      strip.setPixelColor(14, 229, 142, 13); 
 strip.setPixelColor(15, 229, 142, 13); 
    strip.setPixelColor(16, 229, 142, 13); 
    strip.setPixelColor(17, 229, 142, 13); 
   strip.setPixelColor(18, 229, 142, 13); 
    strip.setPixelColor(19, 229, 142, 13);

    strip.show();


  myservo3.write(45,20,true);
 myservo3.write(135,20,true);  
  myservo3.write(45,20,true);
 myservo3.write(135,20,true);  

 } 
if(cm > 30 && cm < 55 ){

strip.setPixelColor(0, 255, 79, 16); 
    strip.setPixelColor(1, 255, 79, 16); 
    strip.setPixelColor(2, 255, 79, 16); 
    strip.setPixelColor(3, 255, 79, 16); 
       strip.setPixelColor(4, 255, 79, 16); 
    strip.setPixelColor(5,255, 79, 16); 
    strip.setPixelColor(6, 255, 79, 16); 
    strip.setPixelColor(7, 255, 79, 16); 
  strip.setPixelColor(8, 0, 0, 255);
 strip.setPixelColor(9, 255, 79, 16); 
    strip.setPixelColor(10,255, 79, 16); 
    strip.setPixelColor(11,255, 79, 16); 
    strip.setPixelColor(12, 0, 0, 255); 
   strip.setPixelColor(13, 255, 79, 16); 
      strip.setPixelColor(14, 255, 79, 16); 
 strip.setPixelColor(15, 255, 79, 16); 
    strip.setPixelColor(16,255, 79, 16); 
    strip.setPixelColor(17, 255, 79, 16); 
   strip.setPixelColor(18, 255, 79, 16); 
    strip.setPixelColor(19, 255, 79, 16);

    strip.show();


delay(1000);

  myservo1.write(110,10,true);         

  myservo2.write(130,10,true);         

  delay(1000);

  myservo3.write(10,10,true); 

  delay(1000);

   myservo3.write(90,50,true); 

  delay(1000);  
    myservo3.write(10,10,true); 

     delay(1000);
    myservo3.write(90,50,true);        
}

if(cm1 > 30 && cm1 < 55 ){

strip.setPixelColor(0, 255, 79, 16); 
    strip.setPixelColor(1, 255, 79, 16); 
    strip.setPixelColor(2, 255, 79, 16); 
    strip.setPixelColor(3, 255, 79, 16); 
       strip.setPixelColor(4, 255, 79, 16); 
    strip.setPixelColor(5,255, 79, 16); 
    strip.setPixelColor(6, 255, 79, 16); 
    strip.setPixelColor(7, 255, 79, 16); 
  strip.setPixelColor(8, 0, 0, 255);
 strip.setPixelColor(9, 255, 79, 16); 
    strip.setPixelColor(10,255, 79, 16); 
    strip.setPixelColor(11,255, 79, 16); 
    strip.setPixelColor(12, 0, 0, 255); 
   strip.setPixelColor(13, 255, 79, 16); 
      strip.setPixelColor(14, 255, 79, 16); 
 strip.setPixelColor(15, 255, 79, 16); 
    strip.setPixelColor(16,255, 79, 16); 
    strip.setPixelColor(17, 255, 79, 16); 
   strip.setPixelColor(18, 255, 79, 16); 
    strip.setPixelColor(19, 255, 79, 16);

    strip.show();


delay(1000);

  myservo1.write(70,10,true);       

  myservo2.write(50,10,true);      

  delay(1000);

  myservo3.write(170,10,true); 

  delay(1000);

   myservo3.write(90,50,true); 

  delay(1000);  
    myservo3.write(170,10,true); 

     delay(1000);
    myservo3.write(90,50,true);        
}


if(cm > 10 && cm < 30 ){

    strip.setPixelColor(0, 255, 37, 0);  
    strip.setPixelColor(1,  255, 37, 0); 
    strip.setPixelColor(2, 255, 37, 0); 
    strip.setPixelColor(3, 255, 37, 0);
       strip.setPixelColor(4, 255, 37, 0);   
    strip.setPixelColor(5, 255, 37, 0); 
    strip.setPixelColor(6, 255, 37, 0); 
    strip.setPixelColor(7, 255, 37, 0);
  strip.setPixelColor(8, 255, 255, 255); 
 strip.setPixelColor(9, 255, 37, 0); 
    strip.setPixelColor(10, 255, 37, 0);
    strip.setPixelColor(11, 255, 37, 0);
    strip.setPixelColor(12, 255, 255, 255); 
   strip.setPixelColor(13, 255, 37, 0); 
      strip.setPixelColor(14, 255, 37, 0);   
 strip.setPixelColor(15, 255, 37, 0); 
    strip.setPixelColor(16, 255, 37, 0); 
    strip.setPixelColor(17, 255, 37, 0); 
   strip.setPixelColor(18, 255, 37, 0);   
      strip.setPixelColor(19, 255, 37, 0);
strip.show(); 

delay(2000);

  myservo1.write(150,30,true);      
  myservo2.write(150,30,true);       
  myservo3.write(90,30,true); 

  delay(1000);

  myservo2.write(60,30,true);  
  myservo3.write(10,10,true);
  delay(1000);
  myservo3.write(160,50,true); 
myservo2.write(150,30,true);
  myservo3.write(90,40,true); 
  delay(2000);

}
if(cm1 > 10 && cm1 < 30 ){

    strip.setPixelColor(0, 255, 37, 0);  
    strip.setPixelColor(1,  255, 37, 0); 
    strip.setPixelColor(2, 255, 37, 0); 
    strip.setPixelColor(3, 255, 37, 0);
       strip.setPixelColor(4, 255, 37, 0);   
    strip.setPixelColor(5, 255, 37, 0); 
    strip.setPixelColor(6, 255, 37, 0); 
    strip.setPixelColor(7, 255, 37, 0);
  strip.setPixelColor(8, 255, 255, 255); 
 strip.setPixelColor(9, 255, 37, 0); 
    strip.setPixelColor(10, 255, 37, 0);
    strip.setPixelColor(11, 255, 37, 0);
    strip.setPixelColor(12, 255, 255, 255); 
   strip.setPixelColor(13, 255, 37, 0); 
      strip.setPixelColor(14, 255, 37, 0);   
 strip.setPixelColor(15, 255, 37, 0); 
    strip.setPixelColor(16, 255, 37, 0); 
    strip.setPixelColor(17, 255, 37, 0); 
   strip.setPixelColor(18, 255, 37, 0);   
      strip.setPixelColor(19, 255, 37, 0);
strip.show(); 

delay(2000);

  myservo1.write(30,30,true);       

  myservo2.write(30,30,true);         
  myservo3.write(90,30,true); 

  delay(1000);

  myservo2.write(120,30,true);  
  myservo3.write(170,10,true);
  delay(1000);
  myservo3.write(20,50,true); 
myservo2.write(30,30,true);
  myservo3.write(90,40,true); 
  delay(2000);

}

if(cm > 0 && cm < 10 ){


strip.setPixelColor(0, 255, 0, 0); 
    strip.setPixelColor(1, 255, 0, 0); 
    strip.setPixelColor(2, 255, 0, 0); 
    strip.setPixelColor(3, 255, 0, 0); 
       strip.setPixelColor(4, 255, 0, 0); 
    strip.setPixelColor(5,255, 0, 0); 
    strip.setPixelColor(6, 255, 0, 0); 
    strip.setPixelColor(7, 255, 0, 0); 
  strip.setPixelColor(8, 255, 255, 255);
 strip.setPixelColor(9, 255, 255, 255); 
    strip.setPixelColor(10,255, 0, 0); 
    strip.setPixelColor(11,255, 255, 255); 
    strip.setPixelColor(12, 255, 255, 255); 
   strip.setPixelColor(13, 255, 0, 0); 
      strip.setPixelColor(14, 255, 0, 0); 
 strip.setPixelColor(15,255, 0, 0); 
    strip.setPixelColor(16, 255, 0, 0); 
    strip.setPixelColor(17, 255, 0, 0); 
   strip.setPixelColor(18, 255, 0, 0); 
    strip.setPixelColor(19, 255, 0, 0);

    strip.show();

delay(2000);

  myservo1.write(140,30,true);     

  myservo2.write(40,30,true);        
  myservo3.write(160,30,true); 
   myservo1.write(140,30,true);     
     myservo1.write(40,30,true);                                    
  myservo2.write(160,30,true);         
  myservo3.write(40,30,true); 
}

if(cm1 > 0 && cm1 < 10 ){


strip.setPixelColor(0, 0, 0, 0); 
    strip.setPixelColor(1, 255, 255, 255); 
    strip.setPixelColor(2, 255, 255, 255); 
    strip.setPixelColor(3, 0, 0, 0); 
       strip.setPixelColor(4, 0, 0, 0); 
    strip.setPixelColor(5,255, 255, 255); 
    strip.setPixelColor(6, 255, 255, 255); 
    strip.setPixelColor(7, 255, 255, 255); 
  strip.setPixelColor(8, 0, 0,0);
 strip.setPixelColor(9, 255, 255, 255); 
    strip.setPixelColor(10,0,0,0); 
    strip.setPixelColor(11,255, 255, 255); 
    strip.setPixelColor(12, 0, 0, 0); 
   strip.setPixelColor(13, 255, 255, 255); 
      strip.setPixelColor(14, 255, 255, 255); 
 strip.setPixelColor(15,255, 255, 255); 
    strip.setPixelColor(16, 0, 0, 0); 
    strip.setPixelColor(17, 0, 0, 0); 
   strip.setPixelColor(18, 255, 255, 255); 
    strip.setPixelColor(19, 255, 255, 255);

    strip.show();

delay(2000);


  myservo3.write(160,60,true); 
   myservo3.write(20,60,true); 
    myservo3.write(160,60,true); 
   myservo3.write(20,60,true);
 myservo1.write(50,10,true);       
   myservo3.write(160,60,true); 
   myservo3.write(20,60,true); 
    myservo3.write(160,60,true); 
   myservo3.write(20,60,true);   
  myservo1.write(130,10,true);
     myservo3.write(160,60,true); 
   myservo3.write(20,60,true); 
    myservo3.write(160,60,true); 
   myservo3.write(20,60,true); 
}
else
{
 // strip.begin();

 strip.setPixelColor(0, 45, 126, 6); 
    strip.setPixelColor(1, 45, 126, 6); 
    strip.setPixelColor(2, 45, 126, 6); 
    strip.setPixelColor(3, 45, 126, 6); 
       strip.setPixelColor(4, 45, 126, 6); 
    strip.setPixelColor(5, 45, 126, 6); 
    strip.setPixelColor(6, 45, 126, 6); 
    strip.setPixelColor(7, 45, 126, 6); 
  strip.setPixelColor(8, 0, 0, 255);
 strip.setPixelColor(9, 45, 126, 6); 
    strip.setPixelColor(10, 45, 126, 6); 
    strip.setPixelColor(11, 45, 126, 6); 
    strip.setPixelColor(12, 0, 0, 255); 
   strip.setPixelColor(13, 45, 126, 6); 
      strip.setPixelColor(14, 45, 126, 6); 
 strip.setPixelColor(15, 45, 126, 6); 
    strip.setPixelColor(16, 45, 126, 6); 
    strip.setPixelColor(17, 45, 126, 6); 
   strip.setPixelColor(18, 45, 126, 6); 
    strip.setPixelColor(19, 45, 126, 6);

    strip.show();



  myservo1.write(75,10,true);        
  myservo2.write(90,10,true); 
    myservo3.write(90,10,true);

}
}

finalmovie from Rutger Oomkes on Vimeo.

What i learned and what went wrong.

Where should i start.. I learned so much during this academy. It opened my eyes to see all the different possibilities and techniques. It almost feel like a before fabacademy and after. Espacially the final assignment i had to incorporate all the techniques and method i learned during the coarse. I kept a strict timescedule to be able to finish in time. First i wanted to make the structure as quick as possible to have enough time for the electronics and the coding of the design. Which is for me the most challenging part. I wanted as much time possible for the finishing touch. The acrylic frame went quick smooth and the rotation of the servo’s went well. First problem solved. The base i made a few errors consuming more time i was hoping for. But still had sufficient time for the rest. The designing of the light i combined with developing the pcb for the design. I lost a lot of time milling my pcb board. My mistake was being to eager to have the board ready and overlooking something i could have seen. Breaking the milling bit twice did not help for my time management. But still a week to finish. The 3d printing went smooth though. Soldering the parts took me a long time but i anticipated that. I was pleased that my pcb board worked and was able to put the code on the device. Making all the different parts work took me a long time. I designed my board so all parts would have one powersource. This i decided after my first test with the servo’s and checking the usage of ampere of the servo’s. Did not seemed to high and i expected i could power them with one power supply. I had to improvise to make the servo’s work and used a add on i developed earlier in the course. Now the servo’s were functioning. Making them all rotate using a code took me again more time i was hoping for. Was revealed that the solution was in the code. Made me realize the importance of good coding. One servo did not function anymore and i had to dismantle the light too replace the servo. Do some extra soldering and put the design back together.

By now i only had a few days before the deadline and i fall behind on schedule. I was very eager to make my design functional and had very short nights and very long days to solve the puzzle. When all code was working separate i still had hope to present a working desing for the interview with neil. The last puzzle with lack of sleep was hard to accomplish. The night before i made the movie with how far i got not showing the complete result. The day of the presentation i managed to get all the parts working. The light, movement and showing the distance worked but not the light responding to the distance. This lays in fine tuning the code. The sonar is very sensitive when it come to delays and was not reliable yet. Time to present..

I am proud of what i learned along the way and my design make me smile and be proud. I wished i could show a full functioning model for the final presentation but fine tuning the code was one bridge to far for the final presentation. From having no knowledge in electronics and coding i now understand so much more. I understand i just scratched the surface of the topics but i hope to surpassed the steep learning curve and to improve my skills i learned. My expertise is more in designing and fabrication but it is valuable to have some knowledge about all the topics covered during the fabacademy. Especially when collaborating with other people it is nice to have a insight in what it involves.

I now see possibilities in what is can be archived and have a realistic image of what you encounter in the process. Also the importance of knowing how to debug. Still no expert in debugging but compared to six months ago i feel like a expert.

This has been a mind blowing six months and i like to thank Waag Amsterdam for making this possible. Also i like to thank Henk Buursen for being a great instructor in this period. Giving me and the other students the support we needed and created a fun atmosphere to learn. Also i have learned a great deal from my fellow students during this coarse. What i said… Mindblowing!