Show Posts
|
|
Pages: [1]
|
|
1
|
Using Arduino / Displays / Re: MENWIZ: yet another character lcd menu wizard library
|
on: January 21, 2013, 08:02:39 pm
|
|
I had this same problem and found that my copy of the menwiz.h library was different on the other computer. I usually copy my files onto a usb drive to move them between computers. I somehow managed to get a copy that did not have the #define BUTTON_SUPPORT line commented out. So if you don't have #include <buttons.h> in your sketch and the menwiz.h calls for it you get the error.
|
|
|
|
|
2
|
Using Arduino / Programming Questions / Re: Please help with array issues
|
on: January 15, 2013, 10:04:40 pm
|
i am kind of new to this, but I think you are only specifying 1 voltage and 1 current with this: int lcd_disp[16][3] = {0}; double volts; double current; I believe that you also have to create an array for volts and current. I think you also need to set up a loop to read and and store the variables. Something like this: #define SENSORS 5 // number of sensors in loop float degreesF[SENSORS]; byte Sensor[SENSORS][8]; // creates byte var. array called Sensor[from zero to #SENSORS][8 bytes long]
void setup() for (int i = 0; i < SENSORS; i++) { degreesF[i] = sensors.getTempF(Sensor[i]); } Loop will also work to display results. It looks like you are reading the address and then using a switch to decide which results to display. Then incrementing the max9611 addr and starting over. I think the loop is more efficient unless you have something where you can pick a specific address lcd.print(max9611_addr<<1,HEX); //print address switch (max9611_addr) { case 0x70: lcd_disp[0][0] = max9611_addr; lcd_disp[0][1] = current; lcd_disp[0][2] = volts; break; case 0x71: .........
|
|
|
|
|
4
|
Using Arduino / Programming Questions / Re: Communication with 2 x DS18B20
|
on: January 09, 2013, 09:42:01 pm
|
I have a hacked version of one of the Dallas_Temperature_Control library examples that searches for your sensors, displays the device count, addresses and temps in degC and degF and probably some other stuff. You will have to modify this if using 2 pins for the sensors. I also have a hacked version that allows manual entry of the addresses and the ability to return temps by index instead of address if you are interested. I use this method, partly because I was struggling with the address method and attempting to input the results in an array. /* Modification of the Dallas Temperature Multiple Example to auto search all devices and report addresses and temps. Date 12/18/2012 */ #include <OneWire.h> #include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino #define ONE_WIRE_BUS 2 #define TEMPERATURE_PRECISION 9
// Temp Sensor setup #define DS1820_SENSORS 5 // number of sensors in loop byte Temp[DS1820_SENSORS][8]; // creates byte var. array called Temp[0-DS1820_SENSORS][8 bytes long]
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire);
// arrays to hold device addresses DeviceAddress temp[DS1820_SENSORS]; // stores addresses in uint8_t format
// Define variables to store temps for each sensor float tempC[DS1820_SENSORS]; float tempF[DS1820_SENSORS]; float degreesF[DS1820_SENSORS];
void setup(void) { // start serial port Serial.begin(9600); Serial.println("Dallas Temperature IC Control Library Demo");
// Start up the library sensors.begin();
// locate devices on the bus Serial.print("Locating devices..."); Serial.print("Found "); Serial.print(sensors.getDeviceCount(), DEC); Serial.println(" devices.");
// report parasite power requirements Serial.print("Parasite power is: "); if (sensors.isParasitePowerMode()) Serial.println("ON"); else Serial.println("OFF");
// search for devices on the bus and assign based on an index. // method search() looks for the next device. Returns 1 if a new address has been // returned. A zero might mean that the bus is shorted, there are no devices, // or you have already retrieved all of them. The order is // deterministic. You will always get the same devices in the same order // // Must be called before search() oneWire.reset_search(); byte sensor; byte present = 0; byte data[12]; for (sensor=0;sensor<DS1820_SENSORS;sensor++) { if (!sensors.getAddress(Temp[sensor], sensor)) Serial.println("Unable to find address for Device"); printAddress(Temp[sensor]); } }
// function to print a device address void printAddress(DeviceAddress deviceAddress) { for (uint8_t i = 0; i < 8; i++) { // zero pad the address if necessary if (deviceAddress[i] < 16) Serial.print("0"); Serial.print(deviceAddress[i], HEX); } Serial.println(); }
// function to print a device's resolution void printResolution(DeviceAddress deviceAddress) { Serial.print("Resolution: "); Serial.print(sensors.getResolution(deviceAddress)); Serial.println(); }
void loop(void) { // loop to print temps sensors.requestTemperatures(); // Send the command to get temperatures for( int j =0; j < DS1820_SENSORS; j++){ printData(Temp[j]); printTemperature(Temp[j]); // Use a simple function to print out the data } } // main function to print information about a device void printData(DeviceAddress deviceAddress) { Serial.print("Device Address: "); printAddress(deviceAddress); Serial.print(" "); }
void printTemperature(DeviceAddress deviceAddress) // function to print the temperature for a device { int i; tempC[i] = sensors.getTempC(deviceAddress); tempF[i] = (DallasTemperature::toFahrenheit(tempC[i])); // Converts tempC to Fahrenheit degreesF[i] = tempF[i]; // copies value so PID can read Serial.print("Temperature: "); Serial.print(degreesF[i]); Serial.println(" degrees F"); delay (1000); }
|
|
|
|
|
5
|
Using Arduino / Displays / Re: How to use only only 3 or 5 buttons using "back" menu entry
|
on: January 09, 2013, 09:19:05 pm
|
Due to my complete ignorance it took me a while to figure this 3 or 5 button thing out completely. But that is part of the learning process is trying to figure out where my mistakes are. I have it compiled but not tested. Program is at 30.7k and I have to get my double PID data converted to float for menwiz.h and then converted back to float for the PID_V1.h. One question I have: does the new "BACK" menu option need to be in each terminal node? OK, make it 2 questions: Can it be a menu.addItem instead of menu.addMenu? I'll find out in testing for sure. s2=menu.addMenu(MW_VAR,s1,F("Back")); //add a terminal node (that is "variable"); s2->addVar(MW_ACTION,&bte); //create a variable of type "action" s2->setBehaviour(MW_ACTION_CONFIRM,false); // you don't need action confirmation to emulate Escape button!!!
|
|
|
|
|
6
|
Using Arduino / Displays / Re: How to use only only 3 or 5 buttons using "back" menu entry
|
on: January 06, 2013, 08:27:56 pm
|
Hi. for all people interested in "odd" button models (that is 3 or 5 button models) I give you a *very simple* patch to implement it now. The next version will consolidate the change. Inside the library is implemented a "logical level" where are defined all actions performed after a button push. Those functions are private members of class menwiz, so it is necessary to make just one change to the MENWIZ.h file, moving the definition of actBTE() from private to public. That is all. In your sketch you can implement a menu entry acting exactly as the escape button as following (example): void bte(){ menu.actBTE();} I'm also trying to use a 5 button analog and can't make the above line compile. It does work if I leave this in Private Private: void actBTE();
and use this in Public: with the menu.actBTE commented out. Also BTE needs to be all capitols. Public: void BTE(); /* { menu.actBTE(); } */ When the menu.actBTE is not commented I get these errors : C:\arduino-1.0.3\libraries\MENWIZ/MENWIZ.h: In member function 'void menwiz::BTE()': C:\arduino-1.0.3\libraries\MENWIZ/MENWIZ.h:202: error: 'menu' was not declared in this scope I don't have my display handy so I can't test the compiled code to see if it works. I'm no c++ expert so I'm not quite sure what to do with this.
|
|
|
|
|
8
|
Using Arduino / Programming Questions / Re: MenWIZ using double instead of float
|
on: January 04, 2013, 09:07:34 pm
|
Use casts.
I don't think this is going to work because I have to put the MENWIZ menu structure in setup() so it's a run once thing. If I have dynamic data, such as my room temp that I want to display. I can see doing this for static double like my PID setpoint. Slightly stripped down version here: #include <Wire.h> //INSERT ALL THE LIBARIES AFTER INCLUDING WIRE LIB (MENWIZ request) #include <LiquidCrystal_I2C.h> #include <MENWIZ.h> #include <PID_v1.h> #include <PID_v1.h> // PID setup const int numSensors = 4; // 4 temp sensors used with PID double Input[numSensors]; // Arrays of 4 input and output variables double Output[numSensors]; double Setpoint[numSensors] = {68, 72, 72, 72}; double kp = 3; double ki = 5; double kd = .1; PID Room0(&Input[0], &Output[0], &Setpoint[0], kp, ki, kd, DIRECT); PID Room1(&Input[1], &Output[1], &Setpoint[1], kp, ki, kd, DIRECT); PID Room2(&Input[2], &Output[2], &Setpoint[2], kp, ki, kd, DIRECT); PID Room3(&Input[3], &Output[3], &Setpoint[3], kp, ki, kd, DIRECT);
// Create global object for menu and lcd menwiz menu; LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlightpin, polarity 4 x 20 LCD
// analog buttons sample const int buttonPin = A0; // 6 button switch circuit input connected to analog pin 0 boolean buttonBlock = 0; boolean buttonAct = 0; // flag 1 boolean stopMenu = 0; // flag 2 byte buttonPressed = 0; // which button was pressed byte lastButtonPressed = 0; // prev button pressed int buttonValue = 0; // read value from analog port for the 4 navigation pushbuttons long menuOffTime = 0; //used for timer extern byte MW_navbtn; //needed to run the software key navigation in Menwiz
void setup() { Serial.begin(9600); Serial.println("The Midway Zone Heat Control");
//++++++++++++++++++++Menu and LCD char b[84]; _menu *r,*s1,*s2; float room0SP = (float) Setpoint[0]; // cast operator
// initialize the menu object ( 2 x rows x 16 columns LCD) menu.begin(&lcd,16,2); menu.addUsrNav(navMenu, 6); MW_navbtn=6; // force 4 or 6 buttons mode for menu navigation -> MW_navbtn=4; or MW_navbtn=6;
//create the menu tree r=menu.addMenu(MW_ROOT,NULL,F("MAIN MENU")); //create a root menu at first (required)
//--------------- s1=menu.addMenu(MW_SUBMENU,r,F("VIEW ROOM INFO")); s2->addItem(MW_LIST,F("SETPOINTS")); //create a variable of type "option list".. s2->addItem(MW_LIST,F("MASTER BEDROOM")); //add option to the OPTION LIST // s2->addVar(MW_AUTO_FLOAT,Setpoint[0], 65, 75, 1); } void loop() { // NAVIGATION MANAGEMENT & DRAWING ON LCD. NOT BLOCKING has to be the first in the void loop menu.draw(); navMenu(); } int navMenu() // { /* As soon as a button is pushed the first time flag 1 is set to HIGH and if the buttonnumber is not 0 then a timer is started. The menu action then should only be performed once. After 2000 msecs the flag will be set to LOW and a new buttonpush can be processed. Menu action is blocked for 2000 msec even if the same button is being kept pressed for 2000 msecs by flag2. */
long menublockTime = millis();
if (buttonAct == 1 && buttonPressed != 0 && stopMenu == 0) // we have a state were we process a menu navigation step once and block it for 2 secs { // digitalWrite(led13Pin,HIGH); // set timer led ON menuOffTime = menublockTime + 2000; //start the timer. You can change this blocking time to your convenience but do not make it lower aa 200 msecs stopMenu = 1;
switch (buttonPressed) { case 1: // Right return MW_BTR; break; case 2: // Up return MW_BTU; break; case 3: // Down return MW_BTD; break; case 4: // Left return MW_BTL; break; case 5: // Select or Confirm return MW_BTC; break; case 6: // Escape NOT USED return MW_BTE; break; } }
if (menuOffTime != 0 && menublockTime > menuOffTime) // Reset of the timer so a new menu action can be processed { buttonAct = 0; // resets the flag 1 buttonPressed = 0; menuOffTime = 0; // resets timer to zero stopMenu = 0; } }
If I wanted to display dynamic data I would have to use the cast operator at the end of the loop() and I assume that when menu.draw(); runs it will pull in the data. Am I thinking correctly?
|
|
|
|
|
9
|
Using Arduino / Programming Questions / Re: MenWIZ using double instead of float
|
on: January 03, 2013, 11:39:55 am
|
|
Oh yea, cast. I remember something about that in my java class. Finally a practical use for it. Adds more variables so my memory creeps up.
I have disabled eeprom and buttons since I am using using an analog input with 5 buttons. The analog sample I found used sprintf to display the usrScreen. I redid that part with sbuf.
I had been attempting to use phi_interface for the analog but the getKey was returning something that was close to the analog values instead of 1-5 like the class appeared to be programmed to return. So I ended up doing the same thing with the custom analog function and deleted phi. That's how I got to 29.2k.
Mega 2560 is in my future. Found some china clones on ebay for $22 last night. I think the real deal is a better choice.
I'll probably end up using some program on the laptop to graph the PID performance so I will be adding Ethernet and sd card. Memory creep.
Is there any method to get 3 variables displayed at the same time in the menu?
|
|
|
|
|
10
|
Using Arduino / Programming Questions / MenWIZ using double instead of float
|
on: January 02, 2013, 10:14:37 pm
|
Been at this Arduino stuff for about a month. Here is the project info: Arduino UNO R3 Pololu Micro Serial Servo with 4 servos (expanding to 6 in final version) on SoftwareSerial pin. String of 5 Dallas 1 wire DS18B20 temp sensors (expanding to 7 in final version) Freetronics LCD 16x2 shield with I2C backpack 5 buttons on analog pin a couple of digital pins OUTPUT to control a fan, furnace and reset Pololu a couple of digital pins INPUT to check if furnace is on What this turns into is a 4 to 6 zone heat controller with PID control of the servos connected to dampers. Fan connected to duct work near the fireplace is turned on by a local temp sensor @ 70 degF or if the furnace is running. It is a functioning system without the menu or analog buttons. I'm using the following libraries: #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <MENWIZ.h> #include <PID_v1.h> #include <OneWire.h> #include <DallasTemperature.h> #include <SoftwareSerial.h> What I am trying to do is use MenWIZ to display the 6 rooms information on a submenu and on another submenu adjust the 6 rooms setpoints. My preferred method is to input the same variables that the PID's are using: Setpoint, Input and Output. The unfortunate part is that the PID vars are double types and MenWIZ requires float type. I can easily convert these to float by adding more variables to the program, however, I'm currently at 29,200 bytes and I haven't finished my menu yet. Any ideas on this one? I'm also trying to display vars on 2 lines like this: SP: 72 IN: 68 OUT: 95 % // this may end up as a 0-255 value instead. I also need to be able to adjust the setpoint which is a double type. Stupid question of the day: Since double and float are the same, according to the reference, why is double used so often? I suppose that I could hack the PID library.
|
|
|
|
|