So it's time for a new hardware interfacing project for the TI 99/4A, namely a wireless weather station managed by that venerable computer. I think it will be a fun project but likely with a steep learning curve. The goal is to have a functional prototype in time to demo at the 2017 Chicago Fair.
So where does one start? The most obvious would be finding a cost efficient and relatively easy way to achieve wireless communication between the various sensors and the computer. I believe the Xbee series 1 modules fit the bill quite nicely because they have a range of about 90 meters (300 feet) which is more than enough for the average user and they come pre-configured for serial communication. I chose the version that has a connector for an external antenna in order to maximize the transmission range.
These modules have integrated ADC as well as digital inputs and transmit data serially which can be captured by a sister Xbee module connected to the computer. Unfortunately, they would not be enough by themselves because there are few sensors that can interface directly with them without some sort of processing first, and so a microcontroller is going to be needed for support and data packaging within the sensor array. With so much community support and experience available for the Arduino, I decided to go with the Arduino Uno using the Sparkfun Redboard.
It comes with installed headers and connectors, making it easier to access and interface.
Now for the sensors:
While I could design and build my own mechanical components for wind speed, direction and rain level, it would be a pretty laborious process. So I opted to go with a ready made solution that is super easy to interface, again from Sparkfun:
This is a purely mechanical device with no embedded electronics, and the data interpretation is via checking the state of various switches. What is even better is that it has a direct interface with the Sparkfun weather shield for the Arduino Uno which also includes pressure, humidity and luminosity sensors.
All we need now is a temperature sensor, and the one below is inexpensive and pretty easy to use. It is analog, so it will be earmarked for one of the Xbee ADC inputs.
This should round up the sensors for our weather station. The last thing we need is the Xbee serial explorer board to connect a receiver Xbee module to the TI 99/4A via the serial port.
So far, this is going to cost around $215, and will likely need another $25 for various connectors and support items. So no, it's not exactly cheap, but the fun factors of putting all this together will be priceless!
Now what? Well, first of all I'm going to have to get familiar with the Arduino since I have had zero previous exposure to it. I have always used the Raspberry Pi for my other projects, but it would not have been suitable for this one. That is going to take a little time. But even before that, I'm going to have to dig deep into the Xbee documentation and come up with some communication tests, likely using only the temperature sensor for starters since it can connect directly to it, and see if I can transmit data wirelessly to the TI.
First things first: Since the Xbee modules communicate via serial protocol, I needed to understand how that worked on the TI. It's definitively more involved than parallel communication, with a multitude of registers and CRU bits needed to be accessed in the 9902 UART chip in the RS232 card. Here Thierry Nouspikel's encyclopedic site ( http://www.unige.ch/medecine/nouspikel/ti99/titechpages.htm ) came in to the rescue with clear explanations and code examples.
Obviously this is all done in assembly which is fine. However, I recently found out the Rich Extended Basic (RXB) by Richard Gilbertson actually has a command called CALL IO which allows direct access to the CRU without resorting to assembly language! Below is an explanation by Lee Stewart about how it works:
If you set a variable named CRU to half the PIO CRU-base-address of >1300/2 = >0980 (2432), you can address CRU bits by adding to CRU in the call.
The following code will set, test and reset (clear) the indicated bits:
100 CRU = 2432
110 CALL IO(3,1,CRU,1) ' SBO 0 ;set bit 0
120 CALL IO(3,1,CRU+7,1) ' SBO 7 ;set bit 7
130 CALL IO(2,1,CRU+2,X) ' TB 2 ;test bit 2 and pass value to X
300 CALL IO(3,1,CRU,0) ' SBZ 0 ;reset bit 0
What this means is that at a minimum I could test my setup directly from within RXB without the need for coding in assembly with its associated cumbersome and time consuming development cycle of Edit/Compile/Run. And if it works out well, then there is a very good possibility that I might be able to code the entire project in RXB and bypass assembly altogether.
At this stage I have configured 2 XBee modules for 9600bps 8N1 communication protocol, and attached one to an Arduino Uno via a shield, and the other to the serial port of the TI using an XBee serial adapter. The way XBee works is that if one of the modules receives data on its Data In line, it will serialize it and transmit it wirelessly to the Data Out line of all the other XBee modules in the same network. I have therefore connected the XBee DOUT line to the Arduino's Rx (receive) line, and the XBee DIN line to the Tx (transmit) line. There is a very small test program running on the Arduino which basically watches for data to show up on the Rx line, reads it, and if it is an 'a', it turns an LED on, and if it is a 'b', it turns that LED off.
On the TI side, I am running TELCO with the same communication parameters as the XBees, using a null modem serial cable. When I type 'a' in TELCO's terminal, the LED on Arduino lights up, and it turns off when I type in 'b'. Simple, but a great proof of concept nonetheless. Here's a quick video of the demo:
On this next step, I switched over to using RXB on the TI side using the CALL IO functionality, and it worked beautifully, thus obviating the need to use assembly for this project. It took some fiddling and lots of help from the AtariAge TI community, particularly Stuart, to properly configure the TMS9901 chip in the RS232 card to work with the Xbee given that we are only using the Tx and Rx lines with no flow control whatsoever, but we eventually figured it out. The only downside of this kind of set up is that the Arduino is much faster than RXB, and so delays had to be introduced in order to get a reliable transmission, in the order of 500 msecs per byte transmitted.
From there, I moved on to actually connecting a temperature sensor to the remote arduino's analog inputs and tried to read the temperature data on the TI. The raw analog input from the sensor was converted by the Arduino to a float temperature value, which in turn was converted to a string and sent byte by byte to the TI. On the other end, the TI reassembled the string and converted the final product back to a float value. Below is the video demonstrating that experiment:
So I've decided to add a real time clock to the project with the idea of logging the various weather parameters for future analysis and comparison. To that effect, I acquired the Sparkfun RTC module based on the DS1307 chip and communicates to the microcontroller via the I2C (inter-inter chip) protocol. Sparkfun provides a specific library for the Arduino that makes access to the various date/time parameters trivial.
Here's a demo of the process. Sorry about the quality of the video but I only had a low end camera on hand...
I am now in the process of testing the Sparkfun weather shield which has on board a pressure, humidity and light sensors. I'm still mulling over the use of the light sensor which would be useless if the whole setup was enclosed in a sealed box. On the other hand, if I add a clear window to the enclosure, I should be able to determine sunset and sunrise times which would be nice to have and log. In the mean time, the humidity and pressure sensors seem to work perfectly.
One issue that arose from using the weather shield is the fact that it utilizes all 6 analog inputs on the Arduino, and so interferes with the analog temperature sensor I am currently using. The solution is to replace that sensor with a one wire digital sensor which connects to a single digital input. I have opted to use the DS18B20 shown below. It is much more involved to set up on the Arduino side though, so we'll see how that goes. On the plus side, the sensor is weather proofed, so I will be able to have it hanging outside the enclosure without issues.
After a rather lengthy hiatus secondary to being super busy at work as well as some technical issues, I have finally managed to set up the last remaining sensors. I have replaced the analog temperature sensor with a digital one, and connected the wind speed, wind direction and rain gauge. This required getting familiar with some advanced Arduino topics, primarily the use of internal and external interrupts needed for the rain and wind sensors. I also made some boneheaded programming errors such as setting a float variable to integer instead of float and wondering why my values were always coming back as zero or forgetting to solder some of the pins to the board... Eventually everything worked out fine. I did end up connecting the two center pins of the rain RJ11 connector to ground and digital pin 9 on the weather shield so I could use internal (pin change) interrupts, but this was probably not necessary once I discovered that I had not soldered pin 2 of the shield which is used by the external interrupts. Live and learn
Here's the final Arduino sketch. I borrowed heavily from code examples on the net, and frankly Arduino programming is akin to building with Lego's where most sensors and interfaces come with set libraries that handle the low level programming and make it relatively easy to connect to these extensions. I have introduced a lot of delays in the program because there is no flow control between the TI and the Arduino and so I needed to allow the TI to process the data received without losses, particularly since I am using RXB and not assembly on the TI side. This translated into roughly an full update of all the sensors about once a minute, which is more than adequate for our purposes here.
And here's the RXB program. Please bear in mind that this is only a test program and definitely not the final product.
And here's the demo video:
Next is tidying up the electronics and designing an proper enclosure which I will likely 3D print. Then I will need to create the final RXB interface program and look into data logging options.
One thing we did not discuss to date is how to power up the wireless station. I suppose I could run an electrical wire to it but that would be cumbersome at best and against the spirit of "wireless"! So the obvious solution was to use solar power. To that end, got the Sparkfun Sunny Buddy solar charger module, a 9W solar panel and a 2Ah 3.7V LIPO rechargeable battery.
The Sunny Buddy is a smart module that maximizes the solar powered charging process and delivers needed power to whatever project you need. It does however come setup for 450mA output charge by default, but there is a provision to add a resistor in parallel to the sense resistor to increase that current to whatever is required. The 2Ah battery should hopefully provide enough juice for uninterrupted operation at night, and the 9W solar panel is large enough for quick battery charging providing 1500mA at peak (1.4hrs charge time).
UPDATE: So I feel pretty dumb at this moment... While the Sunny Buddy coupled with the solar panel charged the battery just fine, I just realized that the Arduino Red Board I have requires at least 7V for operation... Doh... Soooo, I ordered another LIPO battery with similar specs along with a second Sunny Buddy which I will connect in parallel to the solar panel and the batteries output will be in series connecting to the Arduino. The main implication here, aside for the additional cost involved , is that now it will take 2.7hrs in full sun to charge the batteries compared to 1.4hrs previously. Still pretty decent nonetheless.
I also finalized the layout of the electronics, with easy access to the various components in case repairs are needed. Next is the case design, which should be pretty straightforward...
Final Update 6/8/17
So everything is now put together and working as it should. Yay! I'm still struggling with the use of solar power to power up the project for the following reasons:
My house is surrounded by tall trees, and so any particular spot in my back or front yard will only get a maximum of 6hrs of direct sunlight
The batteries can only power up the project for at most 10hrs or so
It takes approximately 3.5-4hrs of direct sunlight to fully charge the batteries
Therefore, starting out with fully charged batteries when no direct sun is available anymore, say 4pm, the system remains powered up till 2am the following day, although I have found that on clear days there is still a trickle charge from the solar panel to stretch operational time by an extra 2hrs. Even then, if the batteries die out at 4am, the sun doesn't peak over the trees till 10am, so there is a 6hr gap right there. Furthermore, since it takes 3.5-4hrs to charge the batteries, the system doesn't actually get back online till 2pm, giving me a total downtime of 10hrs! And it's worse if it's cloudy... Of course I could use larger capacity batteries, but then they would not fit in the enclosure and would need proportionately larger solar panels to recharge...
But this issue is really only particular to my current home location. In MN, sunrise is around 7am and sunset around 9pm in summer, and so if I had that full range of solar radiation accessible, the downtime would be much shorter...
I have toyed with the idea of reducing polling frequency at night to conserve power, but then I would lose a lot of data that way, particularly if it's raining. Preliminary tests did not show a substantial saving in battery power anyway.
Regardless, the project still works as expected, although in my case I might forgo solar power altogether and just use electrical power from the mains with a wireless connection to the TI in the basement. I have found that the effective maximum range was in the order of 70 feet, going through several walls, but your range might vary depending on where the TI is located.
Here's a video of the final setup and testing:
And here's the source code for the control program on the TI using RXB.
So this has been a really fun and hugely educational project for me. I hope you have enjoyed it as well
On to the next adventure!