浏览代码

Added Graph.

Vladimir N. Shilov 4 天之前
父节点
当前提交
db7be7e575
共有 4 个文件被更改,包括 157 次插入16 次删除
  1. 1 0
      Makefile
  2. 15 0
      inc/graph.h
  3. 114 0
      src/graph.c
  4. 27 16
      src/main.c

+ 1 - 0
Makefile

@@ -128,6 +128,7 @@ LDSCRIPT= $(STARTUPLD)/STM32F407xG.ld
 CSRC =	$(ALLCSRC) \
 	$(GFXSRC) \
 	$(FATFSSRC) \
+	src/graph.c \
 	src/buttons.c \
 	src/INA3221.c \
 	src/main.c

+ 15 - 0
inc/graph.h

@@ -0,0 +1,15 @@
+#pragma once
+#ifndef _GRAPH_H_
+#define _GRAPH_H_
+
+/* function prototypes */
+#ifdef __cplusplus
+extern "C" {
+#endif
+  void graph_Init(void);
+  void graph_Draw(uint32_t u_value, uint32_t i_value);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GRAPH_H_ */

+ 114 - 0
src/graph.c

@@ -0,0 +1,114 @@
+/*
+ * https://wiki.ugfx.io/index.php/Graph
+ *
+ * Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
+ * Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *    * Neither the name of the <organization> nor the
+ *      names of its contributors may be used to endorse or promote products
+ *      derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gfx.h"
+#include "math.h"
+
+// window
+#define WINDOW_X    1
+#define WINDOW_Y    123
+#define WINDOW_W    318
+#define WINDOW_H    118
+
+#define MIN_U       0
+#define MIN_I       0
+#define MAX_U       15000
+#define MAX_I       5000
+
+// from Arduino
+static long map(long x, long in_min, long in_max, long out_min, long out_max) {
+      return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
+}
+
+// A graph styling
+static GGraphStyle GraphStyle1 = {
+    { GGRAPH_POINT_DOT, 0, GFX_BLUE },          // Point
+    { GGRAPH_LINE_NONE, 2, GFX_GRAY },          // Line
+    { GGRAPH_LINE_SOLID, 0, GFX_WHITE },        // X axis
+    { GGRAPH_LINE_SOLID, 0, GFX_WHITE },        // Y axis
+    { GGRAPH_LINE_DASH, 5, GFX_GRAY, 50 },      // X grid
+    { GGRAPH_LINE_DOT, 7, GFX_YELLOW, 50 },     // Y grid
+    GWIN_GRAPH_STYLE_POSITIVE_AXIS_ARROWS		// Flags
+};
+
+static GHandle gh;
+static gCoord pos_X;
+
+void graph_Init(void) {
+    // Create the graph window
+    {
+        GWindowInit wi;
+ 
+        wi.show = gTrue;
+        wi.x = WINDOW_X;
+        wi.y = WINDOW_Y;
+        wi.width = WINDOW_W;
+        wi.height = WINDOW_H;
+        gh = gwinGraphCreate(0, &wi);
+    }
+
+    // clear area
+    gdispFillArea(WINDOW_X, WINDOW_Y, WINDOW_W, WINDOW_H, GFX_BLACK);
+
+    // Set the graph origin and style
+    gwinGraphSetOrigin(gh, gwinGetWidth(gh)/2, gwinGetHeight(gh)/2);
+    gwinGraphSetStyle(gh, &GraphStyle1);
+    gwinGraphDrawAxis(gh);
+
+    pos_X = WINDOW_X;
+}
+
+void graph_Draw(uint32_t u_value, uint32_t i_value) {
+    gCoord pos_Y;
+
+    // Modify the style
+    gwinGraphStartSet(gh);
+    GraphStyle1.point.color = GFX_GREEN;
+    gwinGraphSetStyle(gh, &GraphStyle1);
+
+    // Draw voltage point
+    pos_Y = map(u_value, MIN_U, MAX_U, WINDOW_Y, WINDOW_H);
+    gwinGraphDrawPoint(gh, pos_X, pos_Y);
+
+    // Modify the style
+    gwinGraphStartSet(gh);
+    GraphStyle1.point.color = GFX_RED;
+    gwinGraphSetStyle(gh, &GraphStyle1);
+
+    // Draw current point
+    pos_Y = map(i_value, MIN_I, MAX_I, WINDOW_Y, WINDOW_H);
+    gwinGraphDrawPoint(gh, pos_X, pos_Y);
+
+    pos_X ++;
+    if (pos_X >= WINDOW_W) {
+        pos_X = WINDOW_X;
+    }
+}

+ 27 - 16
src/main.c

@@ -24,6 +24,7 @@
 #include "gfx.h"
 #include "buttons.h"
 #include "INA3221.h"
+#include "graph.h"
 
 #define INA_SCAN_PERIOS_US    62500
 #define INA_AVG_FACTOR        16
@@ -237,7 +238,7 @@ static THD_FUNCTION(ChrgThread, arg) {
 /*
  * Green LED blinker thread, times are in milliseconds.
  */
-static THD_WORKING_AREA(waLedThread, 256);
+static THD_WORKING_AREA(waLedThread, 128);
 static THD_FUNCTION(LedThread, arg) {
   (void)arg;
   chRegSetThreadName("blinker");
@@ -296,6 +297,7 @@ int main(void) {
    */
   gfxInit();
   prepare_Screen();
+  graph_Init();
 
   /*
    * Activates the I2C driver 1.
@@ -399,6 +401,7 @@ int main(void) {
     events = chEvtWaitAny(ALL_EVENTS);
 
     if (events & INA_ALL_VALUSE) {
+      /*
       tmp1 = Voltage / 1000;
       tmp2 = Voltage % 1000;
       chsnprintf(buf, 11, "U:%2d.%03uV", tmp1, tmp2);
@@ -417,14 +420,18 @@ int main(void) {
       tmp0 = (Capacity_I + 1800) / 3600;
       tmp1 = tmp0 / 1000;
       tmp2 = tmp0 % 1000;
-      chsnprintf(buf, 13, "CI:%2d.%03uAh", tmp1, tmp2);
+      tmp2 /= 100;
+      chsnprintf(buf, 13, "CI:%2d.%1uAH", tmp1, tmp2);
       gdispFillStringBox(160, 153, 158, 29, buf, font2, Red, Gray, gJustifyLeft);
 
       tmp0 = (Capacity_P + 1800) / 3600;
       tmp1 = tmp0 / 1000;
       tmp2 = tmp0 % 1000;
-      chsnprintf(buf, 13, "CP:%2d.%03uWh", tmp1, tmp2);
+      tmp2 /= 100;
+      chsnprintf(buf, 13, "CP:%2d.%1uWH", tmp1, tmp2);
       gdispFillStringBox(160, 183, 158, 29, buf, font2, Red, Gray, gJustifyLeft);
+      */
+      graph_Draw(Voltage, Current);
 
       /* Check charge/decharge conditions */
       switch (charger_State) {
@@ -465,10 +472,12 @@ int main(void) {
     }
 
     if (events & INA_BUS_VALUES) {
+      /*
       tmp1 = Voltage / 1000;
       tmp2 = Voltage % 1000;
       chsnprintf(buf, 11, "U:%2d.%03uV", tmp1, tmp2);
       gdispFillStringBox(1, 123, 158, 29, buf, font2, Red, Gray, gJustifyLeft);
+      */
       /* here should control processes time ? */
     }
 
@@ -478,7 +487,7 @@ int main(void) {
         if (Profile[charger_Profile].VoltageDechMin_mv > Voltage) {
           gwinPrintf(GW1, "No Battery detected / Low voltage...\n");
           charger_State = Stop;
-          gdispFillStringBox(1, 213, 318, 29, "Stop", font2, Red, Silver, gJustifyCenter);
+          //gdispFillStringBox(1, 213, 318, 29, "Stop", font2, Red, Silver, gJustifyCenter);
           break;
         }
         oldState = Charge1;
@@ -490,7 +499,7 @@ int main(void) {
         gwinPrintf(GW1, "Begin process: Charge_1\n");
 
         palClearLine(LINE_RELAY1);  // power relay on
-        gdispFillStringBox(1, 213, 318, 29, "Charge 1", font2, Red, Silver, gJustifyCenter);
+        //gdispFillStringBox(1, 213, 318, 29, "Charge 1", font2, Red, Silver, gJustifyCenter);
         break;
 
       case Pause1:
@@ -514,7 +523,7 @@ int main(void) {
 
         gwinPrintf(GW1, "Pause after Charge_1\n");
 
-        gdispFillStringBox(1, 213, 318, 29, "Pause 1", font2, Red, Silver, gJustifyCenter);
+        //gdispFillStringBox(1, 213, 318, 29, "Pause 1", font2, Red, Silver, gJustifyCenter);
         chVTSet(&mode_vt, TIME_S2I(CHRGR_PAUSE1_S), mode_vt_cb, (void *)Decharge);
         break;
 
@@ -528,7 +537,7 @@ int main(void) {
         gwinPrintf(GW1, "Begin process: Decharge\n");
         
         palClearLine(LINE_RELAY2);  // load relay on
-        gdispFillStringBox(1, 213, 318, 29, "Decharge", font2, Red, Silver, gJustifyCenter);
+        //gdispFillStringBox(1, 213, 318, 29, "Decharge", font2, Red, Silver, gJustifyCenter);
         break;
 
       case Pause2:
@@ -555,7 +564,7 @@ int main(void) {
         gwinPrintf(GW1, "/%2u.%02u\n", tmp1, tmp2);
 
         gwinPrintf(GW1, "Pause after Decharge\n");
-        gdispFillStringBox(1, 213, 318, 29, "Pause 2", font2, Red, Silver, gJustifyCenter);
+        //gdispFillStringBox(1, 213, 318, 29, "Pause 2", font2, Red, Silver, gJustifyCenter);
 
         chVTSet(&mode_vt, TIME_S2I(CHRGR_PAUSE2_S), mode_vt_cb, (void *)Charge2);
         break;
@@ -570,7 +579,7 @@ int main(void) {
         gwinPrintf(GW1, "Begin process: Charge_2\n");
 
         palClearLine(LINE_RELAY1);  // power relay on
-        gdispFillStringBox(1, 213, 318, 29, "Charge 2", font2, Red, Silver, gJustifyCenter);
+        //gdispFillStringBox(1, 213, 318, 29, "Charge 2", font2, Red, Silver, gJustifyCenter);
         break;
       
       case Error:
@@ -578,7 +587,8 @@ int main(void) {
         // power and load relay off
         palSetLine(LINE_RELAY1);
         palSetLine(LINE_RELAY2);
-        gdispFillStringBox(1, 213, 318, 29, "Error", font2, Silver, Red, gJustifyCenter);
+        gwinPrintf(GW1, "ERROR\n");
+        //gdispFillStringBox(1, 213, 318, 29, "Error", font2, Silver, Red, gJustifyCenter);
         break;
 
       default:
@@ -603,14 +613,15 @@ int main(void) {
         // power and load relay off
         palSetLine(LINE_RELAY1);
         palSetLine(LINE_RELAY2);
-        gdispFillStringBox(1, 213, 318, 29, "Stop", font2, Red, Silver, gJustifyCenter);
+        gwinPrintf(GW1, "STOP\n");
+        //gdispFillStringBox(1, 213, 318, 29, "Stop", font2, Red, Silver, gJustifyCenter);
         break;
       }
     }
 
     if (events & TIME_CHANGE) {
-      chsnprintf(buf, 12, "T:%02u:%02u:%02u", Timer.hh, Timer.mm, Timer.ss);
-      gdispFillStringBox(160, 123, 158, 29, buf, font2, Red, Gray, gJustifyLeft);
+      //chsnprintf(buf, 12, "T:%02u:%02u:%02u", Timer.hh, Timer.mm, Timer.ss);
+      //gdispFillStringBox(160, 123, 158, 29, buf, font2, Red, Gray, gJustifyLeft);
     }
 
     if (events & INSERTED_EVENT) {
@@ -639,15 +650,15 @@ static void prepare_Screen(void) {
   gdispDrawBox(0, 0, width-1, height-1, Green); // all screen
   gdispDrawLine(0, 122, width-1, 122, Green); // h line
   gdispDrawLine(79, 0, 79, 122, Green); // v line, text | console
-  gdispFillArea(1, 1, 78, 121, Blue); // text area
+  gdispFillArea(1, 1, 78, 121, Blue); // menu area
 
-  /* print text to top-left area */
+  /* print menu to top-left area */
   show_MenuItem(MenuItem_1);
   show_MenuItem(MenuItem_2);
   show_MenuItem(MenuItem_3);
   show_MenuItem(MenuItem_4);
 
-  /* clear bootom area */
+  /* clear bootom area. 1,123-319,239 - measure area. 1,213-310,239 - status line */
   gdispFillStringBox(1, 123, 318, 115, " ", font2, Red, Gray, gJustifyLeft);
   gdispFillStringBox(1, 213, 318, 29, "Stop", font2, Red, Silver, gJustifyCenter);