-
PCB Ordered
03/31/2015 at 05:39 • 0 commentsFinally reviewed and ordered the PCB for this project. I used Seeed Studio Fusion which offers $10 for 10x 5cm*5cm boards. This project was a bit bigger and I opted for a blue board, so the total came out to $40 with shipping.
I'm nervous and excited about this; I hope I didn't mess anything up. This is easily the most nerve-wracking part of this project since I work best by iterating, testing and adapting. This is the exact opposite, since it has to be right the first time or there and financial and temporal penalties. I guess we'll see in a few weeks.
Next step is to go back to work on hardware. I still have wire harnesses to strip and solder. However, once that's done, I have a lull until the board is ready. Who knows, I might actually PLAY Kerbal Space Program!
-
Displays Tested!
03/29/2015 at 05:04 • 0 commentsFinally got to the displays. I had a bit of trouble with them, but was able to resolve all the issues in the span of a couple of hours.
The biggest problem I encountered was that writing to the displays too quickly was causing collisions where the subsequent write was ignored. I wasn't sure why this was happening initially since it was happening when I ran a test script, but not when I did it manually. Anyway, I added a delay and it worked fine. I got the timer down to 25ms, but thought I'd try adding a linefeed when the Arduino was working. This got the overall time down to 4ms, so I'm sticking with that solution.
I had a few other minor changes to make, but now the 7-segment displays and LED bargraphs are working as expected! I'm really excited since that's a major milestone. I still have to review the PCB diagram before ordering, but we're really getting close to full prototype status!
-
Merged to Master
03/28/2015 at 05:51 • 0 commentsProgress has been coming along well. I implemented all the configuration reading and object instantiation today. Tonight I took it out for a test spin with KSP. The joysticks are working* and so is the throttle. The buttons are sort of working, but I think that's mostly due to bad wiring. I had to do some troubleshooting and bug fixing, but it's all working now.
I made the final checkin to the Pythonify branch and merged it back into the master. This was a big milestone. Although I hadn't expected this hiccup, getting back to where I was is somewhat of an accomplishment.
Next step is to wire up the 7-segment displays and bargraphs and confirm that works. Once that's done, I can order the PCB. After that it's back to hardware to finish soldering up all the buttons and wiring. With all of that done, I'll be ready for the full prototype hardware test. I'm hoping I can get to that stage within a month.
-
Getting close
03/27/2015 at 05:07 • 0 commentsReally getting close to the state I was in prior to the memory issue. I finished converting all the classes to Python and added some printouts to help debug formatting. Using this I was able to test the formatter for the 7-segment displays to make sure it works within the constraints.
I worked on kapcom.py and tying all the pieces together. I was able to create instances of all the controls and simulate a run and everything worked well. Now I'm working on putting the device settings in a configuration file. After looking into the options, I've decided to go with JSON. It might be a bit harder to work with manually, but I think it's worth it given how easy it is to parse in Python. I might even add an interactive configurator since that should be fairly easy.
I still have to work on getting the values from JSON and creating instances based on those values. That's pretty much the last piece. I think I can take a test run tomorrow night maybe. If not, definitely over the weekend.
Once I actually test everything, I should be able to order my PCBs. Then it's back to the hardware side of things. I have a lot of connections and wires to solder to hook up all my goodies.
-
Progress
03/26/2015 at 06:01 • 0 commentsIt's been a while since I last posted so I figured I'd update my progress. I took a short hiatus to ease my frustration after the memory setbacks. Since picking things up again, I've adapted an Arduino/Python library to send commands and results over serial. I did end up strippingf out some unnecessary functionality and made the protocol a bit leaner.
So far I'm getting 4ms per update...not great given how many input/outputs there are. I added in a subscription and aggregation command, but I haven't tested to see the speed difference yet. I might also be able to update different types of hardware with different frequencies.
Meanwhile, I've also adapted most of the C classes to Python and pin, joy and mod are working well so far. With a bit more work on the main KAPCOM class, I might be nearly back to where I was functionality-wise.
-
Bad News
02/28/2015 at 05:37 • 0 commentsFirst the good news, I got past the memory issues I was having and started working on the displays. I also replaced all the LEDs in the buttons I'll be using with nice diffused ones. I also was able to get past some issues with the Adafruit library for the 24 LED bargraph. When all was said and done, I was able to compile my 42KB sketch and load it onto the Arduino.
That's when things started heading South.
It was then that I realized the severe memory limitations of the Arduino. Even the Mega, with 8KB of SRAM is seriously cramped. It never finished the setup() routine, it ran out of RAM before creating all the variables. So I started to work on cutting down. First, I found that using reserve() on the vectors was chewing through RAM and not doing what I expected. By removing that, I was able to immediately save a ton of SRAM, at least enough to have some breathing room.
From there, I learned about enclosing String literals with F() to reduce SRAM utilization. After implementing this across the board, I was able to save 1374 bytes. After that, I was able to compile the whole thing, with all buttons and displays and have 1638 bytes left. Which isn't enough to actually parse anything.
I do have some options:
- Try to reduce SRAM utilization
- Cut down on objects
- Optimize main sketch
- Purchase an SRAM extender
- Split the project across two Megas
- Relocate the logic to the other side of the serial cable
I'm still investigating, but I'm kind of disheartened.
-
Memory Leak
02/17/2015 at 05:51 • 0 commentsI was able to get to the bottom of the memory leak. It wasn't ArduinoJson related at all. For some reason my char* buffers weren't getting released at the end of the function. Adding free() fixed that.
I spent some time assembling the PCB backpacks for the LED bargraphs, so those are all ready. I tweaked some of the code to implement a basic bargraph. No bells and whistles yet, but it should work.
I started to replace the LEDs in the square buttons, but got sidetracked trying to figure out which resistor I should use. Ordinarily this wouldn't be so hard since I'd previously had very few, but I picked up a huge assortment of them at Radioshack on clearance.
I tried to rework my shield so I could have multiple I2C headers, but it's really fighting me. I'm just going to test the bargraphs connected directly to the Arduino.
-
Indicators
02/13/2015 at 05:41 • 0 commentsI got the first of the outputs working. I can set an LED based on JSON from serial. It works fine manually, but with the Python script the Arduino doesn't like the JSON it sends. While trying to debug this, I discovered that the Arduino is sensitive to either fast requests or large requests (or both). I was able to trigger a freakout by sending too many requests (See below).
I'm not sure if this is the ArduinoJson library, an out of memory issue or a buffer overflow. I was getting them earlier on before I defined the length of a char* array. I did make sure I wasn't sending requests until the previous response was sent, so it shouldn't be stacked requests.
I may look into coding a simple JSON parser. Since it doesn't need to handle advanced JSON, just key-value pairs it shouldn't be too bad to do.
JSON Parsing failed."{v:0.9.0SAS StatusJ0J1,toggle_fbw1six_dof}ONLINECALIBRATINGKey MMKeySASsasTogglesas_statusThrottleset_throttlePercentREADYRESTARTResetting...{}nulltruefalsebfn r t null""\\bf n r t: , ()10TrueFalseError: Trying to get an output pin.ValueToggleNoneTrueFalseZeroOneKeyFloatPercentUnexpected format "" in object ""ErrorKEY: ValueToggleNoneTrueFalseFalseTrueUnexpected format "" in object ""Error Locked Button Indicator,:X: Raw: , Raw: , Corrected Y: Raw: Z: Raw: xFloatyz ButtonValuex+-/+a+A++814 Ô ìàôÿèÿ äô" ÿ@ ºôª²ÿ¢V è è è ê qnqpôöö0öbÒn×M:"True"} {"sas_status":"True"} {"sas_status":"True"} sas_status"55:"True"} sas_status"55:"True"} sas_status"55:"True"} sas_staèÊÅÄÀÁÂÆèRÍÌÈÉÊÎèÚÕÔÐÑÒÖèb¦540126xͺMValueValuertJ0x J0- calibrateCalibrate LockedValue Calibrate ButtonValueJ1h CalibrateCalibrate IndicatorÊÂxà?6&|ìb¶ÿ\@íýH!?7&|íýVÿô>ú>8&|ôÿ ¬9&|°¸ÿ* :Ù/»ì>:(|Ù2ÿξø?ü>;(|øÄìÿðöòýøà?<�(|òýúÿ =(|ÿ&½zåæÔôßÿD"æÔô( ÿ|xà?6æÔôÿÿ³ ?6Gô²ÿÀÿÿxóïß}uýÙNÖßî¹çµU.uïfæÔöö·~îëæï×ÜÏîÈó»sHÊÇïÿ_Û£ýûçÇ Ïá÷¶uËëgì«ÿîÿÍ»ÿÿÿþü¯ù½óÎs÷ýÝk¿Óõë6ï½ÓÿÓþý_ýêþýÃëïksï=Àþ;ÿÏígýcûãtï-Ë}=¾~q¾½ÙöÚú?ß*øßüÛ»oõêß»ËÝÿe®~óùx>¬ý¯þ«ÿ÷2«ÿÿ\ÒÍýîÿ{Éÿý÷Ý¿/Þ¼ÞÿûÖý»«=nß[ícÎÿíÕ>ÿ»¯Lÿñ½û¿þõ5"GÍÿs¿ú~ÿíÓsy¯çÓgïßÿ~ßÎÃ/m÷û§óÿ÷ çÿÿ·Å7ïûùËïßWµÿݲïÿ]ïÍîÝ1³¬ëÛ_¶õ¦é?ÆM=ÏÛÝm¶è®kJºûÿÿÏmþßwýõåÛþó}þÿó÷Ïví¿ù×Ýï×{ÏôoÞ»aþ¾ïÊîÜÝóooo_óûÚíï·µ÷ë§ù³ÿ¿ºöw»çç®ùóÿý¿{ßqþÿ¿ïßûÊÿúûßûÿ÷\õÚô|ùõÞY»~_}oÕn>wo¿î´÷gÎ]öñ÷|üúþ¼}1ëûõ»þÚ[n¾úâeûÍ®ÝÆôªïÍïGñâ~ÿ>ÿ÷뽯xm¯ù=>ýÿÿNwÓÎ÷Þ^¢{^ûw¬ÕB¿ûï8ôÝß·Ísaÿß=þÿ{Ï{ymöõòóÛç]ûï_õ×_|ïw}÷øÿ÷ÏûÕãõûýïîû©}Í×ïßú«=>®ï« ÿé¿l]£¥Þmië¶Ï×ßí&ößùûÿÿÿÎÿß&üÕüöïµý·=¿êÿ/vï|wî[íws)Tô¨ßõ².ßuýý%%ÿë6ë/¿ÿ÷ýîîûuûfX e åÔôMÿÿ ÂôyÂÿÐÿÿÙþ~ä~9ÏÅgùßýÝcÚßÛßýßþotþþý¶Ø;oi÷½ïÿ|Ðß®zlbõÿ·®ê÷öþ®fÿÿë¾ùÿçÿÃûy¦ó]÷×Æö¬Û×ýÿ÷¿[òÛ-·¸û×ÓØoê÷vûÿûçÚkçqÞûûëÚþÿøµþ¿í÷¼ÿ¬ýÿ©[Ûý{ý¯Õ÷Ëÿë¹÷þû³ýÿóê¿{¾üûóÿìïç· µª¸Îãß/ú»Ýûç>]v׫]óç÷²7ßäíÉ{¿á77s=/^ïùS·µ[×ú×ý¿¯C×>Õg¾ÞÓûZú¾ÿëß{üÛ{7íßÿOg¿gï-þÿùû|[íöÆ=l¿?ïé~Õ]ÝþS~ÿÿû÷ßË~W÷owíÿÿïøìþá?Èþß®½»çõÏw¿Z~õ¿ôïãàËû5¿m{û*æûÎc¶Ûö_Ûäþª/z:ºïÿݳϺ~ôd6ë¿îÿþ<¾µÝöüÝdÙ:ëõ®ïíþ¯{ÝòW¾çßrÏí^ïÞý®ïýÞÞ÷÷®ïm~ ï÷~^âÿ_É©-ÿ?ϪÞÿÊïb7¡ß~o/÷ÛWÝS¡ÏþEúïÿífR_Ñ9owïû¿úeýw·¿®=»ÞüÞùÓo_þ·_sþËeÝYó?éëÞý{@ëÿü»ÓU<ÜæôÿûîI®¯ýõ´?ýÕoÝ>ënyÌÊïþ9ýNîÊVo·÷?ðü_çûl¾ß¬Þï×\û¾kñ.·ß60~û³ÿî&.~ýʼCÃøe¥ë¯ûÏÅù¾ÙÚÏöþ|Yûý{ÆÃÑoam×ûþ±çܪ)×ý¿íûò7öåª{ÇÝéµíºïçt»ÐGê'¶;U¾Ûÿo¿ãZÚ{}ÿï¯ó/ÍýûoýìåçùntÇU»îíûÛó}º§÷»5ÿѯÃko÷æu¾?ûzµç¿þÇ»~ùõüuóÿ£øüwìö¹^Ôü¿Êûo~ùßßÝñýoµÿ¿ñýïþwITݼï¬óõ::[?}¾'èíä¦ú:yÍëÚþk·ÿm÷ûï¿÷{3::üí:~æ:::øþ::ÞÿéÞ]:þÿoÁçßgÿÿ÷¿zÖÝ·Ç|Üw{?sÖ³»ìyÿûøí'oþù}óóÕle~«j»ÿmÓÿÿØ ¿îÿïFxz¯Vgÿõ®¾ïèËão%È÷oÏ´v[ßíþß,ßëbýõíÛïÿg´{å?ë'³»Õ{}íÿ_ç{}¿ï5þµüqß÷¯^2~{*_qw½íóÿ1Îê:ãwö|ýÙ Íóÿ¦ùso3>ûwöíÆó÷þ¯Ó;Öð|ï¿[[ëôÏ{¦×:;û+7=ÿþÿ?}Þß Ûìü~è¶×çÝåØÞo´§c½¿Þ}?ÿ½ûFloatJ1xSAShyValue BJ0yFloatºv":"0.9.0"}Key MFloatJ0zFloat J0 ButtonValueÒÒFloattoJ1y Jv"JKeyKEYMJ1zFloat J1 ButtonValuesasToggle"sas_status":"True"}p pNv":SAS Statussas_status"N Throttle set_throttlePercent {"x:"y}sas_statusle_f:"1","six_dof":"0.00,0.0 {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":" {"x:"y}sas_status.J":"0.9.0","toggle_fbw":"{"sas_status":"True"}{"sas_status":"True"}{"sas_status":"True"}{"sas_status:"True}sas_status:"0.Trueoggle_fbw":"1","six_{"sas_status:"True}sas_status}"True"0.9.0","toggle_fbw"{"sas_status:"True}sas_status0.00Truep_brake": "False", "{"sas_status:"True}sas_status.0",Truerottle":"50.64"}%{"sas_status:"True}sas_status.0",Truerottle":"50.73"}%{"sas_status:"True}sas_statusake"Truee", "rcs_st{"resourc{"sas_status:"True}sas_status "FaTruercs_st{"resource_mp_{"sas_status:"True}sas_statusse",Truetv ","toggle_fbw"O{"sas_status:"True}sas_statusp_brTrueFalse, "rcs_status{"sas_status:"True}sas_status.9.0Truele_fbw"O{"resource_{"sas_status:"True}sas_statusFalsTrues_status: "False}{"sas_status:"True}sas_statusle_fTrueresource_mp_max: 27{"sas_status:"True}sas_statuss_stTrue"False}sas_statu{"sas_status:"True}sas_statusresoTrue_max: 275, "action_{"sas_status:"True}sas_status"FalTruesas_status0"}v{"sas_status:"True}sas_status_maxTrue "action_group_brake{"sas_status:"True}sas_statussas_True0"}v":"0.9.0","{"sas_status:"True}sas_status "acTrueoup_brake: "False,{"sas_status:"True}sas_statusTrue!Ç *!!Ç-è!Ç{"sas_status:"True}sas_status.TrueU/¦Æ#2:{"sas_status:"True}sas_status DTrueN D-è Dg/Úgô 'Á¸ÿ+Ï-8ê¯K-rê-²¯G/ Ï ¼¥/Ú¥ "+®n-8êurê:"-¤¤-¯urT"z{«""ÒßÿtndôMÀÿ> K eô¼ÿC16eôrÿÏì=ö>6]ìÿ2* íýH!?7^íý!£/Ú!£ Öa!£!!=-è!£.!£.» Õ£!!£/ Ö/#Á!Ä!Äj0!Ä f!£!!!=-è!Ä .!Ä.1!s!DÏ/ ~zÀ¼xrÛjØ11111]]¿pZ !¾/Ú!¾hç!!Ý-è!¾.!¾½!!¾!áç!8P.»!áÔ!!ç!á!ÕäñIhW)N!)m-:Î8
-
Full Throttle
02/12/2015 at 06:09 • 0 commentsI spent the last two nights re-working the Pin class to accommodate the throttle. Originally, I was going to add a dedicated Throttle class, but I realized 90% of the class was already implemented in Pin, so I just added some extra class members, methods and two new format strings and it's working beautifully.
While I was doing that, I ended up changing some other code. I found out about setting default values in the method definition itself. This means that I was able to reduce the number of constructors needed for all of my classes. Much simpler.
Next step is to work on indicator output. I fully expect to hit some resistance here, but that will pave the way for interacting with other outputs.
-
Keypress Buttons
02/10/2015 at 05:33 • 0 commentsI've now implemented buttons which trigger a keypress on the host OS. Now I can use features which are not exposed by the API. For the moment, this is only implemented in OS X. Eventually I'll port it to Linux as well. I will not be porting this to Windows, but if someone would like to do so, I'll happily pull the changes in. I do have a slight concern for the future with this one since I'd like to eventually disconnect the controller from the computer entirely. For the moment though, this is sufficient.
I also added a software interlock that disables joystick commands when SAS is enabled.
To give myself a better idea of what's left to do, I've fleshed out the project details.