Author |
Message |
Reepicheep
| Posted on Tuesday, March 10, 2015 - 08:40 am: |
|
I've been playing with PIC microcontrollers for a while now. I started with the pic for a couple of reasons, first I wanted to to go bare metal up and do my own libraries and electronics, starting with the data sheet and a blank board and end up with a working system. I did it, and it was a lot of fun, but was a lot of time and was pretty complex by the time it was all sorted. Secondly, I wanted a device that I could use to replace simple analog circuits, meaning it had to come in at the $5-$10 range for an operational device. The pic did that too, I could make something useful for $5 or less in parts. But now the Arduino has caught up with me (as I knew it would), and I am glad for it. First, now you can get a really nice Arduino Uno board for $8 or so. That includes PCB, cpu, USB port, ability to be programmed, voltage regulator, risers, and power jack. And the chip you are getting is much more capable than the PIC's I was getting... lots more inputs, outputs, and RAM to work with. And finally, the open source support for the platform has gotten incredibly rich, while making very good decisions about how to approach the platform. Program in C (fantastic decision) but hide a lot of the really hairy stuff of include files and pragmas and complicated #define commands. Then throw in a bunch of support for common peripherals, and that's a double win. First, it makes them insanely easy to use. Secondly, it helps you choose better peripherals to start with. For illustration, I literally spent probably 30 hours to be able to accurately tell temperature. I was translating nonlinear curves from data sheets from thermistors into algorithms that would fit in a memory constrained CPU, sourcing parts that were likely to be and remain available affordably, and debugging a lot of failed ideas. With the Auduino, there is a library for a common device to sense temperature. Instead of the thermistor I used, they used a part that I wasn't aware of, an LM35. It is far more accurate, and far easier to interface with, then the thermistor I was using... and about the same price. If you have never sat down in front of an utterly blank slate, then logged into the Newark site to start hunting one of a billion components that can solve the problem you are solving, you have no idea how overwhelming and time consuming it can be to find the best solution in an ocean of OK ones. So the perfect storm (in a good way). Literally 5 minutes after I decided I wanted to tell temperature, I had the device selected, the libraries complete, and the code running. So now the 30 hours I spent sorting it out myself (a really cool experience, and one I don't regret, don't get me wrong) can be used for solving problems instead of building components to solve problems. And when I do find a cool new device, if I spend my 30 hours to select and build support for it, I can contribute that back to a community for others to leverage. Absolutely worth it to me, as the community has saved me so much time. So anyway, watch this space for future developments. I'll probably rebuild the heated grip controller on the Arduino platform, and farkle it out a lot more (I was literally down to my last 4 bytes on the PIC, and that was after super aggressive memory optimization). If you want to come along for the ride, order one of the Auduino Uno boards from Ebay or whatever now (they take a few weeks to come in). I am a native C speaker, so perhaps what appears to me as easy as breathing would be a bit more intimidating to others, but from what I have seen so far, this is a very simple and accessible platform, the custodians of it have done an incredible job of keeping it powerful but making it simple. Here is the Arduino I got, it seems fine. There are many places to buy them. This was about $10. It is a good development board, when I start making them to embed somewhere I will probably want solder pads instead of the risers for the ports so I can solder on a daughter board. http://www.ebay.com/itm/US-UNO-R3-ATmega328P-ATmega16U2-2012-Version-Board-Free-USB-Cable-for-Arduino-/251459710321?pt=LH_DefaultDomain_0&hash=item3a8c2aad71 I also got this for $60... http://www.ebay.com/itm/SunFounder-RFID-Starter-Learning-Kit-for-Arduino-from-Knowing-to-Utilizing-no-R3-/151460999083?pt=LH_DefaultDomain_0&hash=item2343c76fab It is a *very* nice selection of bits and bobs, with sample code and schematics to use each. You can find the source and get the parts yourself easily, but bit by bit shipping would probably kill you, and this is a great selection of "legos" to have laying around to play with and understand. It also has things like breadboards and nicely made jumpers that remove a lot of the annoyances and errors associated cobbling together prototypes. I sat down last night knowing very little about the platform, and had an LED blinking in 10 minutes, and the servo moving to whatever positions I wanted to command in 20 minutes. The cat and I were both amused.
|
Reepicheep
| Posted on Tuesday, March 10, 2015 - 01:02 pm: |
|
Ebay humidity and temperature sensor, which can be read "out of the box" by the arduino. Under $4 to my door in quantities of 1 (though it's temperature accuracy is pretty low). Ebay mic (which includes mic, op amp, PCB, gain pot, and connector)... $2 to my door. Ebay 3 axis accelerometer / gyroscopic sensor... $3 to my door. Ebay solid state relay (240 volt AC 10 amp), $6 to my door. Rotary encoder $4 to my door. Bluetooth modem, $4 to my door. Arduino Nano (smaller board good for embedding somewhere forever) $6 to my door. Oh geesh. I'm like a kid in a candy store. |
Reepicheep
| Posted on Tuesday, March 10, 2015 - 01:18 pm: |
|
Micro SD card module, $4. |
Bluzm2
| Posted on Tuesday, March 10, 2015 - 09:56 pm: |
|
Damn it Bill! I'm screwed! |
Reepicheep
| Posted on Wednesday, March 11, 2015 - 07:41 am: |
|
You and me both Brad... And I found the Nano's for $10 for three of them if you wait for shipping from China. Last night I taught my oldest son to program them. Started at 9:30, and he had 5 chaser lights wired and running by 11. |
Reepicheep
| Posted on Friday, March 13, 2015 - 01:22 pm: |
|
Curious what Arduino code looks like? Program to simulate my son's base drum routine for Drumline. // Base Drum Routine Player // Blink the LED base drum simulation // Version 1.0, 2015/03/13 // Bill@KilgallonFamily.com // Set up constants to keep design flexible relative // to hardware // Define which drums pins are simulated by which pins const int firstBasePin = 9; const int secondBasePin = 10; const int thirdBasePin = 11; const int fourthBasePin = 12; const int fifthBasePin = 13; // Define flags for each drum that can be combined into a single // number const unsigned char firstBase = 0b00000001; const unsigned char secondBase = 0b00000010; const unsigned char thirdBase = 0b00000100; const unsigned char fourthBase = 0b00001000; const unsigned char fifthBase = 0b00010000; // Define how long to delay between each beat in milliSeconds const unsigned char beatDelay = 250; // Set up global variables unsigned char counter; // Define the entire routine beat by beat // (Up to 1000 beats, make array bigger if you need more) const unsigned char routine[1000] = { 0b00000000, 0b00000010, 0b00001000, }; // Manually define how many beats are in show (how many entries // you put in array above) const unsigned int beatsInShow = 3; void setup() { // Configure the LED Pin (defined by a const) as an // output port pinMode(firstBase, OUTPUT); pinMode(secondBase, OUTPUT); pinMode(thirdBase, OUTPUT); pinMode(fourthBase, OUTPUT); pinMode(fifthBase, OUTPUT); } void loop() { for (counter=0; counter < beatsInShow; counter++) { digitalWrite(firstBasePin, (routine[counter] && firstBase)); digitalWrite(secondBasePin, (routine[counter] && secondBase)); digitalWrite(thirdBasePin, (routine[counter] && thirdBase)); digitalWrite(fourthBasePin, (routine[counter] && fourthBase)); digitalWrite(fifthBasePin, (routine[counter] && fifthBase)); delay(beatDelay); } }
|
Reepicheep
| Posted on Friday, March 13, 2015 - 01:23 pm: |
|
(sorry about the indentation, the board ate my tabs). |
Reepicheep
| Posted on Friday, March 13, 2015 - 01:26 pm: |
|
(I could have gotten fancy with a union to overlay an unsigned char on the output pins directly, but I didn't want to be a show off ). |
Pedalpimp
| Posted on Friday, March 13, 2015 - 06:15 pm: |
|
This is good timing, I just picked up some of these components for my kids and I to play with. I am very interested to see what you come up with. Seems like there are lots of possibilities for these things. |
Bluzm2
| Posted on Friday, March 13, 2015 - 10:19 pm: |
|
Bill, you are pissing me off. I'm going to have to learn C despite having failed a couple times already.. Got any suggestions? I'm an old assembler programer and never mastered the new fangled object oriented languages.. |
Reepicheep
| Posted on Saturday, March 14, 2015 - 06:22 pm: |
|
Arudino is actually C++, but you can (and generally should for this stuff) use it like C. If you can do assembler, C will be easy once you start into it. Just think of it as assembler with a really nice library of macros. That code above only does a couple subtle things... first, you can statically declare an array, and I defined the values in binary to make it easy to see which drums are beating (the 1's). Then I use a loop to walk through the array to play it back. Then I just use a logical AND with a bitmask (& to see if that bit is set. Except looking at it now, I forgot and did a logical and, which means the code above won't work until you change those && to & in that loop. (I never said I ran it, I just said I wrote it... ) |
Reepicheep
| Posted on Thursday, March 26, 2015 - 08:37 am: |
|
Got the eBay nano's. Take a while to ship, but the first one plugged in and worked perfectly. $3.65 to my door in quantities of 3 at once. I can't even get the parts for my PIC board that cheaply (in the volumes I deal with). And the PIC I was using was a weaker CPU. The nano also comes with solder pads for header pins, which is perfect for embedding them in dedicated little projects. I'm still glad I went the PIC route first, it made me go all the way from data sheets to reading header files to low level C code and writing my own libraries. It really helped me understand what is going on under the covers of these little microcontrollers. But now I am also really glad there are these powerful little assemblies already assembled for $4, with matching libraries others have written and debugged and that I can use, and where I can share libraries I have written also. It lets me spend time on higher level things (which will ultimately do more interesting things). I'll start making something interesting next week. |
Reepicheep
| Posted on Thursday, March 26, 2015 - 08:38 am: |
|
|
Reepicheep
| Posted on Thursday, March 26, 2015 - 08:41 am: |
|
Ebay seller I used http://www.ebay.com/itm/381019048475 |
Reepicheep
| Posted on Thursday, March 26, 2015 - 09:28 am: |
|
And just to make sure I bug Brad this morning... I just bought 3 axis accelerometer modules (three analog outputs)... I picked up three of them for $10 shipped to my door (though slowly). I have a plan for those also. |
Airbozo
| Posted on Friday, March 27, 2015 - 04:55 pm: |
|
Love where this is going. Just picked up the Intel Edison kit to play with and a bunch of sensors. One of my customer's hobbies has been using an Arduino based setup to monitor carb'd motorcycles on a race track picking up as much telemetry as possible without violating the rules. He was able to help one of the test riders drop 2 seconds at Laguna Seca by showing him how he was braking too early in one of the corners (forgot the corner name, but it is one of them that goes uphill before a sharp right downhill). I've asked if he would share what he is doing and the parts list along with his code. |
Reepicheep
| Posted on Saturday, March 28, 2015 - 08:40 am: |
|
Awesome idea! I have a few motorcycle projects in mind also. |
Bluzm2
| Posted on Saturday, March 28, 2015 - 10:50 am: |
|
Bill, you're killing me.. I'm going to have to take the jump... I have a couple projects in mind, I've had them for some time, just didn't want to address the learning and design curve to execute them. These little buggers will really help that. Now just need to figure out how to turn simple line drawings into input streams for solenoid inputs. |
Reepicheep
| Posted on Saturday, March 28, 2015 - 09:56 pm: |
|
Got it working. Had my first "the honeymoon is over" moment, but really it wasn't that bad. The LCD module that came with my kit didn't work with the library on the CD that came in my kit. I deliberately used the IDE version they sent to avoid just this kind of problem. No big deal though, it was easy to find and swap in the new right library, and figure out from a few different sources how to use it. Far easier than when I had the same problem on the PIC and had to write my own LCD interface libraries completely from scratch to get them to work (probably 20 hours before I had ones that were fast, small, and reliable).
(beware below, the forum software may be eating characters and it is eating my indentation... email me at Bill@KilgallonFamily.com if you want source files).
quote: // LCD Demo code // Bill@KilgallonFamily.com // Revision 1.0, 2015/03/28 // This program uses the LiquidCrystal_I2C library, which is // different (and much richer) than the one that came in // the SunFounder kit CD. // To install and use this new library (at least what I had to do today) // Go to https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home // Find the download link // https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads // Download the latest version (LiquidCrystal_V1.2.1.zip 2012/04/05) // Go to your arduino install library location // (i.e. C:/Arduino/libraries) // Move the LiquidCrystal folder to a new location and name it LiquidCrystal.orig // Extract the zip file you downloaded to create a new LiquidCrystal // folder in that library directory // In the Arduino IDE, go to Sketch->Import Library, and navigate to the LCD library // To load code to the Uno, make sure your Arduino IDE tool->programmer is set up // as AVRISP mkII and your port is correct. // To wire this up: // Hook the GND and VCC to the GND and Vin pins on the Arduino // Hook the A4 line on the Arduino up to the SDA line on the LCD I2C LCD module // Hook the A5 line on the Arduino up to the SCL line on the LCD I2C LCD module // // // Define include files necessary to simplify interaction with // peripherals // // Include headers for the two wire communication with the LCD // module. You can talk to the LCD directly using 7 output pins, // which works fine, or you can use an I2C module to talk to it // using only one pin. The I2C modules are only $2 or so, and // just connectors cost more than that, so even aside from eating up // fewer outputs, it makes sense to use more electronics and // and less wire. // // Plus, the two wires carry the concept of // an address, meanining they are really a bus, and you can // put more than just the LCD on these two wires, you can // also add other peripherals. #include <wire.h> // Now include the LCD library (again, the I2C version) #include <liquidcrystal_i2c.h> // // Now define some global variables for use by the entire program // // First, create a 17 byte array here to accomodate the 16 // characters the LCD can display, and the extra byte to // store a null (0x00) so we can use the C string operators // safely (which we might not bother to do) char LCDBuffer[17]; // Now initialize the library to tell it about the LCD. // // The I2C interface basically lets us stuff a variety of parallel data // through a two wire interface. This saves pins on the arduino output, // and wires in the connector. Because the I2C bus is addressed, several // peripherals can all sit on the same two wires and be seperately addressed // // The arduino has plenty of pins if you just want to play with a LCD, you can // hook it up directly and not use the I2C stuff as well. // // The arguments are (in order): // * The LCD I2C address (can vary by maker) // * Which pin is the LCD EN pin // * Which pin is the LCD RW pin // * Which pin is the LCD RS pin // * Which pin is the LCD D4 pin // * Which pin is the LCD D5 pin // * Which pin is the LCD D6 pin // * Which pin is the LCD D7 pin // * Which pin is the LCD Backlight pin // * What the LCD backlight polarity is (POSITIVE | NEGATIVE) LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Now define stuff to blink onboard LED for sanity when debugging // so we know stuff is running const int ledPin = 13; // LED state tracker bool ledState = 0; // Now do the necessary setup calls void setup() { // Send a command to the LCD module to tell it to initialize // itself. This is important because when the module comes // online or if it browns out due to a voltage dip, it can get // in an indeterminate state until it is reset (or re-reset). // // "lcd" is an object of type LiquidCrystal_I2C, and we are // invoking the "init" method for that object. We are // passing it two arguments, the width of the display (16 chars) // and the height of the display (two rows). lcd.begin(16,2); // Setup onboard LED to blink to know we are still alive when debugging pinMode(ledPin, OUTPUT); } // Now the stuff that runs forever void loop() { // Set the LCD Cursor to col 0 row 0 lcd.setCursor(0,0); lcd.print("Hello, world!"); // Set the LCD Cursor to col 0 row 1 lcd.setCursor(0,1); sprintf(LCDBuffer, "2015/03/28 %d", ledState); lcd.print(LCDBuffer); // Flip the on board LCD on and off. A nice assurance when debugging but not // seeing anything on the LCD (maybe because a wire is wrong). digitalWrite(ledPin, ledState); ledState = !ledState; // Delay half a second (500 microseconds) delay(500); }
|
Reepicheep
| Posted on Saturday, March 28, 2015 - 10:01 pm: |
|
Now lets tell temperature... Start the clock... |
Reepicheep
| Posted on Saturday, March 28, 2015 - 11:21 pm: |
|
Stop the clock. Just temp was too easy, so I am reading temps from two different sensors (both pretty lousy in terms of actual accuracy, much worse then my thermistor setup I made for my heater controller), and also humidity. Just cause I can. Under $10 worth of hardware here...
quote: // Temperature and Humidity Monitor // Bill@KilgallonFamily.com // Revision 1.0, 2015/03/28 // This program uses the LiquidCrystal_I2C library, which is // different (and much richer) than the one that came in // the SunFounder kit CD. // To install and use this new library (at least what I had to do today) // Go to https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home // Find the download link // https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads // Download the latest version (LiquidCrystal_V1.2.1.zip 2012/04/05) // Go to your arduino install library location // (i.e. C:/Arduino/libraries) // Move the LiquidCrystal folder to a new location and name it LiquidCrystal.orig // Extract the zip file you downloaded to create a new LiquidCrystal // folder in that library directory // In the Arduino IDE, go to Sketch->Import Library, and navigate to the LCD library // To load code to the Uno, make sure your Arduino IDE tool->programmer is set up // as AVRISP mkII and your port is correct. // To wire this up: // Hook the GND and VCC to the GND and Vin pins on the Arduino // Hook the A4 line on the Arduino up to the SDA line on the LCD I2C LCD module // Hook the A5 line on the Arduino up to the SCL line on the LCD I2C LCD module // // // Define include files necessary to simplify interaction with // peripherals // // Include headers for the two wire communication with the LCD // module. You can talk to the LCD directly using 7 output pins, // which works fine, or you can use an I2C module to talk to it // using only one pin. The I2C modules are only $2 or so, and // just connectors cost more than that, so even aside from eating up // fewer outputs, it makes sense to use more electronics and // and less wire. // // Plus, the two wires carry the concept of // an address, meanining they are really a bus, and you can // put more than just the LCD on these two wires, you can // also add other peripherals. #include <wire.h> // Now include the LCD library (again, the I2C version) #include <liquidcrystal_i2c.h> // Now include the DHT library (temp and humidity sensor) // I grabbed the libraries from the Sunfounder kit CD, but they // can be found on the web as well. Installation is similar to the // LCD library install directions above. #include <dht.h> // // Now define some global variables for use by the entire program // float lmTemp = 0; long lmVal = 0; // // Now define the pins for out LM35 temp sensor (really // just one analog input) // #define lmPin A0 // // And the pin for the DHT (temp and humidity) sensor // #define DHT11_PIN 4 // Now initialize the library to tell it about the LCD. // // The I2C interface basically lets us stuff a variety of parallel data // through a two wire interface. This saves pins on the arduino output, // and wires in the connector. Because the I2C bus is addressed, several // peripherals can all sit on the same two wires and be seperately addressed // // The arduino has plenty of pins if you just want to play with a LCD, you can // hook it up directly and not use the I2C stuff as well. // // The arguments are (in order): // * The LCD I2C address (can vary by maker) // * Which pin is the LCD EN pin // * Which pin is the LCD RW pin // * Which pin is the LCD RS pin // * Which pin is the LCD D4 pin // * Which pin is the LCD D5 pin // * Which pin is the LCD D6 pin // * Which pin is the LCD D7 pin // * Which pin is the LCD Backlight pin // * What the LCD backlight polarity is (POSITIVE | NEGATIVE) LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Now define stuff to blink onboard LED for sanity when debugging // so we know stuff is running const int ledPin = 13; // LED state tracker bool ledState = 0; // DHT object (humidity and temp) dht DHT; // Now do the necessary setup calls void setup() { // Send a command to the LCD module to tell it to initialize // itself. This is important because when the module comes // online or if it browns out due to a voltage dip, it can get // in an indeterminate state until it is reset (or re-reset). // // "lcd" is an object of type LiquidCrystal_I2C, and we are // invoking the "begin" method for that object. We are // passing it two arguments, the width of the display (16 chars) // and the height of the display (two rows). lcd.begin(16,2); // Setup onboard LED to blink to know we are still alive when debugging pinMode(ledPin, OUTPUT); } // Now the stuff that runs forever void loop() { // Read the temperature from the LM35 temp sensor lmVal = analogRead(lmPin); // Convert counts to degrees C // Equation derived from LM35 data sheet // Device reads 10mv / deg C // mv = (counts/1024) * 5000 (ratio of 0 to 1024 across 5v) // degC = mv / 10 // Solving for degC = ((counts/1024) * 5000) / 10 // Simplifying degC = counts * .4883 lmTemp = (lmVal * 0.48828125); // And convert degrees C t0 degrees F lmTemp = (((lmTemp * 9.0)/5.0) + 32.0); // Set the LCD Cursor to col 0 row 0 lcd.setCursor(0,0); lcd.print("LMTmp="); lcd.print(lmTemp); lcd.print(" F "); // Flip the on board LCD on and off. A nice assurance when debugging but not // seeing anything on the LCD (maybe because a wire is wrong). digitalWrite(ledPin, ledState); ledState = !ledState; // Now get the DHT temp and humidity // This returns DHTLIB_OK, DHTLIB_ERROR_CHECKSUM, and DHTLIB_ERROR_TIMEOUT // but we are ignoring those for this demo DHT.read11(DHT11_PIN); // Set LCD cursor to col 0 row 1 lcd.setCursor(0,1); lcd.print("DT="); // Gotta convert deg C to degrees F while printing lcd.print( (((DHT.temperature * 9.0)/5.0) + 32.0), 1); lcd.print(" Hum="); lcd.print(DHT.humidity, 1); lcd.print("%"); // Cant read the DHT more than once every 2 seconds so slow everything down delay(2500); }
|
Reepicheep
| Posted on Sunday, March 29, 2015 - 12:51 am: |
|
quote:Sketch uses 6,974 bytes (21%) of program storage space. Maximum is 32,256 bytes. Global variables use 340 bytes (16%) of dynamic memory, leaving 1,708 bytes for local variables. Maximum is 2,048 bytes.
That leaves a lot of room |
Reepicheep
| Posted on Wednesday, April 01, 2015 - 06:14 pm: |
|
Starting to prototype the heater controller on the Arduino... a very nice little platform. This is reading several thousand samples per second, and reporting the current, lowest, and highest values observed since it started measuring. I'll probably change that to one minute windows, or maybe give it a "reset highs and lows" button. Simple code so far.
quote: // Heated gear controller // Bill@KilgallonFamily.com // Revision 1.0, 2015/03/28 // Configuration notes // // This program uses the LiquidCrystal_I2C library, which is // different (and much richer) than the one that came in // the SunFounder kit CD. // To install and use this new library (at least what I had to do today) // Go to https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home // Find the download link // https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads // Download the latest version (LiquidCrystal_V1.2.1.zip 2012/04/05) // Go to your arduino install library location // (i.e. C:\Arduino\libraries) // Move the LiquidCrystal folder to a new location and name it LiquidCrystal.orig // Extract the zip file you downloaded to create a new LiquidCrystal // folder in that library directory // In the Arduino IDE, go to Sketch->Import Library, and navigate to the LCD library // // To load code to the Uno, make sure your Arduino IDE tool->programmer is set up // as AVRISP mkII and your port is correct. // // To wire the LCD up: // Hook the GND and VCC to the GND and Vin pins on the Arduino // Hook the A4 line on the Arduino up to the SDA line on the LCD I2C LCD module // Hook the A5 line on the Arduino up to the SCL line on the LCD I2C LCD module // // // Define include files necessary for the libraries we want to use // // Include headers for the two wire communication with the LCD // module. You can talk to the LCD directly using 7 output pins, // which works fine, or you can use an I2C module to talk to it // using only one pin. The I2C modules are only $2 or so, and // just connectors cost more than that, so even aside from eating up // fewer outputs, it makes sense to use more electronics and // and less wire. // // Plus, the two wires carry the concept of // an address, meanining they are really a bus, and you can // put more than just the LCD on these two wires, you can // also add other peripherals. // #include <wire.h> #include <liquidcrystal_i2c.h> // // Define the pin for the input voltage to the heater (bike voltage) // just one analog input) // #define bikeVoltPin A0 // // Now define some global variables for use by the entire program // float bikeVolts, highVolts, lowVolts; // Now initialize the library to tell it about the LCD. // // The I2C interface basically lets us stuff a variety of parallel data // through a two wire interface. This saves pins on the arduino output, // and wires in the connector. Because the I2C bus is addressed, several // peripherals can all sit on the same two wires and be seperately addressed // // The arduino has plenty of pins if you just want to play with a LCD, you can // hook it up directly and not use the I2C stuff as well. // // The arguments are (in order): // * The LCD I2C address (can vary by maker) // * Which pin is the LCD EN pin // * Which pin is the LCD RW pin // * Which pin is the LCD RS pin // * Which pin is the LCD D4 pin // * Which pin is the LCD D5 pin // * Which pin is the LCD D6 pin // * Which pin is the LCD D7 pin // * Which pin is the LCD Backlight pin // * What the LCD backlight polarity is (POSITIVE | NEGATIVE) LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Now define stuff to blink onboard LED for sanity when debugging // so we know stuff is running const int ledPin = 13; // LED state tracker bool ledState = 0; // Counter short unsigned int counter = 0, burstCounter; // Now do the necessary setup calls void setup() { // Send a command to the LCD module to tell it to initialize // itself. This is important because when the module comes // online or if it browns out due to a voltage dip, it can get // in an indeterminate state until it is reset (or re-reset). // // "lcd" is an object of type LiquidCrystal_I2C, and we are // invoking the "begin" method for that object. We are // passing it two arguments, the width of the display (16 chars) // and the height of the display (two rows). lcd.begin(16,2); // Setup onboard LED to blink to know we are still alive when debugging pinMode(ledPin, OUTPUT); // Start them all even so we can compare and get highs and lows right bikeVolts = highVolts = lowVolts = analogRead(bikeVoltPin) * .0293255; } // Now the stuff that runs forever void loop() { // Counters gonna count counter++; // Read the voltage from the precision resistor divider // on Vin instead of regulated 5v. Should work all the // way up to the point where the magic smoke comes out // // Convert counts to volts // Equation derivation: // 1024 counts = 5V (how Arduino is set up) // So 5.0 * (counts / 1023) is voltage read // Or voltRead = .00488759 * counts // // But this is reading a voltage divider, not pure input // voltage (so we can read more than 5 volts) // So Vin = ((10k + 2k) / 2k) * voltage read // or Vin = 6 * voltage read // // Combining these two equations gives // bikeVolts = (.00488759 * analogRead(bikeVoltPin)) * 6.0; // Which can be simplified to analogRead(bikeVoltPin) * .0293255 for ( burstCounter = 0; burstCounter < 1000; burstCounter++ ) { bikeVolts = analogRead(bikeVoltPin) * .0293255; // See if we have a new high score if (bikeVolts > highVolts ) { highVolts = bikeVolts; } // Or a new low score if (bikeVolts < lowVolts) { lowVolts = bikeVolts; } } // Set the LCD Cursor to col 0 row 0 lcd.setCursor(0,0); // Display current voltage with one decimal place lcd.print(bikeVolts,1); lcd.print("V"); lcd.print("("); lcd.print(lowVolts, 1); lcd.print("/"); lcd.print(highVolts,1); lcd.print(") "); // Display count // lcd.setCursor(0,1); // lcd.print(counter); // lcd.print(" "); // Flip the on board LCD on and off. A nice assurance when debugging but not // seeing anything on the LCD (maybe because a wire is wrong). digitalWrite(ledPin, ledState); ledState = !ledState; // Delay to make LCD more readable delay(0); }
|
|