implementation of parts of the unilynx protocol, for communicating with danfos photovoltaic inverters. Still BETA ! needs byte stuff/unstuff fixed, and some CRC are left out for niw...

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
morten_opprud
Date:
Tue Aug 28 19:53:42 2012 +0000
Parent:
0:66a099b01e08
Child:
2:de090b60d543
Commit message:
can retrieve values, still needs CRC and byte stuffing

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
unilynx.cpp Show annotated file Show diff for this revision Revisions of this file
unilynx.h Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Mon Aug 27 18:30:37 2012 +0000
+++ b/main.cpp	Tue Aug 28 19:53:42 2012 +0000
@@ -1,22 +1,39 @@
 #include "mbed.h"
 #include "unilynx.h"
 
-
+Serial pc(USBTX, USBRX);
 DigitalOut myled(LED1);
 
-int main() {
-rs485init();
-    while(1) {
-        //test();
-        readParameter(RAW_MEAS_VALUES, ENERGY_PRODUCTION);
+int current_production_avg;
+int current_production;
+int today_production;
+int total_production;
+
+int main()
+{
+    /* setup terminal */
+    pc.baud(115200);
+    /* setup RS485 */
+    rs485init();
 
-        #if 1
-//        ping();
-        myled = 1;
-        wait(1);
-        myled = 0;
-//        getNodeInfo();
-        wait(1);
-        #endif
+    while(1) 
+    {
+        /* read parameters of interest */
+        total_production        = readParameter(RAW_MEAS_VALUES, ENERGY_PRODUCTION, ID_RAW_MEAS_VALUES);
+        pc.printf("Production Total: %d [Wh]\n",total_production);
+        today_production        = readParameter(RAW_MEAS_VALUES, ENERGY_PRODUCTION_TODAY, ID_RAW_MEAS_VALUES);
+        pc.printf("Production Today: %d [Wh]\n",today_production);
+        //current_production_avg  = readParameter(RAW_SMOOTH_VALUES, INSTANT_ENERGY, ID_RAW_SMOOTH_VALUES);
+        current_production      = readParameter(RAW_MEAS_VALUES, INSTANT_ENERGY, ID_RAW_MEAS_VALUES);
+        //pc.printf("Production Now: %04d [W] Avg.: %04d [W] \n",current_production,current_production_avg);
+        pc.printf("Production Now: %04d [W] \n",current_production);
+        
+        /* print to console*/
+/*        pc.printf("Production Total: %d [Wh]\n",total_production);
+        pc.printf("Production Today: %d [Wh]\n",today_production);
+        pc.printf("Production Now: %04d [W] \n",current_production);
+*/
+        wait(3);
+
     }
 }
--- a/unilynx.cpp	Mon Aug 27 18:30:37 2012 +0000
+++ b/unilynx.cpp	Tue Aug 28 19:53:42 2012 +0000
@@ -8,18 +8,16 @@
 * @date     Aug 24, 2012
 *
 */
-
-//#include <stdio.h>
-//#include <stdlib.h>
 #include "mbed.h"
 #include "unilynx.h"
 #include "crc.h"
 
-#define DEBUG
 
 Serial rs485(p26, p25);
+//#define DEBUG
+#ifdef DEBUG
 Serial pc(USBTX, USBRX);
-
+#endif
 
 // Telegram format
 //----------------------------------------------------------------------------------------------------
@@ -32,8 +30,8 @@
 #define MY_ADDR0        0x28
 #define MY_ADDR1        0xD7
 
-#define FRAME_START        0x7E
-#define FRAME_STOP        0x7E
+#define FRAME_START      0x7E
+#define FRAME_STOP       0x7E
 #define FRAME_ADDRESS    0xFF
 #define FRAME_CONTROL    0x03
 
@@ -77,8 +75,9 @@
 void rs485init(void)
 {
     rs485.baud(19200);
+#ifdef DEBUG
     pc.baud(115200);
-
+#endif
     LPC_PINCON->PINSEL4 &= 0x0ffff;
     LPC_PINCON->PINSEL4 |= 0x0AAAA;
 
@@ -91,24 +90,16 @@
     LPC_UART1->RS485CTRL   |= (1<<5);       //DTR=1 when transmitting
 }
 
-void rs485write(char* str, int len)
+static void rs485write(char* str, int len)
 {
     int i;
     i=0;
-    while(i < len)
-    {
+    while(i < len) {
         rs485.putc(*(str +i));
         i++;
+        //TODO byte stuff
+
     }
-#ifdef DEBUG2
-    i=0;   
-    pc.printf("TX:");
-    while(i < len)
-    {
-        pc.putc(*(str +i));
-        i++;
-    }
-#endif
 }
 
 static void rs485read(char* str, int len)
@@ -118,20 +109,15 @@
     while(i < len) {
         (*(str +i)) = rs485.getc();
         i++;
+        //TODO byte unstuff
         //TODO add timeout
     }
-#ifdef DEBUG
-    i=0;
-    pc.printf("RX:");
-    while(i < len)
-    {
-        pc.putc(*(str +i));
-        i++;
-    }
-#endif
-
 }
 
+/*
+ Get node info, serial no etc...
+ currently kept in local variables insode function.
+*/
 void getNodeInfo(void)
 {
     /* data of interest TODO MAKE GLOBAL AVAILIBLE */
@@ -152,69 +138,71 @@
     rs485write(getNodeReqStrWoCrc,41);
     /* retrieve response */
     rs485read(rx,41);
+    //TODO CRC
     /* extract data*/
     network = rx[33];
     subnet  = rx[34];
     address = rx[35];
-    
+
     //pc.printf("Network: %X Subnet: %X Address: %X",network,subnet, address);
 }
 
-void readParameter(int param_idx, int param_sub_idx)
+/*
+   read a parameter from the inverter
+   @param param_idx "index" used to retrieve parameter values
+   @param param_sub_idx "sub-index" used to retrieve parameter values
+*/
+int readParameter(int param_idx, int param_sub_idx, int dest)
 {
-	short fcs;
-	char rx[24];
-	char flags;
-
-	/* fill in address */
-	getNodeParamStrWoCrc[5] = MY_ADDR0;
-	getNodeParamStrWoCrc[6] = MY_ADDR1;
-
-	getNodeParamStrWoCrc[10] = 0x04;//0D;//dest;
-	getNodeParamStrWoCrc[11] = 0xD0;//((source<<4) | page);
-	getNodeParamStrWoCrc[12] = (param_idx);
-	getNodeParamStrWoCrc[13] = (param_sub_idx);
-	getNodeParamStrWoCrc[14] = 0x80;//	we want reply (DO_REPLY | IM_REQUEST | TYPE_U16);
-	getNodeParamStrWoCrc[15] = 0;
-	getNodeParamStrWoCrc[16] = 0;
-	getNodeParamStrWoCrc[17] = 0;
-	getNodeParamStrWoCrc[18] = 0;
-
-	/* calculate VRC and fill in string */
-	fcs = pppfcs16( PPPINITFCS16, &getNodeParamStrWoCrc[1], 18 );
-	fcs ^= 0xFFFF;
-	getNodeParamStrWoCrc[19] = (unsigned char)(fcs & 0xFF);
-	getNodeParamStrWoCrc[20] = (unsigned char)((fcs>>8) & 0xFF);
-
-	/* send request */
-	rs485write(getNodeParamStrWoCrc,22);
-	/* retrieve response */
-	rs485read(rx,22);
-	/* extract data*/
-	flags = rx[14];
-	
-	switch (flags & 0x0F)
-	{
-		case 0x07:	//U32
-			pc.printf("VAl: %d %d %d %d",rx[15],rx[16],rx[17],rx[18]);
-		break;
-		default:
-			pc.printf("Flags: %X" ,rx[14]);
-		break;
-	}
-}
+    short fcs;
+    short u16val;
+    int u32val;
+    char rx[24];
+    char flags;
 
 
-void test(void)
-{
-    //pc.baud(19200);
+    /* fill in address */
+    getNodeParamStrWoCrc[5] = MY_ADDR0;
+    getNodeParamStrWoCrc[6] = MY_ADDR1;
+
+    getNodeParamStrWoCrc[10] = dest;//0x04;//0D;//
+    getNodeParamStrWoCrc[11] = 0xD0;//((source<<4) | page);
+    getNodeParamStrWoCrc[12] = (param_idx);
+    getNodeParamStrWoCrc[13] = (param_sub_idx);
+    getNodeParamStrWoCrc[14] = 0x80;//	we want reply (DO_REPLY | IM_REQUEST | TYPE_U16);
+    getNodeParamStrWoCrc[15] = 0;
+    getNodeParamStrWoCrc[16] = 0;
+    getNodeParamStrWoCrc[17] = 0;
+    getNodeParamStrWoCrc[18] = 0;
+
+    /* calculate VRC and fill in string */
+    fcs = pppfcs16( PPPINITFCS16, &getNodeParamStrWoCrc[1], 18 );
+    fcs ^= 0xFFFF;
+    getNodeParamStrWoCrc[19] = (unsigned char)(fcs & 0xFF);
+    getNodeParamStrWoCrc[20] = (unsigned char)((fcs>>8) & 0xFF);
 
-    while(1) {
-        if(pc.readable())
-            rs485.putc(pc.getc());
+    /* send request */
+    rs485write(getNodeParamStrWoCrc,22);
+    /* retrieve response */
+    rs485read(rx,22);
+    //TODO CRC
+    /* extract data*/
+    flags = rx[14];
 
-        if(rs485.readable())
-            pc.putc(rs485.getc());
+    switch (flags & 0x0F) {
+        case 0x06:	//decode U16
+            u16val = ((rx[16]<<8)+rx[15]);
+            return (int)u16val;
+            break;
+        case 0x07:	//decode U32
+            u32val = ((rx[18]<<24)+(rx[17]<<16)+(rx[16]<<8)+rx[15]);
+            return u32val;
+            break;
+        default:
+#ifdef DEBUG
+            com.printf("You got work to do !! Flags are: %X" ,rx[14]);
+#endif
+            break;
     }
 }
 
@@ -226,28 +214,16 @@
 
     for(int i=0; i < 12; i++) {
         rs485.putc(pingAllStr[i]);
-//        pc.putc(pingAllStr[i]);
     }
     while(1) {
         if(rs485.readable()) {
             rx[rxcnt++] = rs485.getc();
-//            pc.putc(rx[rxcnt]);
         }
         /* reached stop 0x7E ? todo, timeout & CRC*/
         if( rxcnt > 10)
             if(rx[rxcnt] == 0x7E)
                 break;
-
         if( rxcnt == 11)
             break;
     }
-
-    for(int i=0; i < 12; i++) {
-        pc.putc(pingAllStr[i]);
-    }
-    for(int i=0; i < 12; i++) {
-        pc.putc(rx[i]);
-    }
-
-    pc.printf("Done");
 }
\ No newline at end of file
--- a/unilynx.h	Mon Aug 27 18:30:37 2012 +0000
+++ b/unilynx.h	Tue Aug 28 19:53:42 2012 +0000
@@ -4,15 +4,17 @@
 
 /* RAW measured values */
 #define RAW_MEAS_VALUES                0X01 
-#define INSTANT_ENERGY                0X01 //RETURNS U32
-#define ENERGY_PRODUCTION            0X02 //RETURNS U32
+#define ID_RAW_MEAS_VALUES             0X04 
+#define INSTANT_ENERGY                 0X01 //RETURNS U32
+#define ENERGY_PRODUCTION              0X02 //RETURNS U32
 #define ENERGY_PRODUCTION_TODAY        0X04 //RETURNS U32
 
 /* Smoothed measured values */
-#define RAW_SMOOTH_VALUES            0X02 
-#define GRID_VOLTAGE                0X14 //RETURNS U32
-#define GRID_CURRENT_MA                0X15 //RETURNS U32
-#define GRID_FREQ_cHZ                0X16 //RETURNS U32
+#define RAW_SMOOTH_VALUES               0X02 
+#define ID_RAW_SMOOTH_VALUES            13//0X0D 
+#define GRID_VOLTAGE                    0X14 //RETURNS U32
+#define GRID_CURRENT_MA                 0X15 //RETURNS U32
+#define GRID_FREQ_cHZ                   0X16 //RETURNS U32
 
 
 /* Status values */
@@ -22,7 +24,8 @@
 
 void rs485init(void);
 void getNodeInfo(void);
-void readParameter(int param_idx, int param_sub_idx);
+//int readParameter(int param_idx, int param_sub_idx);
+int readParameter(int param_idx, int param_sub_idx, int dest);
 void test(void);
 void ping(void);