using System; using System.Text; using System.IO.Ports; using System.Threading; using Microsoft.SPOT; using Microsoft.SPOT.Hardware; namespace CPF { class ADuC { private static byte[] ADuCPortReadBytes = new byte[10240]; private static SerialPort ADuCPort = new SerialPort("COM2", 9600, Parity.None); private static int ADuCPortBytesToRead = 0; private static byte[] ADuCPortInByteArray = new byte[256]; private static int ADuCPortInByteArrayIndex = 0; private static object ADuCLock = new object(); private static byte STX = 36; //Start of text = "$" private static byte ETX = 10; //End of text = LF private static byte negativeSign = 45; //negative sign private static byte decimalPt = 46; //decimal point private static byte CR = 13; private static byte token = 32; //token (separator) = space private static int messageNum = 0; private static StringBuilder sb = new StringBuilder(256); private static byte[] parserField = new byte[16]; private static int parserI = 0; private static int parserJ = 0; private static int decimalPtIndex = -1; private static double[] aducVolts = new double[12]; private static int fieldNum = 0; private static double accum = 0; private static int lastByte = 0; private static int fieldSign = 1; public static void Init() { ADuCPort.Open(); ADuCPort.DiscardInBuffer(); ADuCPort.DiscardOutBuffer(); ADuCPort.DataReceived += new SerialDataReceivedEventHandler(ADuCPortDataReceived); } private static void ADuCPortDataReceived(object sender, SerialDataReceivedEventArgs e) { ADuCPortBytesToRead = ADuCPort.BytesToRead; try { ADuCPort.Read(ADuCPortReadBytes, 0, ADuCPortBytesToRead); //charArray = UTF8Encoding.UTF8.GetChars(ADuCPortReadBytes); } catch { Debug.Print("ADuC Read Exception"); //TODO do something smarter here } for (int i = 0; i < ADuCPortBytesToRead; i++) { ADuCPortInByteArray[ADuCPortInByteArrayIndex] = ADuCPortReadBytes[i]; if (ADuCPortInByteArrayIndex == 0) //Check to make sure first character is = LF { if (ADuCPortInByteArray[0] == STX) //only move on to byte index 1 after we get a LF { ADuCPortInByteArrayIndex = ADuCPortInByteArrayIndex + 1; } } else { if (ADuCPortInByteArray[ADuCPortInByteArrayIndex] == ETX) { ADuCPortInByteArrayIndex = 0; messageNum = messageNum + 1; if ((messageNum % configFile.aducEnqueueDecimator) == 0) { lock (ADuCLock) { Program.MessageQueue.Enqueue(ADuCPortInByteArray); } sb.Clear(); sb.Append(UTF8Encoding.UTF8.GetChars(ADuCPortInByteArray)); Debug.Print(sb.ToString()); } Array.Clear(ADuCPortInByteArray, 0, ADuCPortInByteArray.Length); Array.Clear(ADuCPortReadBytes, 0, ADuCPortReadBytes.Length); } else { ADuCPortInByteArrayIndex = ADuCPortInByteArrayIndex + 1; } } } } public static double[] parseADuC(byte[] inArray) { parserJ = -1; fieldNum = 0; fieldSign = 1; for (parserI = 0; parserI < inArray.Length; parserI++) { //Find the index of the first token if (parserJ < 0) { if (inArray[parserI] == token) { parserJ = parserJ + 1; } } else { //When the second token shows up, turn the bytes into a number if ((inArray[parserI] == token) || (inArray[parserI] == CR)) { accum = 0.0; lastByte = parserJ; //Handle fields that don't have any decimal points if (decimalPtIndex < 0) { decimalPtIndex = lastByte - 1; } //Turn the field into a number for (parserJ = 0; parserJ < lastByte; parserJ++) { accum = accum + ((parserField[parserJ] - 48) * System.Math.Pow(10, (decimalPtIndex - parserJ))); } accum = fieldSign * accum; aducVolts[fieldNum] = accum; //Debug.Print("Voltage " + fieldNum.ToString() + " = " + aducVolts[fieldNum].ToString("F5")); //End the loop at the CR if (inArray[parserI] == CR) { parserI = inArray.Length; } else { fieldSign = 1; parserJ = -1; fieldNum = fieldNum + 1; decimalPtIndex = -1; parserI = parserI - 1; //Need to do this so we don't skip the start of the next field } } else // put the number in the field unless it is a decimal point or a negative sign { parserField[parserJ] = inArray[parserI]; //Look for the decimal point if (inArray[parserI] == decimalPt) { decimalPtIndex = parserJ - 1; } else if (inArray[parserI] == negativeSign) { fieldSign = -1; } else { parserJ = parserJ + 1; } } } } //double battVolts = aducVolts[1] * configFile.aducCH1Scale; //Debug.Print("Parsed volts = " + // aducVolts[0].ToString("f2") + " " + // aducVolts[1].ToString("f4") + " " + // aducVolts[2].ToString("f4") + " " + // aducVolts[3].ToString("f4") + " " + // aducVolts[4].ToString("f4") + " batt voltage = " + // battVolts.ToString("F2")); return (aducVolts); } } }