// method to connect to any open serial ports and attempt handshake. // On success, method exits and logs successful baud rate and port name public Boolean connect() { if (serialPort.IsOpen) { return true; } else { // set properties that we know will be always true serialPort.Parity = Parity.None; serialPort.DataBits = 8; serialPort.StopBits = StopBits.One; serialPort.Handshake = Handshake.None; serialPort.ReceivedBytesThreshold = 3; serialPort.ReadTimeout = 500; string[] AvailableSerialPorts = null; // clear out // Populate the list box with currently available COM ports AvailableSerialPorts = SerialPort.GetPortNames(); foreach (string s in AvailableSerialPorts) // put each available port in as an item { foreach (int i in baudValues) { try { serialPort.PortName = s; serialPort.BaudRate = i; serialPort.Open(); // open serial port on a COM and a baud from the baud values array txPacket = new TxPacket(TxPacket.INSTRUCTION_HANDSHAKE, TxPacket.DATA1_HANDSHAKE, TxPacket.DATA2_HANDSHAKE); // send the packet as an array of bytes serialPort.DiscardOutBuffer(); serialPort.DiscardInBuffer(); serialPort.Write(txPacket.asByteArray(), 0, 3); rxPacket = new RxPacket(); // make a new incoming packet to store data in. while ((serialPort.BytesToRead < 3) && (serialTimeoutCounter < connectTimeout)) { Thread.Sleep(1); serialTimeoutCounter++; } serialTimeoutCounter = 0; if (dataStorage.getVerbosity()) { form1.appendToRichTextBox1("Attempting connection on " + serialPort.PortName + " " + serialPort.BaudRate + " baud\r"); } if (serialPort.BytesToRead >= 3) { rxPacket.setInstruction((Byte)serialPort.ReadByte()); rxPacket.setData1((Byte)serialPort.ReadByte()); rxPacket.setData2((Byte)serialPort.ReadByte()); if ((rxPacket.getInstruction() == RxPacket.RX_INSTRUCTION_HANDSHAKE) && (rxPacket.getData2() == RxPacket.RX_DATA2_HANDSHAKE)) { incomingPackets.Enqueue(rxPacket); // put the handshake response packet in the incoming packets queue. parseData(incomingPackets); // parseData(rxPacket); serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); // start the handler for future packets. form1.appendToRichTextBox1("Connected to device on port " + s + " at " + i + " baud.\r"); } else { if (dataStorage.getVerbosity()) { form1.appendToRichTextBox1("An MCU at " + serialPort.PortName + ", " + serialPort.BaudRate + " baud replied with " + rxPacket.getInstruction().ToString("x") + " " + rxPacket.getData1().ToString("x") + " " + rxPacket.getData2().ToString("x") + "\r"); } serialPort.DiscardInBuffer(); serialPort.DiscardOutBuffer(); serialPort.Close(); } } else { serialPort.DiscardInBuffer(); serialPort.DiscardOutBuffer(); serialPort.Close(); if (dataStorage.getVerbosity()) { form1.appendToRichTextBox1("Failed to connect to " + serialPort.PortName + " at " + serialPort.BaudRate + " baud rate.\r"); } } } catch (Exception ex) { serialPort.DiscardInBuffer(); serialPort.DiscardOutBuffer(); serialPort.Close(); form1.appendToRichTextBox1("Error connecting to port " + serialPort.PortName + " at " + serialPort.BaudRate + " baud, message: " + ex.Message + "\r"); } if (serialPort.IsOpen) { return true; } } if (serialPort.IsOpen) { return true; } } } return false; }
// parses the data received in the packet into appropriate memory locations private void parseData(Queue<RxPacket> incomingPackets/*RxPacket rxPacket*/) { while (incomingPackets.Count > 0) { rxPacket = incomingPackets.Dequeue(); switch (rxPacket.getInstruction()) { case RxPacket.RX_INSTRUCTION_HANDSHAKE: int numChannels = rxPacket.getData1(); if (numChannels < 8) { form1.appendToRichTextBox1("MCU has " + numChannels + " channels.\r"); } if (numChannels > 8) { numChannels = 8; form1.appendToRichTextBox1("MCU has more than 8 channels.\rUsing channels 0-7\r"); } dataStorage.setNumADCChannels(numChannels); form1.appendToRichTextBox1("received handshake packet from MCU.\r"); break; case RxPacket.RX_INSTRUCTION_READ_ADC_CHANNEL_ZERO: case RxPacket.RX_INSTRUCTION_READ_ADC_CHANNEL_ONE: case RxPacket.RX_INSTRUCTION_READ_ADC_CHANNEL_TWO: case RxPacket.RX_INSTRUCTION_READ_ADC_CHANNEL_THREE: case RxPacket.RX_INSTRUCTION_READ_ADC_CHANNEL_FOUR: case RxPacket.RX_INSTRUCTION_READ_ADC_CHANNEL_FIVE: case RxPacket.RX_INSTRUCTION_READ_ADC_CHANNEL_SIX: case RxPacket.RX_INSTRUCTION_READ_ADC_CHANNEL_SEVEN: case RxPacket.RX_INSTRUCTION_READ_ADC_CHANNEL_EIGHT: case RxPacket.RX_INSTRUCTION_READ_ADC_CHANNEL_NINE: case RxPacket.RX_INSTRUCTION_READ_ADC_CHANNEL_TEN: case RxPacket.RX_INSTRUCTION_READ_ADC_CHANNEL_ELEVEN: UInt16 ADCcount = (UInt16)((UInt16)rxPacket.getData1() << 8); ADCcount |= (UInt16)rxPacket.getData2(); dataStorage.setADCCount(rxPacket.getInstruction(), ADCcount); // packet instruction is ADC channel to measure if (dataStorage.getVerbosity()) { form1.appendToRichTextBox1("Read ADC channel " + rxPacket.getInstruction() + " value is 0x" + ADCcount.ToString("x") + "\r"); } break; case RxPacket.RX_INSTRUCTION_FAILED_ADC_READ: form1.appendToRichTextBox1("MCU failed to read ADC\r"); break; case RxPacket.RX_INSTRUCTION_READ_DUTY_CYCLE: dataStorage.setCurrentDutyCycle(rxPacket.getData1()); // record duty cycle if (dataStorage.getVerbosity()) { form1.appendToRichTextBox1("Duty cycle is 0x" + rxPacket.getData1().ToString("x") + "\r"); } break; case RxPacket.RX_INSTRUCTION_SET_DUTY_CYCLE: dataStorage.setCurrentDutyCycle(rxPacket.getData2()); // record duty cycle if (dataStorage.getVerbosity()) { form1.appendToRichTextBox1("Duty cycle changed from 0x" + rxPacket.getData1().ToString("x") + " to 0x" + rxPacket.getData2().ToString("x") + "\r"); } break; case RxPacket.RX_INSTRUCTION_EOF: break; case RxPacket.RX_INSTRUCTION_UNKNOWN_COMMAND: form1.appendToRichTextBox1("MCU sent error code 0xAA, says it received instruction 0x" + rxPacket.getData1().ToString("x") + " and data1 0x" + rxPacket.getData2().ToString("x") + "\r"); break; default: form1.appendToRichTextBox1("Error reading fom MCU: \r received instruction code 0x" + rxPacket.getInstruction().ToString("x") + "\r data 1 was 0x" + rxPacket.getData1().ToString("x") + "\r data 2 was 0x" + rxPacket.getData2().ToString("x") + "\r"); //throw new Exception("Error parsing data from MCU"); break; } } }