//Get the calibration structure from the master unit public bool setCalibration(UInt32 CanID, SlaveConfig sc) { UInt32 retval; CAN.VCI_CAN_OBJ[] send = ctl.allocateCanFrameBuffer(1 + Marshal.SizeOf(typeof(SlaveConfig)) / 8); CAN.VCI_CAN_OBJ[] receive; send[0].ID = CanID; send[0].TimeFlag = 0; send[0].SendType = 0; send[0].RemoteFlag = 0; send[0].ExternFlag = 1; send[0].DataLen = 1; send[0].Data[0] = (byte)CANCMD.CAN_CMD_WRITE_CAL; retval = CAN.VCI_Transmit(CAN.DEV_USBCAN2, 0, 0, send, 1); if (retval != CAN.STATUS_OK) { return(false); } ctl.sendData(StructTools.struct2byteArray <SlaveConfig>(sc), CanID, false, true); ctl.getCanFrames(out receive, 1); if (receive[0].Data[0] == (byte)CANCMD.CAN_CMD_WRITE_CAL) { return(true); } else { return(false); } }
private byte getData <T>(T str, byte address) { byte[] buffer; buffer = StructTools.struct2byteArray <T>(str); return(buffer[address]); }
private void cmdReadVoltages_Click(object sender, EventArgs e) { byte [] data; byte [] dOut; int len; BalPktSingle balPkt; if (chkMaster.Checked) { ushort [] voltages = bc.getLocalVoltages(0xA); consolePrint("Voltages:"); for (int i = 0; i < 6; i++) { consolePrint(" " + Convert.ToString(Convert.ToDouble(voltages[i]) / 1000)); } consolePrint("\r\n\n"); } else { data = new byte[] { (byte)SlaveCodes.CMD_GET_BAL_INFO, 0x00 /*hop count*/, 0x01 /*balancer count*/, 0x00 /*load enable*/ }; bc.balBusTx(0xA, data); bc.balBusRx(out dOut, out len, 4 + 12, 100); balPkt = StructTools.byteArray2Struct <BalPktSingle>(dOut); consolePrint("Voltages:"); for (int i = 0; i < 6; i++) { consolePrint(" " + Convert.ToString(Convert.ToDouble(balPkt.voltages[i]) / 1000)); } consolePrint("\r\n\n"); } }
//Get the calibration structure from the master unit public SlaveConfig getCalibration(UInt32 CanID) { SlaveConfig sc = new SlaveConfig(); UInt32 retval; CAN.VCI_CAN_OBJ[] send = new CAN.VCI_CAN_OBJ[1]; CAN.VCI_CAN_OBJ[] receive; send[0].ID = CanID; send[0].TimeFlag = 0; send[0].SendType = 0; send[0].RemoteFlag = 0; send[0].ExternFlag = 1; send[0].DataLen = 1; send[0].Data = new byte[8]; send[0].Data[0] = (byte)CANCMD.CAN_CMD_READ_CAL; retval = CAN.VCI_Transmit(CAN.DEV_USBCAN2, 0, 0, send, 1); if (retval != CAN.STATUS_OK) { return(sc); } ctl.getCanFrames(out receive, 3); byte[] buffer = new byte[Marshal.SizeOf(typeof(SlaveConfig))]; for (int i = 0; i < buffer.Length; i++) { buffer[i] = receive[i / 8].Data[i % 8]; } return(StructTools.byteArray2Struct <SlaveConfig>(buffer)); }
public bool getBalData(UInt32 CanID) { CAN.VCI_CAN_OBJ[] rx; byte[] txBuf = { (byte)CANCMD.CAN_CMD_SEND_BAL_DATA }; ctl.sendData(txBuf, 0xA, false, true); int bytes = Marshal.SizeOf(typeof(BalData_t)) + 2; //Command code plus returned data //Get the first can frame and determine the length ctl.getCanFrames(out rx, (bytes + 7) / 8); UInt16 cmd = (ushort)(rx[0].Data[0] | rx[0].Data[1] << 8); if (cmd != (byte)CANCMD.CAN_CMD_SEND_BAL_DATA) { return(false); } byte[] buffer = new byte[Marshal.SizeOf(typeof(BalData_t))]; for (int i = 0; i < buffer.Length; i++) { buffer[i] = rx[(i + 2) / 8].Data[(i + 2) % 8]; } balData = StructTools.byteArray2Struct <BalData_t>(buffer); return(true); }
//Send the configuration structure public bool setConfig(UInt32 CanID, Config_t config) { CAN.VCI_CAN_OBJ[] receive; byte[] txMsg = { (byte)CANCMD.CAN_CMD_SET_CONFIG }; ctl.sendData(txMsg, CanID, false, true); ctl.sendData(StructTools.struct2byteArray <Config_t>(config), CanID, false, true); ctl.getCanFrames(out receive, 1); if (receive[0].Data[0] == (byte)CANCMD.CAN_CMD_SET_CONFIG) { return(true); } else { return(false); } }
public ushort[] getLocalVoltages(UInt32 CanID) { UInt32 retval; CAN.VCI_CAN_OBJ[] send = new CAN.VCI_CAN_OBJ[1]; CAN.VCI_CAN_OBJ[] receive; VoltagesStr vStr; send[0].ID = CanID; send[0].TimeFlag = 0; send[0].SendType = 0; send[0].RemoteFlag = 0; send[0].ExternFlag = 1; send[0].DataLen = 1; send[0].Data = new byte[8]; send[0].Data[0] = (byte)CANCMD.CAN_CMD_GET_LOCAL_VOLTAGES; retval = CAN.VCI_Transmit(CAN.DEV_USBCAN2, 0, 0, send, 1); if (retval != CAN.STATUS_OK) { return(new ushort[0]); } ctl.getCanFrames(out receive, 2); byte[] buffer = new byte[Marshal.SizeOf(typeof(VoltagesStr))]; for (int i = 0; i < buffer.Length; i++) { buffer[i] = receive[i / 8].Data[i % 8]; } vStr = StructTools.byteArray2Struct <VoltagesStr>(buffer); return(vStr.voltages); }
//Get the configuration structure from the master unit public Config_t getConfig(UInt32 CanID) { Config_t config = new Config_t(); CAN.VCI_CAN_OBJ[] receive; byte[] txMsg = { (byte)CANCMD.CAN_CMD_GET_CONFIG }; if (!ctl.sendData(txMsg, CanID, false, true)) { return(config); } ctl.getCanFrames(out receive, (Marshal.SizeOf(typeof(Config_t)) - 1) / 8 + 1); byte[] buffer = new byte[Marshal.SizeOf(typeof(Config_t))]; for (int i = 0; i < buffer.Length; i++) { buffer[i] = receive[i / 8].Data[i % 8]; } return(StructTools.byteArray2Struct <Config_t>(buffer)); }
private void slaveCalStep() { byte[] data = new byte[] { 0x01, 0x00, 0x01, 0x3F }; byte[] dOut; int len; byte address; SlaveConfig slaveConfig; BalPktSingle balPkt; switch (wizardState) { case WizardState.START: bc.setPassthrough(0xA, true); System.Threading.Thread.Sleep(100); bc.ctl.flush(); wizardState = WizardState.GET_FULL_V; consolePrint("Set the source to all full voltage \r\n"); cmdCalibrate.Text = "Next"; break; case WizardState.GET_FULL_V: slaveConfig.gain = new ushort[6]; slaveConfig.offset = new short[6]; //Set the calibration structure to default for (int i = 0; i < 6; i++) { slaveConfig.gain[i] = 5105; slaveConfig.offset[i] = 0; } slaveConfig.gain[1] *= 2; // for (address = 0; address < Marshal.SizeOf(slaveConfig); address++) { //Set address in config struct to modify data = new byte[] { (byte)SlaveCodes.CMD_SET_ADDR, address }; bc.balBusTx(0xA, data); //Send data for above address data = new byte[] { (byte)SlaveCodes.CMD_WRITE_CFG, getData <SlaveConfig>(slaveConfig, address) }; bc.balBusTx(0xA, data); } //Do a measurement with the new parameters data = new byte[] { (byte)SlaveCodes.CMD_GET_BAL_INFO, 0x00 /*hop count*/, 0x01 /*balancer count*/, 0x00 /*load enable*/ }; bc.balBusTx(0xA, data); bc.balBusRx(out dOut, out len, 4 + 12, 100); balPkt = StructTools.byteArray2Struct <BalPktSingle>(dOut); fullVoltages = balPkt.voltages; for (int i = 0; i < len; i++) { consolePrint(dOut[i].ToString() + " "); } consolePrint("\r\n"); consolePrint("Voltages:"); for (int i = 0; i < 6; i++) { consolePrint(" " + Convert.ToString(Convert.ToDouble(balPkt.voltages[i]) / 1000)); } consolePrint("\r\n\n"); consolePrint("Set voltage 0 to half level\r\n"); //bc.setPassthrough(0xA, false); wizardState = WizardState.GET_VLOW; vLowIndex = 0; cmdCalibrate.Text = "Next"; break; case WizardState.GET_VLOW: data = new byte[] { (byte)SlaveCodes.CMD_GET_BAL_INFO, 0x00 /*hop count*/, 0x01 /*balancer count*/, 0x00 /*load enable*/ }; bc.balBusTx(0xA, data); bc.balBusRx(out dOut, out len, 4 + 12, 100); balPkt = StructTools.byteArray2Struct <BalPktSingle>(dOut); halfVoltages[vLowIndex] = balPkt.voltages[vLowIndex]; consolePrint("Read half voltage of " + Convert.ToString((double)halfVoltages[vLowIndex] / 1000) + "\r\n"); vLowIndex++; if (vLowIndex >= 6) { wizardState = WizardState.WRITE_RES; } if (vLowIndex < 6) { consolePrint("Set voltage " + vLowIndex.ToString() + " to half level\r\n"); } else { consolePrint("Ready to write results\r\n"); } break; case WizardState.WRITE_RES: wizardState = WizardState.START; double [] actualHigh = new double[6]; double [] actualLow = new double[6]; actualHigh[0] = Convert.ToDouble(txtV0.Text); actualHigh[1] = Convert.ToDouble(txtV1.Text); actualHigh[2] = Convert.ToDouble(txtV2.Text); actualHigh[3] = Convert.ToDouble(txtV3.Text); actualHigh[4] = Convert.ToDouble(txtV4.Text); actualHigh[5] = Convert.ToDouble(txtV5.Text); actualLow[0] = Convert.ToDouble(txtVLow.Text); actualLow[1] = actualLow[0]; actualLow[2] = actualLow[0]; actualLow[3] = actualLow[0]; actualLow[4] = actualLow[0]; actualLow[5] = actualLow[0]; SlaveConfig newConfig; newConfig.gain = new ushort[6]; newConfig.offset = new short[6]; for (int i = 0; i < 6; i++) { if (i != 1) { double adcHigh = (double)fullVoltages[i] / 5105 * 65536; double adcLow = (double)halfVoltages[i] / 5105 * 65536; newConfig.gain[i] = (ushort)((actualHigh[i] - actualLow[i]) / (double)(adcHigh - adcLow) * 65536 * 1000); newConfig.offset[i] = (short)(adcLow * (double)newConfig.gain[i] / 65536 - actualLow[i] * 1000.0); } else { double adcHigh = ((double)fullVoltages[i] + (double)fullVoltages[0]) / (5105 * 2) * 65536; double adcLow = ((double)halfVoltages[i] + (double)fullVoltages[0]) / (5105 * 2) * 65536; newConfig.gain[i] = (ushort)((actualHigh[i] - actualLow[i]) / (adcHigh - adcLow) * 65536 * 1000); newConfig.offset[i] = (short)(adcLow * (double)newConfig.gain[i] / 65536 - actualHigh[0] * 1000 - actualLow[i] * 1000); } } //Write the new cal values to the balancer module for (address = 0; address < Marshal.SizeOf(typeof(SlaveConfig)); address++) { //Set address in config struct to modify data = new byte[] { (byte)SlaveCodes.CMD_SET_ADDR, address }; bc.balBusTx(0xA, data); //Send data for above address data = new byte[] { (byte)SlaveCodes.CMD_WRITE_CFG, getData <SlaveConfig>(newConfig, address) }; bc.balBusTx(0xA, data); } data = new byte[] { (byte)SlaveCodes.CMD_SAVE_CFG }; bc.balBusTx(0xA, data); bc.balBusRx(out dOut, out len, 100, 5000); if ((byte)SlaveCodes.CMD_SAVE_CFG == dOut[0] && len == 1) { consolePrint("Succsessfully stored results\r\n"); } else { consolePrint("Failed to store results! Received\r\n"); for (int i = 0; i < len; i++) { consolePrint(" " + dOut[i].ToString()); } consolePrint("\r\n"); } break; } }