I have some previous CAD experience on Onshape, however they were all simple gemoetric stuff, for example.
\r\n\r\nBut I'd like to challenge myself, by CADing something curve-y and circular. So I chose to CAD a fan.
\r\nThe inner blades were created by filling a 3D fit spline and a sketch curve on the cylinder.
\r\n\r\nThe side of the fan was created by bridging curves between the bottom and top circles.
\r\nThe top of the fan were extruded conic sections.
\r\n\r\nThis was surprisingly successful!
\r\n \r\nFor my first attempt in designing a press fit kit, I wanted to make some sort of ball joint out of cardboard. So I first CADed a ball joint.
\r\nSo then I would take cross sections of the design and cut out rectangles in order to make the cardboard cutouts that would create such ball joint.
\r\nBut before I start printing, there are several tests that had to first be done. A test for the optimal settings for laser cutting cardboard and a kerf test since the cardboard\r\n pieces need to be pretty well fitted.
\r\nThe tests showed that the laser cutter should be ran at 100% power and 10% speed, and the optimal size for slots are 4mm, considering kerf.
\r\nSo here is the final product, plus a paper cutout I used to test out the design.
\r\nHowever, functionality wise, this did not function as expected, due to the two main issues - the thickness and rigidness of the cardboard. \r\n I think that doing cross sections of a CADed model introduced a very optimistic point of view for desining press fit kits in general, since I lost the sense of scaling and how it would look in real life.
\r\nUsing the time I have left, I tried to make somthing more...artistic. (Like a pawn in chess)
\r\nSo the main lesson from this is that I learnt that I am not that artistic and stuff comes out pretty differently than what I usually imagine/CAD.
\r\n\r\nYay! For vinyl cutting (which thankfully does not require that much art ability), we learnt how to use mods to process an image.
\r\nAnd for the results...
\r\nNow we have access to a mill! So first thing I had to do was test the boundaries and characterize the mill and it's limits.
\r\nSo we did a test print using a 1/64 inch end mill, and turns out it worked out pretty well
\r\nThe removing stopped at around 0.015 (1/64 is 0.0156), while the other was fine up till 0.001, however I don't think the copper itself adheres well to the bottom plate.
\r\nI firstly used mods to generate the outline and paths for the mill to mill the traces
\r\nHowever, I made two mistakes. First time I took the wrong png file, and on the second try I adjusted the origin of the mill too far away from \r\n where I was cutting the piece, and since the piece is not totally flat, the cut did not go through all the copper.
\r\n \r\nThen I redid it and soldered all the parts on. I used solder paste and the technique of using the solder as an adhesive. However the last strip of copper burnt off, possibly because I had the iron it for too long.
\r\nI guess fourth time's the charm.
\r\nNow I had to install the firmware into the microprocessor, which involved installing the software and a driver.\r\n In order to program our board, I need another programmer to flash our board. After that I blew all the fuses.
\r\nTo test if my programmer works, I used it to flash another unfinished programmer.
\r\nIt works!
\r\n\r\n\r\nAs always, we must first test the limits and specs of the 3D printer.
\r\nSo a couple test prints were done. Including tests for wall thickness and supports.
\r\nFeaturing Xiqing
\r\nHere are the results:
\r\nClearance
\r\nFree overhang
\r\nAnchored overhang
\r\nAnisotropy
\r\nWall thickness
\r\nUnsupported Angle
\r\n\r\n
As for my project, I wanted to print a sphericon. It is known to be a 'roller' meaning it brings all points of\r\n it's surface to contact with the floor while rolling.
\r\nIt is first made by combining two rotated bicones.
\r\nThen taking out some parts to make it look fancier.
\r\nThis is the final product.
\r\nHowever there are some parts that are printed on the board with supports. And these supports could not be fully removed, so it wasn't \r\n as smooth as expected.
\r\nIt does roll quite smoothly though!
\r\nFor 3D scanning, I used the 3D systems SENSE2 scanner - and we are scanning tape!
\r\nThe process was slightly tedious, since I had to slowly and steadily go around the object. ( Which was also surprising inconvenient since the table was rectangular)
\r\nHere's the result! Apparently it also scanned the little piece I used to fix the tape in place. But with some repairing it gives a pretty good 3D representation!
\r\nIt's the week where we make a board for a microprocessor!
\r\nFirst thing's first, we need to design the circuits and the board. So I\r\n had to learn Eagle.
\r\nFirst we get parts that correspond to parts on the board, then connect them correctly on the schematic.\r\n Then we can use that to create the board.
\r\nThe issue here is that the traces were actually stuck to each other. It turns out the design rules is slightly off to the png mods.\r\n So I just used the otherMill, since it takes in a .brd file instead of a png.
\r\nNow we solder parts!
\r\nWith a little handy dandy coding and help from my friend's unfinished (still has older bridge) ICP.\r\n I was able to power and code my attiny44.
\r\n\r\n \r\n\r\n\r\n \r\nI decided to use this week to make a design for my final project - a controlled labyrinth
\r\nSo since there are two axis of freedom for the maze, I had to create some mechanism for it to rotate. As you can see the outer square would be connected two stands such that it can rotate in one axis, while the inner square would be connected to the outer square in another axis, such that the inner square can rotate in essentially both axes!
\r\n\r\nAfter designing, I had to draw out the pieces of the design.
\r\nThen with a some help from Anthony, we designed the toolpaths on MasterCAM. And then we are ready to print!
\r\nThe architecture wood shop had the onsrud machine which is VERY fast for a router.
\r\n \r\nIt even switches tools automatically!
\r\nAs you can see OSB is not the best material, the wood board itself was kind of curved initially, but this shouldn't be a huge issue,\r\n since my parts are relatively big. One thing worth noting is that since the wood is kept on the table by a vacuum, we did not cut all the way through the wood, since then the vacuum would be lost and the parts would not stay to the table. So in order to maintain the parts on the board, we did not drill all the way through, leaving a thin layer of wood called the 'onion skin' that we can break off later.The resulting parts were then broken off the onion skin and it's time to file everything down!
\r\nThen we had to glue the parts! Since these parts are relatively large, we had to come up with some special ways to clamp them down.
\r\nSo for the big outer square, we used right angle clamps to fix the corners so the square doesnt tilt and maintains a right angle, however, this fixes the anlge, but doesn't actually provide any force to fix the wood parts. So we then tied a belt around the whole square, and then tightened the belt to apply force to all sides at once without using 4 intersecting clamps.
\r\nFor the base, we used pipe clamps to tighten the supports on the sides. But then I realized that these stands were not very perpendicular, so later I also placed the outer box in the middle so that the supports were clamped against the inner box which is sufficiently perpendicular. In hope to get them as close to perpendicular as possible.
\r\n\r\nAnd here's the final product! Since I did not have the axles yet, I used some pencils to demonstrate it's functionality.
\r\nRecall from week 5, we made a board with a button and a light. So now we need to make it do something
\r\nDuring programming, we need two things, a programmer and a way to power the board while it is getting programmed. Luckily, my friend's programmer's solder bridge was not desoldered yet, so I was able to use that to power my board.
\r\nThe first step was to look up the attiny44 arduino pinout. Since I am using arduino to program the board, this is necessary since the pin names on the datasheet for the AT44 is not the same as the pin number used in arduino to program them.
\r\n\r\nRecall that the button is a PULLUP, so by initiating the button pin as an input and the LED pin as an output. We can code the logic between these two buttons such that this code sets the LED pin to high when the button is LOW. Since the button pulls the voltage to low.
\r\nSo before programming, there is some setup to be done. We must first download the board (attiny) libraries, by getting the link to it online, and adding to the places arduino searches for board libraries. After doing so, we canset it in board manager.
\r\nPick ATTINY44 as the board and tinyUSB as the programmer, also pick the clock to the internal 1 MHz clock.
\r\nIn the end I was able to power and code my attiny44.
\r\nSoooo after my failed attempt on a chess piece from laser cutting week. I aimed to redeem myself by casting a chess piece instead.
\r\n \r\nSo my second attempt is to mold and cast a chess piece. First step was to CAD a positive of the chess piece to make the mold. Since I had the CAD from previous weeks, this wasn't too hard. Then put this model into SolidWorks and design some toolpaths, (in which case 2D adaptive clearing wasn't actually half bad) then we can mill this guy from wax!
\r\nHere's some milling live action! So the first pass made the rough shape of the pawn, and we did a second more detailed pass to get the pawn as round and smooth as possible! This was all done during the design of toolpaths, where the second pass was designed with a smaller shifting distance
\r\nNow it's time to make the mold!
\r\nI made a the mold with OOMOO, a silicone mold rubber solution. (It's quite a mess) What I had to do was take one part of solution A (so they call it), and one part of solution B and combining them, while mixing them as much as possible. To get an accurate amount of OOMOO, I first measured the volume of the chess mold mold by pouring water into the mold and marking the amount. Then I filled the amount with half solution A and half solution B. So to not waste/lack an OOMOO, since the pawn was pretty close to the top of the mold.
\r\nRepeat this process twice, get two halves of the mold and we are ready to cast!
\r\nI decided to use hydro-stone, which is obviously the best material for a chess piece, who would want a rubber pawn? Hydrostone is a powder, that when mixed with water forms a stone like solid overtime. What surprised me was that the ratio between hydrostone and water was very skewed. It was like 9 part powder to 1 part water. So the solution is ectremely saturated, and a slight offset woulc make a uge difference in the consistency of the mixture and probably the final product.
\r\nIn order to keep the two molds together, I clamped the two halves of the molds together. However there was no way to guarantee that they were perfectly inline. If I wanted to, a good idea would be to create some linkage between the two molds, for example a hole in one and a part that sticks out in the order. BUT this would require me to make two different molds for the chess pieces, which in my opinion is an extreme waste of time for something not that accurate. I then cut a hole in the top in order to pour the stone solution in from the hole. Then it was only a matter of time.
\r\nThe final product had a little stub, and it was slightly off centered (since I eyeballed the clamping of the two halves).\r\n But the stub was easily removed and here is the (far superior) chess piece!
\r\nFor part of my final project, I have to read from an accelerometer to control the labirinth. So I'll try to make this work.
\r\nThe first challenge to this is milling the accelerometer. It has extremely small pads, smaller than what the 1/64 inch end mill could mill, so the pads on the accelerometer were actually less than 1/64 inch apart.\r\n Thankfully Neil actually had a design that had smaller traces, but still worked just as well. The design made copper connections on the board that are smaller than the pads on the accelerometer, so effectively the pads on the accelerometer were bigger than the traces on the board, which is a very smart solution. \r\n
\r\n \r\nThe next challenge is to solder these small pads on the board. I used a technique called reflow. Which involves putting solder paste on the pads, putting the part on the paste and heating the whole thing up and the solder paste would naturally bind to the closest copper trace.\r\n Hoping that there are no shorts underneath. This strategy works surprisingly well, even though it did take multiple tries to get right, since it is very easy to have too much solder paste and create a short. Another thing however, is that it is very to easy to overheat the accelerometer in the process, which did happen once.
\r\nI also then made an FabFTDI, but it only transmits in 4800 baud since it uses an AT45 which is not enough for the accelerometer. But I could\r\n use it to power the board while I program it. But in the end I still have to use an actual FTDI to get the data.
\r\nFabFTDI
\r\nFTDI cable
\r\nUsing the \"make -f \"makefile\"\" command to first make the hex file. Then using make -f \"makefile\" program-usbtiny, I loaded the porgram into the board.\r\n (which under the hood is avrdude \"-p t45 -P usb -c avrisp2 -U flash:w:$(PROJECT).c.hex\")\r\n
\r\nThen we just open the python file that parses the data. (Which is basically bytes that represented \"1\", \"2\",\"3\",\"4\", then 3 2byte numbers. Each represented x y z, and range from -255 to 255, with the first byte descibing if the number is negative or not, and the second byte being a value from 0 to 255. Along with a basic low pass filter.\r\n By using a running average.
\r\nSo what we need to do is write code that continuously takes in data, until the starting frame is matched (so a continuous triplet of 1 2 3), then we can read the next 6 datapoints reliably to get the acceleration in the X,Y and Z axis by doing some basic algebra.
\r\nFirst step is to make the board for the motor driver. However I did not check what regulator the lab had,\r\n so I milled a board for the LM2940, only to realize we only had ZLDO1117s. So that was an unfortunate waste of time.
\r\nLM2940
\r\nZLDO1117
\r\nSo after uploading the code on the board (neil's). We first connect the board to an actual power source, since the USBport\r\n does not give enough power to power the servo. (Beware since reversing polarity might fry the regulator, which I almost did). What was interesting though is that I tested out multiple servos, and they all took different amount of current(duh), but some were actually able to reach max torque just by computer connection! If the pulse width modulation is coded effectively and correctly, it could actually use the current more effectively.\r\n
\r\nAlso the servo takes in VCC, GND and signal. The signal is a PWM meaning the pulse controls the angle the servo goes to, which is slightly less of a mess compared to steppers and DC motors.\r\n My code also uses software PWM, but there is also hardware PWM in attinys, which allows concurrent processing since the PWM is maintained through the hardware of the servo. \r\n
\r\nAnd it workss!
\r\nSo after creating the servo controller and and Accelerometer reading chip, I had to combine these two. My first intuitive idea \r\n was to have these two directly talk to each other through UART. So I created a little wired mechanism to give me accesss to ground and a pin on the motor controller to connect it to the accelerometer.
\r\nHowever, possibly because I don't know how to code efficiently in C using\r\n bit shifts, the calculations/code required take slightly too much memory to be embedded on a chip, it is also extremely frustrating to debug since you never know what's going on between the two boards.
\r\n\r\n \r\nSo instead, I am going to make a python script that does all the math and reads in accelerometer and writes to the servo in one UART line. This allows me to print out the incoming data and outgoing data, to facilitate debugging and allows me to do all the math on my computer, which is significantly faster and less memory consuming than putting the task on one particular board.
\r\nThe accelerometer to python part was done in input week, however the python to servo part was not.
\r\nAs I was doing this I have learnt about the Arduino IDE and libraries. I learnt that the AT44 is not compatible with the servo library for some reason, possibly because the AT44 uses an 8 bit, while the servo library is designed for 16 bit timers. So my solution was to hard code PWM in arduino, effectively making software PWM.
\r\n\r\n Then I also learnt that the typical serial library in arduino is also not compatible with the At44. So after a lot of searching, I have learnt that I can use the softwareserial library. So by doing the mapping and math, specifically mapping the acceleration measured into an angle, then to a PWM pulse length. I was able to make the python script send out the length of the PWM. So the servo controller can do a minimum amount of math. Below is the software PWM code in arduino, with smoothing.
\r\n\r\n \r\n `{`void turn(int pulse,int old){`}
\r\n {`int diff = 0;`}
\r\n {`for (int i =0;i<5;i++){`}
\r\n {`diff = int(old+i/5*(pulse-old));`}
\r\n {`digitalWrite(A7, HIGH); // sets the digital pin 13 on`}
\r\n {`delayMicroseconds(diff); // waits for a second`}
\r\n {`digitalWrite(A7,LOW); `}
\r\n {`delayMicroseconds(20000-diff);`}
\r\n {`}`}
\r\n {`}`}\r\n `
\r\n One issue I ran into was the timing, since the servo can only response/read at such a speed, since it takes time for the servos to spin. The accelerometer spits out\r\n information at 9600baud rate, so this was extremely fast compared to the spin time of the servo. So I changed the rate at which the PYTHON script sends info to the servo, while continuously reading information from the Accerlerometer,\r\n this allows a continuous stream of information for the low pass filter, so I would maintain a steady and accurate measurements while not having the servo spazz out and delay due to amount of information it is receiving.\r\n
\r\n\r\nPS this is an old video before the servo was smoothed out.
\r\n\r\n Since I have some experience in Unity before, I decided to do a simulation of what I hope to achieve in Unity. Since Unity has an in built physics engine, all I would need to do is make a plane and a ball, and send data to Unity that could allow it to constantly update the tilt of the plane.\r\n
\r\n\r\nMy first intuitive thought was use some sort of serial functionality in Unity to directly get data from the accelerometer, since that is the most straightfoward solution.
\r\nThe main way to use Serial in Unity is by using the .NET framework and using System.IO.Ports, and after reading the data from the accelerometer I would have to parse it in Unity, and do the math to convert it to an angle.
\r\n\r\nHowever, there is a same issue - the raw accelerometer sends info too rapidly for unity to respond. As a result it misses a bunch of data and is really laggy, unclear why.
\r\nSo instead I decided to learn and try something new - Sockets.
\r\nSo I first tried to make a simple socket server and client work in pure python.
\r\nNormally one would have to do post and get requests to talk to servers, and those take a significant amount of time toget around. However, sockets are able to open a continuous stream of communication that goes both ways. And this is how most games/chatrooms are able to do near instantaneous responses.
\r\nWhat the server code is doing is opening a listener on localhost that would print out any messages that gets sent to them. And the client is simply another python script that sends 'foo' to a socket at a specific address every 0.1 seconds. And the result is the server constantly printing 'foo'.
\r\nServer
\r\nClient
\r\nAfter this worked, since I already had a python script that parsed the accelerometer data, all I needed to do was instead of sending serial data to the motoy, I had the python script do more math to convert accelerometer data into an angle (specifically it was the inverse sine of the ratio between acceleration measured in that axis over the max acceleration (which is 255 AKA 1g)). I had my accelerometer script send angles to a socket instead of PWM times through Serial.
\r\nUsing System.Net and System.Net.Sockets, I was able to create a socket server on UNity.
\r\nServer
\r\nNow what we need to do is start a tcp server stream to continuously update the angle of the virtual board. So next step is actually make the plane and controls in UNity, which was not hard since I am familiar with UNity, but it involves setting the gameobject transform into the correct quaternion. Finally add a ball, put a tennis ball texture and let Unity physics take care of the rest!
\r\nIt's wildcard week and me and my friend Kevin chose to do Inflatables, since it would teach us a very useful skill - sewing.
\r\nOur original plan is to attempt to make a pokemon called Corsola. Since we thought of making something that is big and decorative, possibly something to hang somewhere in our room, so we first thought of making a tentacle like structure, but in the end we resorted to something on the cute side.
\r\nFor planning, we first made a quick cylinder to test out the dynamics of inflatables. After seeing how a simple cylinder inflates, we made a rough sketch of the 2D map of Corsola, which would consist of basically cones and ellipses like sheets that would create a obloid like shape. After planning, we also cut a quick paper mesh and taped that together to create a rough prototype to see if the idea of an obloid
\r\nNext step was to learn how to use the sewing machine! So the machine actually uses two threads and criss crosses them to imitate 'sewing', there was a lot of set up that included hooking up the thread in the correct way such that nothing tangled. But after everything is set up. All we had to do is step on the pedal and the fabric automatically moves and the machine sews! All we need to do is guide the fabric to the correct position!
\r\nThe process was kind of rough due to HUGE fabric we were using, but it was fine since precision really doesn't matter on such a big scale, and since the traces are getting flipped inside out, the sewing job does not need to be particularly nice too.
\r\nFinally we created our big obloid, we also had a hole on top so that the ball doesn't just burst when it's filled with air! This took a surprising amount of time, so unfortunately we only had time to put one cone (tentacle thingy) on! However, learning sewing was very fun and a very practical skill to have!
\r\nEverything is more entertaining when it's big! For example, toy/remote control cars are fun and all, but it seems like the bigger they are, the more fun it provides, toys like plushies or even rubix cubes, I'll be down to have a huge version of. But there is one issue - when these toys get out of scale, it's sometimes hard to play with them - how would you spin a huge rubix cube?
\r\nA difficult part of making huge games/toys is the actuating. And there's one particular toy that I'd like to see a big version of - the labyrinth.
\r\nSo since there are two axis of freedom for the maze, I had to create some mechanism for it to rotate. As you can see the outer square would be connected two stands such that it can rotate in one axis, while the inner square would be connected to the outer square in another axis, such that the inner square can rotate in essentially both axes!
\r\n\r\nAfter designing, I had to draw out the pieces of the design.
\r\nThen with a some help from Anthony, we designed the toolpaths on MasterCAM. And then we are ready to print!
\r\nThe architecture wood shop had the onsrud machine which is VERY fast for a router.
\r\n \r\nIt even switches tools automatically!
\r\nAs you can see OSB is not the best material, the wood board itself was kind of curved initially, but this shouldn't be a huge issue,\r\n since my parts are relatively big. One thing worth noting is that since the wood is kept on the table by a vacuum, we did not cut all the way through the wood, since then the vacuum would be lost and the parts would not stay to the table. So in order to maintain the parts on the board, we did not drill all the way through, leaving a thin layer of wood called the 'onion skin' that we can break off later.The resulting parts were then broken off the onion skin and it's time to file everything down!
\r\nThen we had to glue the parts! Since these parts are relatively large, we had to come up with some special ways to clamp them down.
\r\nSo for the big outer square, we used right angle clamps to fix the corners so the square doesnt tilt and maintains a right angle, however, this fixes the anlge, but doesn't actually provide any force to fix the wood parts. So we then tied a belt around the whole square, and then tightened the belt to apply force to all sides at once without using 4 intersecting clamps.
\r\nFor the base, we used pipe clamps to tighten the supports on the sides. But then I realized that these stands were not very perpendicular, so later I also placed the outer box in the middle so that the supports were clamped against the inner box which is sufficiently perpendicular. In hope to get them as close to perpendicular as possible.
\r\n\r\nAnd here's the final product! Since I did not have the axles yet, I used some pencils to demonstrate it's functionality.
\r\nLater on though, I changed the design slightly. Since the glue that were holding the stands were no where strong enough to actually keep them perpendicular. I made them into blocks instead and did the classic trick of screwing the stand to the block, and the block to the base.
\r\nI also made axles to rotate the squares, since they had quite big holes, I had to 3D-print the custom axles, to match the length and size of the labyrinth.
\r\nSo there were a couple issues with my design, I realized since the wood was relatively heavy, weight distribution actually became extremely important and played a huge role in distributing the torque on the servo.
\r\nAnd another issue was the material choice - wood was actually extremely heavy for something this big, I could've easily used something lighter like acrylic or cardboard that would've made my life easier. So in the end I replaced the inner square with a cardboard square instead.
\r\nThe first challenge to this is milling the accelerometer. It has extremely small pads, smaller than what the 1/64 inch end mill could mill, so the pads on the accelerometer were actually less than 1/64 inch apart.\r\n Thankfully Neil actually had a design that had smaller traces, but still worked just as well. The design made copper connections on the board that are smaller than the pads on the accelerometer, so effectively the pads on the accelerometer were bigger than the traces on the board, which is a very smart solution. \r\n
\r\n \r\nThe next challenge is to solder these small pads on the board. I used a technique called reflow. Which involves putting solder paste on the pads, putting the part on the paste and heating the whole thing up and the solder paste would naturally bind to the closest copper trace.\r\n Hoping that there are no shorts underneath. This strategy works surprisingly well, even though it did take multiple tries to get right, since it is very easy to have too much solder paste and create a short. Another thing however, is that it is very to easy to overheat the accelerometer in the process, which did happen once.
\r\nI also then made an FabFTDI, but it only transmits in 4800 baud since it uses an AT45 which is not enough for the accelerometer. But I could\r\n use it to power the board while I program it. But in the end I still have to use an actual FTDI to get the data. (Later on though I made the better FabFTDI with the ATmega.
\r\nFabFTDI
\r\nFTDI cable
\r\nUsing the \"make -f \"makefile\"\" command to first make the hex file. Then using make -f \"makefile\" program-usbtiny, I loaded the porgram into the board.\r\n (which under the hood is avrdude \"-p t45 -P usb -c avrisp2 -U flash:w:$(PROJECT).c.hex\")\r\n
\r\nThen we just open the python file that parses the data. (Which is basically bytes that represented \"1\", \"2\",\"3\",\"4\", then 3 2byte numbers. Each represented x y z, and range from -255 to 255, with the first byte descibing if the number is negative or not, and the second byte being a value from 0 to 255. Along with a basic low pass filter.\r\n By using a running average.
\r\nSo what we need to do is write code that continuously takes in data, until the starting frame is matched (so a continuous triplet of 1 2 3), then we can read the next 6 datapoints reliably to get the acceleration in the X,Y and Z axis by doing some basic algebra.
\r\nFirst step is to make the board for the motor driver. However I did not check what regulator the lab had,\r\n so I milled a board for the LM2940, only to realize we only had ZLDO1117s. So that was an unfortunate waste of time.
\r\nLM2940
\r\nZLDO1117
\r\nSo after uploading the code on the board (neil's). We first connect the board to an actual power source, since the USBport\r\n does not give enough power to power the servo. (Beware since reversing polarity might fry the regulator, which I almost did). What was interesting though is that I tested out multiple servos, and they all took different amount of current(duh), but some were actually able to reach max torque just by computer connection! If the pulse width modulation is coded effectively and correctly, it could actually use the current more effectively.\r\n
\r\nAlso the servo takes in VCC, GND and signal. The signal is a PWM meaning the pulse controls the angle the servo goes to, which is slightly less of a mess compared to steppers and DC motors.\r\n My code also uses software PWM, but there is also hardware PWM in attinys, which allows concurrent processing since the PWM is maintained through the hardware of the servo. \r\n
\r\nAnd it workss!
\r\nSo after creating the servo controller and and Accelerometer reading chip, I had to combine these two. My first intuitive idea \r\n was to have these two directly talk to each other through UART. So I created a little wired mechanism to give me accesss to ground and a pin on the motor controller to connect it to the accelerometer.
\r\nHowever, possibly because I don't know how to code efficiently in C using\r\n bit shifts, the calculations/code required take slightly too much memory to be embedded on a chip, it is also extremely frustrating to debug since you never know what's going on between the two boards.
\r\n\r\n \r\nSo instead, I am going to make a python script that does all the math and reads in accelerometer and writes to the servo in one UART line. This allows me to print out the incoming data and outgoing data, to facilitate debugging and allows me to do all the math on my computer, which is significantly faster and less memory consuming than putting the task on one particular board.
\r\nThe accelerometer to python part was done in input week, however the python to servo part was not.
\r\nAs I was doing this I have learnt about the Arduino IDE and libraries. I learnt that the AT44 is not compatible with the servo library for some reason, possibly because the AT44 uses an 8 bit, while the servo library is designed for 16 bit timers. So my solution was to hard code PWM in arduino, effectively making software PWM.
\r\n\r\n Then I also learnt that the typical serial library in arduino is also not compatible with the At44. So after a lot of searching, I have learnt that I can use the softwareserial library. So by doing the mapping and math, specifically mapping the acceleration measured into an angle, then to a PWM pulse length. I was able to make the python script send out the length of the PWM. So the servo controller can do a minimum amount of math. Below is the software PWM code in arduino, with smoothing.
\r\n\r\n \r\n `{`void turn(int pulse,int old){`}
\r\n {`int diff = 0;`}
\r\n {`for (int i =0;i<5;i++){`}
\r\n {`diff = int(old+i/5*(pulse-old));`}
\r\n {`digitalWrite(A7, HIGH); // sets the digital pin 13 on`}
\r\n {`delayMicroseconds(diff); // waits for a second`}
\r\n {`digitalWrite(A7,LOW); `}
\r\n {`delayMicroseconds(20000-diff);`}
\r\n {`}`}
\r\n {`}`}\r\n `
\r\n One issue I ran into was the timing, since the servo can only response/read at such a speed, since it takes time for the servos to spin. The accelerometer spits out\r\n information at 9600baud rate, so this was extremely fast compared to the spin time of the servo. So I changed the rate at which the PYTHON script sends info to the servo, while continuously reading information from the Accerlerometer,\r\n this allows a continuous stream of information for the low pass filter, so I would maintain a steady and accurate measurements while not having the servo spazz out and delay due to amount of information it is receiving.\r\n
\r\n\r\nPS this is an old video before the servo was smoothed out.
\r\nNow all mechanisms are ready, it's time to intergrate them. First thing to do is optimize the data being sent from PYTHON to the accelerometer. So since the PWM range goes from 300ms (0 degrees) to 2000ms (180 degrees), in order to minimum calculations on the motor driver, the python script first sends a period before any data point, and then 4 digits that encode the PWM length.
\r\n\r\nNow here's the mistake, I assumed that everything would be fine as long as I do the same thing for the other motor. However, since I was determined to control both motors from one motor control. Here's when stuff went south.
\r\nSo first on the data side, I chose to be as efficient as possible but still send the right information. So I scaled the PWM to a number between 0 and 99 and sent the data in the form of '.XX,YY' With the period prefacing the X pwm and comma prefacing the Y pwm. This could then be scaled back into a PWM on the motor side. However...
\r\nIt does not work! I assumed that it was an issue of power since I was powering two motors through my computer. So I tried lowering the torque by centering the square (which surprising allowed it to tilt a little more) and lubricating the axles, but all in vain.
\r\nSo I lived at EDS, using their power source and oscilloscope to debug this thing. So apprently it wasn't a power/torque issue. My most likely guess is that it is an issue of delays.
\r\nMy first guess is that it is an issue since I am operating two motors one after another, this big delay was enough to interfere with me reading the data (even though I have symbols that prefaces the data). I tried using hardware PWM so that I can concurrently control the motor and receive input, but apparently, softwareserial is not compatible with hardware PWM.
\r\n\r\n I realized that most drivers out there are not compatible with anything, and I guess knowing how to code everything from scratch is probably the best move. Given Serial and Servo libraries aren't compatible with At44, and Softwareserial isn't compatible with hardware PWM.\r\n
\r\n\r\nSo I decided to settle for a one axis game - instead I'll make a tiltable pachinko machine!
\r\nA pachinko machine is almost like pinball, but you just let the ball drop and hope it lands on a slot that has a reward.
\r\nSo here's my final project and some vids of it in action!
\r\nHi! Im Jeremy Ma! A international sophomore in MIT majoing in 6-9 [Computation and Cognition]hehe). I've gotten pretty into dance in my years in MIT.
\r\nI'm interested in how we perceive specifically the overlaps between computation and human percpetion.
\r\nI also do a good amount of making for fun (less so now), here's some examples.
\r\n\r\n