11-19-14, 10:21 PM | #291 |
Supreme EcoRenovator
|
I just finished some reading on the AVR/ATMEGA chipset, and learned something useful: the processor has no hardware support for division at all! Integers, longs, floats, whatever gets divided will be compiled into repeated subtraction. WOW.
|
11-20-14, 01:44 AM | #292 |
Helper EcoRenovator
Join Date: Jul 2014
Location: Hungary
Posts: 34
Thanks: 0
Thanked 16 Times in 10 Posts
|
floats and 1w temp sensors
In my hetpump controller sw I use long and float operations alot. In such application the speed of the uC is plenty to waste for emulated floating point operations. Even there are several frequent interruts from flow sensors, timer, there is tcp/ip communication and the user interface is still responsive.
In my code, I implemented setup menu for dallas temp sensor assignment. I store the assigned 1w addresses in eeprom, in the background, the program periodically read the temperature information from sensors one by one and stores the result in a global array. From "main" program I just use the temperatures from the array. The setup menu looks like this: l 1w List of 1W devices: Bus:0 1W bus number 00;28B0BFA704000088 20.44C 0; (0) Air in device number, serial, measuret temperature (if device support it) assigned function number, assigned function description 01;28328EA704000045 20.81C 2; (0) Air evap. gas 02;286AC6A70400001D 20.13C 7; (0) Condenser gas 03;282EC6A7040000B4 20.44C unassigned device 04;28AED4A7040000A1 20.75C 05;28055CA80400006A 20.81C 1; (0) Air out 06;284382A7040000CB 20.06C 13; (0) Suction temp 07;2857FEA704000000 19.25C 8; (0) Condenser liquid 08;285F8DA704000082 20.06C 09;28FFBDA70400005A 19.31C 9; (0) Heating water in Bus:1 no device on bus Bus:2 00;281239BB030000BD 24.63C 11; (2) Electric box Functions: 00; * Air in * means device assigned to function 01; * Air out 02; * Air evap. gas 03; Water evap. liquid 04; Water evap. gas 05; Well water in 06; Well water out 07; * Condenser gas 08; * Condenser liquid 09; * Heating water in 10; Heating Water out 11; * Electric box 12; Compressor 13; * Suction temp 14; Discharge temp a 0 3 10 assign command, bus number, device number, function number see above a 0 4 06 like above l1w list new 1w config If you want to import it, i'm willing to help you to dig out from my code the related parts. In my topic you can find details http://ecorenovator.org/forum/geothe...iscussion.html This post is here about it: http://ecorenovator.org/forum/39116-post8.html T. Last edited by takyka; 11-20-14 at 02:11 AM.. |
The Following 2 Users Say Thank You to takyka For This Useful Post: |
11-20-14, 03:27 AM | #293 | |
Apprentice EcoRenovator
Join Date: Oct 2014
Location: SE MI
Posts: 105
Thanks: 3
Thanked 12 Times in 9 Posts
|
Quote:
Even the whimpy μprocessor I programmed on 35 years ago had hardware divide. That was quite unusual back then, but I just kind of assumed it was there. |
|
11-20-14, 08:03 AM | #294 |
Apprentice EcoRenovator
Join Date: Oct 2014
Location: SE MI
Posts: 105
Thanks: 3
Thanked 12 Times in 9 Posts
|
Arduino Mega or Arduino Due. IMHO, the 3.3v Vref of the Due is a big strike against it.
|
11-20-14, 04:43 PM | #295 | |
Supreme EcoRenovator
|
Quote:
Maybe somebody might start a project based on a Mega, but why? It shares the same instruction set and cpu as the Uno. If you can rig up a Uno and get it working, you can rig up a Mega. If you have that many sensors and output pins to deal with, to need a Mega, the system is no longer a general-purpose-friendly setup. It does have more onboard flash and ram, though. If I really needed more memory, I would add a shield that I could stick an SD card into. With the shield, I would probably add some sort of wireless comms also. Cheap thrills. If I really really wanted more processing power, I might hold out for the Zero. A whopping 256k of flash and 32k of ram. ARM Cortex processor @32 bits and 48 MHz. Oooh la la! But alas, it runs at 3.3VDC. Shucks. I can always give up my prefab LCD keypad shield for another display if I really need the extra pins. Given the fact that there are all kinds of sensors, displays, and control devices that will work over serial comms or the 1wire or 2wire interface standards, I doubt this basic controller would need a whole lot else to do its "basic" job.. |
|
The Following User Says Thank You to jeff5may For This Useful Post: | buffalobillpatrick (11-21-14) |
11-21-14, 01:50 AM | #296 |
Helper EcoRenovator
Join Date: Jul 2014
Location: Hungary
Posts: 34
Thanks: 0
Thanked 16 Times in 10 Posts
|
The arduino mega is a 5V device! As long as one doesn't need computation power of 32bit systems, but for more pins or memory does, arduino mega can be a good choice.
Unlike some are thinking multiplexed analog inputs or IO port expanders, these are needless with mega. And all UNO shields are compatible... In relationto this, one more tought about 1wire adressing. As separate arduino pins can be used for analog sensor reading, the same way, dallas sensors can be connected to separate pins too (one ds18xxx on one pin). This way temperature reading can be done without the knowledge of sensor ID, sensor swap is as easy as in case of NTC. Where temperature reading speed is not a concern, (more than one reading/ second), I prefer DS sensors over NTC because of accuracy, noise immunity and unnecessarity of calibration. T. |
The Following 2 Users Say Thank You to takyka For This Useful Post: |
11-21-14, 08:00 PM | #297 | |
Supreme EcoRenovator
|
Quote:
The reason I brought up the Zero is because it looks as if it will be the "nexgen" replacement for the Uno. Likewise, the Due will be the "nexgen" replacement for the Mega. The Arduino crew is working hard to make sure that "old school" programs and libraries can migrate to the new boards and work. I don't know how seamlessly this will end up, but the time is coming soon when the retail version of the Zero will hit the market. As I write this, competitors are already releasing "knockoff" boards based on the pre-production architecture. I believe that the Uno and Mega will remain the most widely used boards in the line for quite some time. Until the "modernized" boards get lots of specific code and support content tailored for them (as with the Uno and Mega), they won't attract users and beginners like the "original" boards do. That doesn't mean they're not useful. They just haven't stolen the spotlight from their parents yet. |
|
The Following User Says Thank You to jeff5may For This Useful Post: | buffalobillpatrick (11-24-14) |
11-25-14, 10:38 PM | #298 |
Supreme EcoRenovator
|
Here she comes
OK, since nobody is doing any interaction with the code I put up on github, I'll just post it in here. This rough alpha version is basically a wall thermostat with auto-change-over. There have been a few pieces chopped out of it that are giving me problems, but what is here will compile with the libraries off hacktronics and run like magic.
Come get some: Code:
// include the library code: #include <LiquidCrystal.h> #include <OneWire.h> #include <DallasTemperature.h> // define pin configuration: #define defrostSensor A2 #define lcdBacklightPin 10 #define reversingValve 11 #define indoorPump 12 #define compressor 3 OneWire ds(13); // Temperature sensors on pin 13 DallasTemperature sensors(&ds); int x = 1; // initialize the LCD library with the numbers of the interface pins LiquidCrystal lcd(8, 9, 4, 5, 6, 7); boolean fan = false, thermostat = false, heatingCall = false, coolingCall = false, compressorLockout = true ; float temp_c, temp_f; int y, heat_sp, cool_sp, defrost_t, settemp = 25; int state = 0, right = 0, left = 0, up = 0, down = 0, last_st = 0, st = 0; byte sel = 0, mode = 0; unsigned long up_time_1 ,up_time_2, up_time, last_request, lastLockout; double time_1, time_2, time; void process_io(); void process_display(); void setup() { // set up the LCD's number of columns and rows: lcd.begin(16, 2); sensors.begin(); pinMode( lcdBacklightPin, INPUT ); pinMode( defrostSensor, INPUT); pinMode( reversingValve, OUTPUT ); pinMode( indoorPump, OUTPUT ); pinMode( compressor, OUTPUT ); last_request = millis(); digitalWrite(lcdBacklightPin, LOW); //Turn on the backlight // Print a message to the LCD. lcd.setCursor(0,0); lcd.print("Control center"); lcd.setCursor(0,1); lcd.print("Startup Delay"); delay(12000); up_time_1 = millis(); time_1 = millis(); compressorLockout = false; } void process_io() { if ((millis()-last_request) > 15000) { get_temp(); last_request = millis(); } switch(mode) { case 0: //mode is off heatingCall = false; coolingCall = false; lastLockout = millis(); break; case 1: //mode is heat digitalWrite(reversingValve,false); if (temp_c < (settemp - 1)) heatingCall = true; if (settemp < temp_c) { heatingCall = false; compressorLockout = true; lastLockout = millis(); } break; case 2: //mode is cool digitalWrite(reversingValve,true); if (temp_c < (settemp + 1)) coolingCall = true; if (settemp > temp_c) { coolingCall = false; compressorLockout = true; lastLockout = millis(); } break; case 3: //mode is auto if (abs(temp_c - settemp)>2) { //auto-changeover territory if (temp_c < settemp){ digitalWrite(reversingValve, false); //changeover to heating heatingCall = true; } else { digitalWrite(reversingValve, true); // changeover to cooling coolingCall = true; } } if ((temp_c - settemp) > 1) coolingCall = true; if ((settemp - temp_c) > 1) heatingCall = true; if (abs(temp_c - settemp)<.05) { heatingCall = false; coolingCall = false; compressorLockout = true; lastLockout = millis(); } break; } if (heatingCall || coolingCall && (millis() - lastLockout < 120000)&& compressorLockout) { //2 minute lockout digitalWrite(compressor,true); digitalWrite(indoorPump,true); compressorLockout = false; } else { digitalWrite(compressor, false); digitalWrite(indoorPump,false); } } void process_display() { switch (right) { case 0: lcd.clear(); lcd.setCursor(0,0); lcd.print("Current "); lcd.print(temp_c); if (up>0){ settemp=settemp+1; up=0; } if (up<0) { settemp=settemp-1; up=0; } lcd.setCursor(0,1); lcd.print("Setpnt "); lcd.print(settemp); break; case 1: lcd.clear(); lcd.setCursor(0,0); lcd.print("Mode ^ "); switch(up) { case 0: lcd.print("OFF v"); mode=0; break; case 1: lcd.print("HEAT v"); mode=1; break; case 2: lcd.print("COOL v"); mode=2; break; case 3: lcd.print("AUTO v"); mode=3; break; case 4: up=0; break; case -1: up=3; break; } lcd.setCursor(0,1); lcd.print("Press select to set"); if(sel == 1){ mode=up; sel = 0; lcd.clear(); lcd.setCursor(0,0); lcd.print("Mode set."); lcd.setCursor(0,1); lcd.print(temp_c); lcd.print("C//"); lcd.print(temp_f); lcd.print("F"); delay(3000); } break; case 2: lcd.clear(); lcd.setCursor(0,0); lcd.print("Get up time"); lcd.setCursor(0,1); lcd.print("Press select"); if(sel == 1){ get_up_time(); sel = 0; lcd.clear(); lcd.setCursor(0,0); lcd.print("Up time"); lcd.setCursor(0,1); lcd.print(up_time); lcd.print(" sec"); delay(3000); } break; case 3: lcd.clear(); lcd.setCursor(0,0); lcd.print("RxBuffer up"); lcd.setCursor(0,1); lcd.print("Press select"); if(sel == 1){ sel = 0; lcd.setCursor(0,0); lcd.print("VALUE "); lcd.print(up); } break; case 4: lcd.clear(); lcd.setCursor(0,0); lcd.print("Thermostat?"); lcd.setCursor(0,1); if (thermostat) { lcd.print("YES"); } else { lcd.print("NO"); } if (up>0){ thermostat=true; up=0; } if (up<0) { thermostat=false; up=0; } break; } } void process_state(){ switch (state) { case 1: //right right = right + 1; if(right > 4) { right = 0; } break; case 2: //up up = up + 1; break; case 3: //down up = up - 1; break; case 4: //left right = right - 1; if(right < 0) { right = 4; } break; case 5: break; } } void read_state(){ state = 0; y = analogRead (0); //lcd.setCursor(10,1); if (y < 100) { //lcd.print ("Right "); state = 1; } else if (y < 200) { //lcd.print ("Up "); state = 2; } else if (y < 400){ //lcd.print ("Down "); state = 3; } else if (y < 600){ //lcd.print ("Left "); state = 4; } else if (y < 800){ //lcd.print ("Select"); state = 5; sel = 1; } } void get_up_time(){ up_time_2 = millis(); up_time = up_time_2 - up_time_1; up_time = up_time/1000; //time in seconds } void get_temp() { if ((millis() - last_request)>5000) { sensors.requestTemperatures(); last_request = millis(); temp_c = (sensors.getTempCByIndex(0)); temp_f = (sensors.getTempFByIndex(0)); } } void loop() { time_2 = millis(); last_st = state; read_state(); st = state; if(st != last_st){ process_state(); //delay(45); time_1 = millis(); } time = time_2 - time_1; time = time/1000; if(time <=10){ pinMode( lcdBacklightPin, INPUT); //deals with possible hardware bug, turns backlight on. } else{ pinMode( lcdBacklightPin, OUTPUT ); //deals with possible hardware bug, lets pin float, backlight shuts off via shield pullup resistor. right = 0; up = 0; } delay(190); process_display(); process_io(); I am dealing with a defrost function now that will work with an air-source unit. I'm doing n adaptive defrost algorithm based on a carrier board that has been around for a long time. |
11-25-14, 10:47 PM | #299 |
Supreme EcoRenovator
|
How is the water-source controller coming along? Have you all sorted out a serial interface? Does anything work?
As long as the blasted machine doesn't go off the deep end with interrupts, I might be able to integrate some of the functionality into what I have working. I could ditch the keypad shield if I had to. If I don't have to, I won't. But I might.... |
12-27-14, 10:40 PM | #300 | |
Supreme EcoRenovator
|
Quote:
http://diyhacking.com/projects/FlowMeterDIY.ino The main article is here: Measure Water Flow Rate and Quantity Arduino DIY Project - DIY Hacking It seems you have decided to go the way BBP has, using interrupts to count pulses. It is less code intensive to use this method, but you have to remember that there are multiple things that can be going on at any given time. With the simplistic nature of your device, it might not give you much trouble. One interrupt for measuring evap side flow, one interrupt for measuring condenser side flow. Sorry it took so long for me to reply to this post. I had the general idea that you and BBP had worked out an algorithm that worked for both of you. If you need some coding done, I can help. |
|
|
|