Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : MM2: Dual Battery Monitor
Author | Message | ||||
disco4now Guru Joined: 18/12/2014 Location: AustraliaPosts: 844 |
Back in December I stumbled across TBS and Micromite while googling. I had not played with electronics since the 80's so I ordered a couple of MUPs off Mick to see if they could be the solution to some problem I might be able to dream up. Well here it is! We have a caravan and when we are free camping I am always looking at the battery voltage to see how the batteries are holding up. The car has a dual battery setup and a national Lunar dual battery monitor that shows a row of LEDs that represent the voltage of each battery. In both cases you see the current voltage, what would be more informative would be to see the history of the voltage as well.i.e. is is going down fast, holding. Enter the MMII Dual Battery Monitor using the ILI9341 touch screen to graph the voltage. The screen has left and right next page buttons across the bottom and down the right a number of different mode buttons. The time scale is across the top. The area left (240 pixels by 180 pixels is used to display a rolling graph of the 4 values. This is updated each second with the existing values move left by one pixel and the new values added at the right most pixel. There are six pages stored. In the 1 second mode the most recent 24 minutes worth of 1 second readings are available. In the 1 minute mode the most recent 24 hours of 1 minute averages are available. In the 3 minute mode the most recent 72 hours of 3 minute averages are available. In the 6 minute mode the most recent 6 days of 6 minute averages are available. All data is stored in the MX170 memory. When data is read it is converted to the y coordinate where it will be graphed. So actual values are not stored, just the y coordinate of where they would display. This means the range of values is 30 to 210 so 8 bits is enough. This allows 4 values to be stored per word so memory is conserved. A new CFunction has been added to Peters code, dgraph. 'call refresh routine with the two array address for the new and old values
I9341.dgraph(NewValuesAddress,k, screen(),gparams()) This is passed the pointer to the array containing the data to be graphed and the pointer to an array which contains the current screen pixels.The colours for the graphs are also passed.k is starting point within the array. The cFunction moves everything left 1 pixel and adds the new data, but will only rewrite a pixel if it changes. In basic this took over 1 second so could not keep up. The cFunction is less that 100ms when graphing 4 values which are all changing. This shows a battery being discharged and then recharged over a number of hours. I have housed it in a Jaycar jiffy box but needs a few things adjusted. I built the first prototype using a MUP ,some veroboard and many soldered wires. The next two are based on Micks BP170.Uses the same pins and drives the display on PWM via pin(26). To get the screen to fit in the box I could not piggy back the BP170, so made a little connector to straddle the posts in the case. To get the 5V supply from 12 volts I have used one of these DC-DC converters. DC-DC LM2596 Step Down Module Adjustable Converter Power Supply Output 1.3-35V Got them from here. It does not get hot like an LM7805 and is quite efficient. The system draws 52mA @ 12.5V when on and 14mA @ 12.5V when the screen it off. The thing will sleep if the OFF button is pressed or after 15minutes if voltage is below 12.6V. It will wake if voltage is >13.0V In sleep mode logging still takes place, but screen is off and CPU is a 10MHz to save power. The software I will load here will display 4 scrolling sine waves and should work straight on a BP170 without any hardware other than the screen. Swap the active declaration at line 39&40 and comment out lines 191-197 and it becomes the dual battery monitor software reading pins 23 and 24. The dual Battery Monitor graphs only two values, but uses the other two graph values to make the line a bit wider and smooth the graph. So each graph is the value and the value +1 or -1 to make it two pixel deep and smooth it. 2015-05-17_135936_VoltageMonitorILI9341v2.zip Here is the schematic that shows the voltage divider and protection diodes. 2015-05-17_140514_Schematict.pdf Here is my jig to try an improve the screen cutouts. A couple of draw runners to try and help with a straight line. This one is a bit better. I also need to elongate the mounting holes in the screen a bit. Its working in the car without any issues so far. (Diesel) This is what the sine wave example looks like. I hope you find this useful. It could be use it to graph anything, just need to adjust the vertical scale to suite. I hope someone comes up with a great little enclosure for the BP170 and screen as I am not really happy with my cutting out. Regards Gerry Latest F4 Latest H7 |
||||
disco4now Guru Joined: 18/12/2014 Location: AustraliaPosts: 844 |
I forgot to add, thanks to everyone on here for the ideas and utilities that made this possible. The MMII is a really powerful tool when coupled with all the talent and ideas available on TBS. Thanks Gerry Latest F4 Latest H7 |
||||
twofingers Guru Joined: 02/06/2014 Location: GermanyPosts: 1139 |
Hi Gerry, thanks a lot. Looks great! Very useful! Regards Michael Edit: It seems you have to delete the comments (or some of them) to get it running. But it looks very impressive and could be the base for many more projects. |
||||
disco4now Guru Joined: 18/12/2014 Location: AustraliaPosts: 844 |
OK,I see that it does not run as its too big if the 'Auto crunch on load' under Advanced menu in MMEdit is not ticked. So when loading check 'Auto crunch on load' - Good one Jim. You can also use 'delete blank lines' to save a bit, but if you have errors then the reported line number don't line up, so I don't turn that on. When the thing is in Sleep Mode, touching the screen in the middle graphing area will wake it up. Also tapping in this area will rotate the screen through 3 preset brightness levels once it is awake. Regards Gerry Latest F4 Latest H7 |
||||
panky Guru Joined: 02/10/2012 Location: AustraliaPosts: 1099 |
Hi Gerry, Very interesting and I am particularly interested in the micromite use with the little screen. Will study in more detail as soon as I can. Some time ago, I built up a colour maximite system driving a 7 inch vga display for my caravan to monitor battery and solar voltages and also to monitor current into and out of the battery so I could get a sense of how much charge was being used and input. I also do mostly free camping so need to keep track of power usage. A full description of my system is in the main software library if you are interested. The system has been running in my caravan for nearly 2 years now, 24/7 with no stops, restarts, etc. which shows just how stable the mite series and MMBasic is, to Geoff's great credit. Doug. ... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it! |
||||
bigmik Guru Joined: 20/06/2011 Location: AustraliaPosts: 2870 |
Hi Gerry, Great Writeup.. Maybe Silicon Chip Mag would be interested in publishing it.. I soldered the BP170 directly to the screen so it cuts down the height.. Of course BP170 has its own uMite chip so you could probably do away with the MuP if there is enough IO left for you.. As to the cutouts... Yes a bit rough but if you can source some of the U-Shape cable protection tube similar to this one.... You can make a nice facia around your cutout and no-one will see it being rough.. You can even bevel 45 degrees and make it fit perfectly. Regards, Mick Mick's uMite Stuff can be found >>> HERE (Kindly hosted by Dontronics) <<< |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8601 |
disco4now Great project Please can you post the source of the new Cfunction. Thanks Peter |
||||
disco4now Guru Joined: 18/12/2014 Location: AustraliaPosts: 844 |
@panky I had a look at your project. Some good info there on using the current sensors. @bigmick Mick, Thanks for the idea on the U shaped stuff.There is also some T shaped stuff used when putting cupboards into caravans that has a long edge and a little cap that may work, else some silicon. I used a MUP for the first one, but am using the BP170 for the others. @matherp I have attached the code as a zip. It is your stuff with these two functions added. The values stored in each byte of the array are the y co-ordinate of the pixel. When they are stored if the value co-incides with a horizontal scale line they are divided by 30. The function multiplies any value below 20 by 30 so if a 2 is stored it is really y=60, but as is passed as a 2 the function knows to write back the horizontal scale colour and not the normal background, so the horizontal scale lines are preserved. The oobcolour (out of bounds) is supposed to be used if the value is out of range. ie <30 or >210. These would be written at 29 and 211 respectively, but in the oobcolour. There is a problem with this, I have not sorted as yet, the original colour is used when I expect the oobcolour.(except sometimes?) You could make this more generic by passing some more parameters so the graph could be positioned elsewhere on the screen, different horizontal scale positions etc. Where your functions are included in MMbasic in the MX170 is it possible to call the localdrawPixel() part of it from a CFunction or would you need to add the CFunctions for it all? long long localdrawPixelPre( long long colour,long long oobcolour, long long xx, long long yy, long long params[]){ long dp,bn=yy,i=xx; if (bn>0){ if ( bn<20 ){ dp=localdrawPixel(colour,i,(bn<<5)-(bn<<1),params); //dp=localdrawPixelPre(graph3,oobcolour,i,(bn3<<5)-(bn3<<1),params); }else{ if ( bn==29 || bn==211 ){ dp=localdrawPixel(oobcolour,i,bn,params); }else { dp=localdrawPixel(colour,i,bn,params); //dp=localdrawPixelPre(graph3,oobcolour,i,bn3,params); } } } // dp=localdrawPixel(colour,xx,yy,params); return dp; } void drawgraph(int new[],long long offset,long long screen[],long long gparams[] ,long long params[]) { unsigned long maxgraph=gparams[0]; long long backcolour=gparams[1]; long long gridcolour=gparams[2]; long long oobcolour=gparams[3]; long long graph0=gparams[4]; long long graph1=gparams[5]; long long graph2=gparams[6]; long long graph3=gparams[7]; long dp,bn0,bn1,bn2,bn3,bo0,bo1,bo2,bo3; unsigned int i,j=offset,*newaddr; unsigned int n,o; //newaddr=new; //*newaddr=new; for(i=0;i<=239;i++){ n=new[(j)]; o=screen[ i ]; bn0=n&255; bn1=(n>>8)&255; bn2=(n>>16)&255; bn3=(n>>24)&255; bo0=o&255; bo1=(o>>8)&255; bo2=(o>>16)&255; bo3=(o>>24)&255; // only rewrite old bo0 value if not used again if (bo0!=bn0 && bo0!=bn1 && bo0!=bn2 && bo0!=bn3){ if (bo0>0 && bo0<20){ dp=localdrawPixel(gridcolour,i,(bo0<<5)-(bo0<<1),params); //white }else{ dp=localdrawPixel(backcolour,i,bo0,params); //black } } // only rewrite old bo1 value if not used again if (bo1!=bn0 && bo1!=bn1 && bo1!=bn2 && bo1!=bn3){ if (bo1>0 && bo1<20){ dp=localdrawPixel(gridcolour,i,(bo1<<5)-(bo1<<1),params); //white }else{ dp=localdrawPixel(backcolour,i,bo1,params); //black } } // only rewrite old bo2 value if not used again if (bo2!=bn0 && bo2!=bn1 && bo2!=bn2 && bo2!=bn3){ if (bo2>0 && bo2<20){ dp=localdrawPixel(gridcolour,i,(bo2<<5)-(bo2<<1),params); //white }else{ dp=localdrawPixel(backcolour,i,bo2,params); //black } } // only rewrite old bo3 value if not used again if (bo3!=bn0 && bo3!=bn1 && bo3!=bn2 && bo3!=bn3){ if (bo3>0 && bo3<20){ dp=localdrawPixel(gridcolour,i,(bo3<<5)-(bo3<<1),params); //white }else{ dp=localdrawPixel(backcolour,i,bo3,params); //black } } // write new bo0 value if required if (bo0!=bn0 || bn0==bo1 || bn0==bo2 || bn0==bo3) { dp=localdrawPixelPre(graph0,oobcolour,i,bn0,params); } // write new bo1 value if required if (bo1!=bn1 || bn1==bo0 || bn1==bo2 || bn1==bo3) { dp=localdrawPixelPre(graph1,oobcolour,i,bn1,params); } // write new bo2 value if required if (bo2!=bn2 || bn2==bo0 || bn2==bo1 || bn2==bo3) { dp=localdrawPixelPre(graph2,oobcolour,i,bn2,params); } // write new bo3 value if required if (bo3!=bn3 || bn3==bo0 || bn3==bo1 || bn3==bo2) { dp=localdrawPixelPre(graph3,oobcolour,i,bn3,params); } screen[ i ]=(bn3<<24)+(bn2<<16)+(bn1<<8)+bn0; j+=1; if(j>1439) { j=j-1440 ; } } } (Looks like screen[ i ] is changed in the code to just screen so I have added some spaces) and this addition to the main call // G.A. if (*fn==0xa){ drawgraph((long long)*Arg1,(long long)*Arg2,Arg3,Arg4,Arg5); return(*fn); } 2015-05-18_104931_ILI9341.zip Thanks for all code to drive the various screen. Regards Gerry Latest F4 Latest H7 |
||||
G8JCF Guru Joined: 15/05/2014 Location: United KingdomPosts: 676 |
In the chat window, when the program breaks because of an error click the little RED right pointing arrow, and the main MMEdit window will show the correct line of the error even though you have set Delete Blank Lines on. BTW, it's a brilliant project, and great to see another CFunctioneer (is that what we should call people who write CFunctions ?) at work !! Peter The only Konstant is Change |
||||
bigmik Guru Joined: 20/06/2011 Location: AustraliaPosts: 2870 |
Gday Peter, Surely you mean C-Farers like the explorers of old.. breaking new ground (water) and all that... Mick's uMite Stuff can be found >>> HERE (Kindly hosted by Dontronics) <<< |
||||
G8JCF Guru Joined: 15/05/2014 Location: United KingdomPosts: 676 |
Hi Mick I like that C-Farers ! Can I use that term in the tutorials ? Peter The only Konstant is Change |
||||
OA47 Guru Joined: 11/04/2012 Location: AustraliaPosts: 911 |
Gerry, I found some "T" section plastic strips at the local hobby shop. These strips come in white but can be easily sprayed black. I have made a frame around the display and it hides any rough edges made when cutting out. GM Similar product:TFS-4EA Styrene Tee |
||||
bigmik Guru Joined: 20/06/2011 Location: AustraliaPosts: 2870 |
Peter, Cetainly !! With the usual royalty fee of course. MG Mick's uMite Stuff can be found >>> HERE (Kindly hosted by Dontronics) <<< |
||||
disco4now Guru Joined: 18/12/2014 Location: AustraliaPosts: 844 |
Thanks Graeme, I have ordered some, got some 2.4mm wide as well in case my cutting does not improve down to 1.2mm Latest F4 Latest H7 |
||||
OA47 Guru Joined: 11/04/2012 Location: AustraliaPosts: 911 |
disco4now, I think the ones I purchased are 4mm and 6mm which cover the LCD border nicely. GM |
||||
Print this page |