//этот таймер будет использоваться для работы с поиском устройств, //он будет отсчитывать время до отправки следующего сообщения private void timer3_Tick(object sender, EventArgs e) { if (templateArrIndex < templateArr.Length - 1) { if ((ReadDataCRCOk) | (answerTimedOut) | (ReadDataCRCError >= 3)) { templateArrIndex++; } byte[] tmpMsg = new byte[1]; tmpMsg[0] = 0x00; HartProtocol.lastCommand = templateArr[templateArrIndex]; dataToWriteInPort = HartProtocol.createMessageToSend(templateArr[templateArrIndex], tmpMsg); serialPort1.Write(dataToWriteInPort, 0, dataToWriteInPort.Length); if (templateArrIndex % 2 == 0) { textBox3.AppendText(DateTime.Now.ToString() + " отправлен запрос на чтение идентификатора устройства по адресу " + Convert.ToString(HartProtocol.SlaveAddress) + "\r\n"); } else { textBox3.AppendText(DateTime.Now.ToString() + " отправлен запрос на чтение серийного номера устройства по адресу " + Convert.ToString(HartProtocol.SlaveAddress) + "\r\n"); } textBox3.AppendText(ByteToHex(dataToWriteInPort)); textBox3.AppendText("\r\n"); timer2.Start(); timer3.Start(); } else { toolStripStatusLabel1.Text = "Поиск устройств завершен"; templateArrIndex = 0; button4.Text = "Начать поиск"; toolStripProgressBar1.Visible = false; } }
private void timer2_Tick(object sender, EventArgs e) { timer2.Stop(); //if()progressBarCounter++; if (serialPort1.BytesToRead - 3 > HartProtocol.GetCommandDataLength(HartProtocol.lastCommand)) { answerTimedOut = false; incomingMessageProcessor();// HartProtocol.GetCommandDataLength(HartProtocol.lastCommand)) incomingMessageProcessor(); if ((ReadDataCRCOk) && (templateSelected == 1)) { devicesArr[HartProtocol.SlaveAddress].address = Convert.ToByte(HartProtocol.SlaveAddress); devicesArr[HartProtocol.SlaveAddress].devType = Convert.ToByte((Convert.ToByte(HartProtocol.DevTypeCode) & 0x10) >> 4); devicesArr[HartProtocol.SlaveAddress].devName = "ДВСТ-" + Convert.ToString(Convert.ToByte(HartProtocol.DevTypeCode) & 0x0f); devicesArr[HartProtocol.SlaveAddress].serialNum = HartProtocol.DevSerialNumber; devicesArr[HartProtocol.SlaveAddress].firmwareRevision = Convert.ToByte(HartProtocol.SoftwareRev); devicesArr[HartProtocol.SlaveAddress].enabled = true; ListViewItem newItem; if ((devicesArr[HartProtocol.SlaveAddress].enabled) && (templateArrIndex % 2 != 0)) { devicesArr[HartProtocol.SlaveAddress].setValues(devicesArr[HartProtocol.SlaveAddress].devType); //newItem.SubItems.Add(devicesArr[i].address.ToString()); //newItem.SubItems.Add(devicesArr[i].devName); //newItem.SubItems.Add(devices.firmware.bootloader.ToString()); //newItem.SubItems.Add(devicesArr[i].serialNum.ToString()); //newItem.SubItems.Add(devicesArr[i].firmwareRevision.ToString()); newItem = new ListViewItem(devicesArr[HartProtocol.SlaveAddress].devs); listView1.Items.Add(newItem); } } if ((ReadDataCRCOk) && (templateSelected == 2)) { //CRCErrorsCounter++; //this.label3.Text = "Ошибок приёма:" + CRCErrorsCounter.ToString(); if (progressBarCounter > toolStripProgressBar1.Value) { toolStripProgressBar1.Value++; } } } else { //ReadBytesLastCycle = serialPort1.BytesToRead; answerTimedOut = true; textBox3.AppendText(DateTime.Now.ToString() + " таймаут ответа от устройства по адресу " + Convert.ToString(HartProtocol.SlaveAddress) + "\r\n"); //timer2.Start(); } if ((templateArrIndex % 2 != 0) && (templateArr[templateArrIndex] <= 0x10)) { // if (templateArr[templateArrIndex] == 0x00) if (lastSearchAddress != HartProtocol.SlaveAddress) { HartProtocol.SlaveAddress++; //progressBarCounter++; toolStripProgressBar1.Value++; } } }
public static byte[] ReadInputdataToSend(int commNumber)//здесь в зависимости от команды выбираем, что будем слать { byte[] dataToSend = new byte[CommandDataAnswerBytes[commNumber]]; if (commNumber == 4) { dataToSend[0] = (byte)SlaveAddress; //адрес для подчиненного устройства } if (commNumber == 5) { dataToSend = HartProtocol.ConvertASCIIToHartASCII(Tag); //отправляем тэг } if (commNumber == 11) { dataToSend = HartProtocol.ConvertASCIIToHartASCII(Message); //отправляем сообщение } if (commNumber == 12) //формирование сообщение с тэгом, дескрипотором и датой { byte[] tmp_tag = HartProtocol.ConvertASCIIToHartASCII(Tag); byte[] tmp_desc = HartProtocol.ConvertASCIIToHartASCII(Descriptor); for (int i = 0; i < tmp_tag.Length; i++) { dataToSend[i] = tmp_tag[i]; } for (int i = tmp_tag.Length; i < tmp_tag.Length + tmp_desc.Length; i++) { dataToSend[i] = tmp_desc[i - tmp_tag.Length]; } for (int i = tmp_tag.Length + tmp_desc.Length; i < tmp_tag.Length + tmp_desc.Length + Date.Length; i++) { dataToSend[i] = Date[i - tmp_tag.Length - tmp_desc.Length]; } } if (commNumber == 14) { dataToSend[0] = (byte)HartProtocol.PVunitsCode; //единицы измерения первичной переменной for (int i = 1; i < 5; i++) { dataToSend[i] = HartProtocol.UpperRangeLimit[i - 1]; //верхний предел диапазона dataToSend[i + 4] = HartProtocol.LowerRangeLimit[i - 1]; //нижний предел диапазона } } if (commNumber == 23) //измеренное значение нуля тока { dataToSend = HartProtocol.MeasuredCurrentZero; } if (commNumber == 24) //измеренное значение приращения тока { dataToSend = HartProtocol.MeasuredCurrentGain; } return(dataToSend); }
public static byte[] ReadInputdataToSend(int commNumber) { byte[] dataToSend = new byte[CommandDataAnswerBytes[commNumber]]; if (commNumber == 4) { dataToSend[0] = (byte)SlaveAddress; } if (commNumber == 5) { dataToSend = HartProtocol.ConvertASCIIToHartASCII(Tag); } if (commNumber == 11) { dataToSend = HartProtocol.ConvertASCIIToHartASCII(Message); } if (commNumber == 12) { byte[] tmp_tag = HartProtocol.ConvertASCIIToHartASCII(Tag); byte[] tmp_desc = HartProtocol.ConvertASCIIToHartASCII(Descriptor); for (int i = 0; i < tmp_tag.Length; i++) { dataToSend[i] = tmp_tag[i]; } for (int i = tmp_tag.Length; i < tmp_tag.Length + tmp_desc.Length; i++) { dataToSend[i] = tmp_desc[i - tmp_tag.Length]; } for (int i = tmp_tag.Length + tmp_desc.Length; i < tmp_tag.Length + tmp_desc.Length + Date.Length; i++) { dataToSend[i] = Date[i - tmp_tag.Length - tmp_desc.Length]; } } if (commNumber == 14) { dataToSend[0] = (byte)HartProtocol.PVunitsCode; for (int i = 1; i < 5; i++) { dataToSend[i] = HartProtocol.UpperRangeLimit[i - 1]; dataToSend[i + 4] = HartProtocol.LowerRangeLimit[i - 1]; } } if (commNumber == 23) { dataToSend = HartProtocol.MeasuredCurrentZero; } if (commNumber == 24) { dataToSend = HartProtocol.MeasuredCurrentGain; } return(dataToSend); }
private void button2_Click(object sender, EventArgs e) { //textBox1.Text = ByteToHex(getBytesFromGrid(1, 5)); HartProtocol.SlaveAddress = Convert.ToInt32(numericUpDown1.Value); byte[] tmpAddr = new byte[1]; tmpAddr[0] = Convert.ToByte(numericUpDown2.Value); byte[] tmpMes = HartProtocol.createMessageToSend(6, tmpAddr); numericUpDown1.Value = numericUpDown2.Value; HartProtocol.lastCommand = 6; templateProcessor((byte)dataExchangeTemplates.singleMessageTemplate, 6, tmpAddr, tmpAddr.Length); serialPort1.Write(tmpMes, 0, tmpMes.Length); textBox1.Text = ByteToHex(tmpMes); }
private void button5_Click(object sender, EventArgs e) { HartProtocol.SlaveAddress = Convert.ToInt32(numericUpDown1.Value); byte[] tmpSerial = new byte[3]; tmpSerial[0] = Convert.ToByte(Convert.ToInt32(numericUpDown3.Value) >> 16); tmpSerial[1] = Convert.ToByte((Convert.ToInt32(numericUpDown3.Value) >> 8) & 0x00ff); tmpSerial[2] = Convert.ToByte(Convert.ToInt32(numericUpDown3.Value) & 0x0000ff); byte[] tmpMes = HartProtocol.createMessageToSend(19, tmpSerial); HartProtocol.lastCommand = 19; templateProcessor((byte)dataExchangeTemplates.singleMessageTemplate, 19, tmpSerial, tmpSerial.Length); serialPort1.Write(tmpMes, 0, tmpMes.Length); textBox1.Text = ByteToHex(tmpMes); //numericUpDown1.Value = numericUpDown2.Value; }
private void button7_Click(object sender, EventArgs e) { byte[] eraseMes = new byte[5] { 0x45, 0x52, 0x41, 0x53, 0x45 }; byte[] tmpMes = HartProtocol.createMessageToSend(42, eraseMes); templateProcessor((byte)dataExchangeTemplates.singleMessageTemplate, 42, eraseMes, eraseMes.Length); serialPort1.Write(tmpMes, 0, tmpMes.Length); textBox1.Text = ByteToHex(tmpMes); toolStripStatusLabel1.Text = "Стирание программы..."; toolStripProgressBar1.Visible = true; progressBarCounter = 0; toolStripProgressBar1.Maximum = 500; toolStripProgressBar1.Value = 0; panel1.Enabled = false; toolStrip1.Enabled = false; timer5.Start(); }
private void button3_Click(object sender, EventArgs e) { // if (!serialPort1.IsOpen) // serialPort1.Open(); //HartProtocol.SlaveAddress = Convert.ToInt32(numericUpDown1.Value); byte[] tmpData = new byte[32]; for (byte i = 0; i < 32; i++) { tmpData[i] = i; } byte[] tmpByteArr = HartProtocol.createMessageToSend(0, tmpData); textBox1.Text = ByteToHex(tmpByteArr); HartProtocol.lastCommand = tmpByteArr[6]; serialPort1.Write(tmpByteArr, 0, tmpByteArr.Length); timer2.Start(); //numericUpDown1.Value = numericUpDown2.Value; //dataToWriteInPort = HartProtocol.createMessageToSend(templateArr[templateArrIndex], getBytesFromGrid(tableCellDataIndex, 32)); //templateProcessor((byte)dataExchangeTemplates.flashLoadTemplate, 1, getBytesFromGrid(tableCellDataIndex, 32), (dataGridView1.Rows.Count-1) * 16); }
/*Этот таймер используется для отсчета времени до следующей отправки сообщения * вообще же два таймера нужны для более простого и понятного интерфейса управления */ private void timer1_Tick(object sender, EventArgs e) { timer1.Stop(); if (templateArrIndex < templateArr.Length - 1) { progressBarCounter++; templateArrIndex++; tableCellDataIndex += 32; HartProtocol.lastCommand = templateArr[templateArrIndex]; byte[] tmpArr1 = getBytesFromGrid(tableCellDataIndex, 16); byte[] tmpArr2 = getBytesFromGrid(tableCellDataIndex + 16, 16); Array.Resize(ref tmpArr1, 32); for (int i = 16; i < 32; i++) { tmpArr1[i] = tmpArr2[i - 16]; } dataToWriteInPort = HartProtocol.createMessageToSend(templateArr[templateArrIndex], tmpArr1); serialPort1.Write(dataToWriteInPort, 0, dataToWriteInPort.Length); textBox3.AppendText("отправлено сообщение № " + (templateArrIndex + 1).ToString() + "\r\n"); textBox3.AppendText(ByteToHex(dataToWriteInPort)); textBox3.AppendText("\r\n"); if (templateArrIndex % 2 == 0) { toolStripStatusLabel1.Text = "Выполняется прошивка устройства.. "; } else { toolStripStatusLabel1.Text = "Выполняется прошивка устройства..."; } timer2.Start(); timer1.Start(); } else { toolStripStatusLabel1.Text = "Устройство прошито"; toolStripProgressBar1.Visible = false; } }
public void ConnectTest() { const int portNumber = 6; // Номер COM-порта. const int numberOfRepeats = 3; // Количество повторов запроса команды для теста получения серии ответов.. // Перед началом теста, необходимо убетиться, что COM-порт доступен и не занят. Иначе тест выполнять не имеет смысла. if (!SerialPortAdapter.IsPortAccessible(portNumber)) { Assert.Inconclusive(); } var connector = new SerialPortAdapter(portNumber); hart = new HartProtocol(connector, true, FrameFormats.Short); connector.DataReceived += NewData; var request = new Request(false, 0) { Preamble = 5, Command = 3 }; hart.Connect(); Thread.Sleep(1000); Assert.IsTrue(hart.IsConnected); for (var i = 1; i <= numberOfRepeats; i++) { hart.Request(request); Thread.Sleep(1000); } hart.Disconnect(); Assert.IsFalse(hart.IsConnected); Assert.IsTrue(hart.Messages.Count == 0); Assert.IsTrue(response.Count == numberOfRepeats); }
private void timer4_Tick(object sender, EventArgs e) { timer4.Stop(); if (serialPort1.BytesToRead - 3 > HartProtocol.GetCommandDataLength(HartProtocol.lastCommand)) { answerTimedOut = false; incomingMessageProcessor();// HartProtocol.GetCommandDataLength(HartProtocol.lastCommand)) incomingMessageProcessor(); if ((ReadDataCRCOk) && (HartProtocol.lastCommand == 19)) { textBox3.AppendText("Установлен серийный номер" + numericUpDown3.Value.ToString() + "\r\n"); devicesArr[HartProtocol.SlaveAddress].serialNum = Convert.ToInt32(numericUpDown3.Value); ListViewItem newItem; listView1.Items.RemoveAt(0);//вообще нужно поменять для выбранного индекса. devicesArr[HartProtocol.SlaveAddress].setValues(devicesArr[HartProtocol.SlaveAddress].devType); newItem = new ListViewItem(devicesArr[HartProtocol.SlaveAddress].devs); listView1.Items.Add(newItem); } if ((ReadDataCRCOk) && (HartProtocol.lastCommand == 6)) { textBox3.AppendText("Изменен адрес устройства на " + numericUpDown2.Value.ToString() + "\r\n"); devicesArr[HartProtocol.SlaveAddress].address = Convert.ToByte(numericUpDown2.Value); ListViewItem newItem; listView1.Items.RemoveAt(0);//вообще нужно поменять для выбранного индекса. devicesArr[HartProtocol.SlaveAddress].setValues(devicesArr[HartProtocol.SlaveAddress].devType); newItem = new ListViewItem(devicesArr[HartProtocol.SlaveAddress].devs); listView1.Items.Add(newItem); } } else { //ReadBytesLastCycle = serialPort1.BytesToRead; answerTimedOut = true; textBox3.AppendText(DateTime.Now.ToString() + " таймаут ответа от устройства по адресу " + Convert.ToString(HartProtocol.SlaveAddress) + "\r\n"); //timer2.Start(); } }
private void incomingMessageProcessor() { int i = 0; { //int dataQ = HartProtocol.GetCommandDataLength(HartProtocol.lastCommand); //if ((serialPort1.BytesToRead > dataQ)) //{ byte[] buffer = new byte[serialPort1.BytesToRead];//new byte[serialPort1.BytesToRead]; //for (i = 0; i < dataQ; i++)// (serialPort1.BytesToRead > 0) //{ // buffer[i] = (byte)serialPort1.ReadByte(); //} this.serialPort1.Read(buffer, 0, serialPort1.BytesToRead); //Array.Reverse(buffer); if (HartProtocol.CheckMessageIntegrity(buffer)) { // HartProtocol.CutOffGhostBytes(buffer); Array.Reverse(buffer); spRead = ByteToHex(buffer); byte[] buffer_ = HartProtocol.CutOffPreambulasRecieved(buffer); buffer_ = HartProtocol.CutOffGhostBytes(buffer_); if (HartProtocol.CheckCRC(buffer_) == 1) { spRead += " ---> CRC OK!"; MessagesRecieved++; ReadDataCRCError = 0; ReadDataCRCOk = true; } else { spRead += " ---> CRC Wrong!"; MessagesRecieved++; CRCerrors++; ReadDataCRCError++; ReadDataCRCOk = false; } HartProtocol.GenerateAnswer(buffer_); this.demoThread = new Thread(new ThreadStart(this.ThreadProcSafe)); this.demoThread.Start(); // ReadBytesLastCycle = 0; this.serialPort1.DiscardInBuffer(); this.serialPort1.DiscardOutBuffer(); this.serialPort1.Close(); this.serialPort1.Open(); ReadBytesLastCycle = 0; } // } } // ReadBytesLastCycle = serialPort1.BytesToRead; }
/* эта функция собирает шаблон для работы процессора обмена сообщений * она создает массив номеров команд и обнуляет индекс массива * входные данные - сценарий обмена, команда, данные, длина сообщения */ public void templateProcessor(byte dataReq, byte command, byte[] data, int length) { templateSelected = dataReq; progressBarCounter = 0; switch (dataReq) { case 0: { templateArr = new byte[length]; templateArr[0] = command; dataToWriteInPort = HartProtocol.createMessageToSend(command, data); HartProtocol.lastCommand = command; templateArrIndex = 0; //serialPort1.Write(dataToWriteInPort, 0, dataToWriteInPort.Length); timer4.Interval = 650; timer4.Start(); return; } case 1: { templateArr = new byte[length * 2]; //templateArr[0] = 0; //спрашиваем идшник девайса HartProtocol.SlaveAddress = firstSearchAddress; dataToWriteInPort = HartProtocol.createMessageToSend(command, data); //templateArr[1] = 1; // и его серийник for (int i = 0; i < templateArr.Length; i++) //templateArr[i] = 0x00; { if ((i % 2) != 0) { templateArr[i] = 16; } else { templateArr[i] = 0x00; } } serialPort1.Write(dataToWriteInPort, 0, dataToWriteInPort.Length); textBox3.AppendText("отправлен запрос на чтение идентификатора устройства по адресу " + Convert.ToString(HartProtocol.SlaveAddress) + "\r\n"); textBox3.AppendText(ByteToHex(dataToWriteInPort)); textBox3.AppendText("\r\n"); templateArrIndex = 0; timer3.Interval = 650; timer3.Start(); timer2.Start(); toolStripStatusLabel1.Text = "Выполняется поиск устройств..."; toolStripProgressBar1.Minimum = 0; toolStripProgressBar1.Maximum = 15; toolStripProgressBar1.Visible = true; return; } case 2: { /* * важный момент состоит в том, что команда записи страничного сегмента в память мк - 0xAA * должна приходить, пока не будет заполнена вся страница, т.е. если не хватает еще 2х сегментов страниц * данных, заполняем их oxff; * таким образом удастся заметно сократить код бутлодера, и он будет перезагружаться сразу по получению сообщения * о конце записи 0xAB */ while (length % 128 != 0) { length += 16; //добавляем ff до размера номинальной страницы флеш } templateArr = new byte[length / 32 + 1]; for (int i = 0; i < templateArr.Length - 1; i++) //шлем очень много 32х байтных сообщений { templateArr[i] = 0xAA; } templateArr[templateArr.Length - 1] = 0xAB; //и одно сообщение о том, что данных больше нет dataToWriteInPort = HartProtocol.createMessageToSend(0xAA, data); HartProtocol.lastCommand = 0xAA; templateArrIndex = 0; timer1.Interval = 650; serialPort1.Write(dataToWriteInPort, 0, dataToWriteInPort.Length); textBox3.AppendText("отправлено сообщение № " + (templateArrIndex + 1).ToString() + "\r\n"); textBox3.AppendText(ByteToHex(dataToWriteInPort)); textBox3.AppendText("\r\n"); timer2.Start(); timer1.Start(); toolStripStatusLabel1.Text = "Выполняется прошивка устройства..."; toolStripProgressBar1.Visible = true; toolStripProgressBar1.Minimum = 0; toolStripProgressBar1.Maximum = length / 32; toolStripProgressBar1.Value = 0; progressBarCounter = 0; return; } } }