NEWS
По-битный разбор десятичного числа
-
Добрый день.
К сожалению Beckhoff дает считать с себя данные только словами, а это 16 бит.
Читаю из Remanent области и для получения 50 бит данных разбазаривать 100 байт совсем не комильфо, когда можно считать одним словом булевы данные по целому разделу.
в JS не силен, курил булевы операции но так и не понял как правильно перевести число в двоичный вид и раскидать данные по отдельным переменным… точнее так: как правильно сделать побитовый сдвиг и "&" с маской...
-
Добрый день.
К сожалению Beckhoff дает считать с себя данные только словами, а это 16 бит.
Читаю из Remanent области и для получения 50 бит данных разбазаривать 100 байт совсем не комильфо, когда можно считать одним словом булевы данные по целому разделу.
в JS не силен, курил булевы операции но так и не понял как правильно перевести число в двоичный вид и раскидать данные по отдельным переменным… точнее так: как правильно сделать побитовый сдвиг и "&" с маской... `
Как ты читаешь данные?не твой случай? http://forum.iobroker.net/viewtopic.php?f=26&t=8629
-
Читаю просто, двухбайтное слово через modbus TCP с контроллера.
Благодарю, щас раскурю ссылку.
-
Читаю просто, двухбайтное слово через modbus TCP с контроллера.
Благодарю, щас раскурю ссылку. `
т.е. обычная строка? разбей её посимвольно -
вроде все получилось.
разбил по-символьно, засунул в массив.
получилось как то так:
! ````
var bin16;
var length1;
var data = [];
createState('MOV.FLT',0);
createState('MOV.KUH',0);
createState('MOV.KOR',0);
createState('MOV.BDR',0);
createState('MOV.DET',0);
createState('MOV.VAN',0);
createState('MOV.TLT',0);
createState('MOV.PRH',0);
! schedule("*/15 * * * * *", function () {
! bin16 = getState("modbus.0.holdingRegisters.56411_MOV_FLT").val.toString(2); // получаем из ячейки modbus 2-х байтное слово и переводим в двоичное представление, слово типа "1010011101"
! length1 = 6;
while (length1>=0) { // обнуляем весь массив для того чтоб не было undefined при массиве размером меньше 6
data[length1]=0;
length1--;
}
! switch (parseInt (bin16)) {
! case 0: //если ключевой бит снят то все обнуляем
setState("javascript.0.MOV.FLT", 0);
setState("javascript.0.MOV.KUH"/MOV.KUH/, 0);
setState("javascript.0.MOV.KOR"/MOV.KOR/, 0);
setState("javascript.0.MOV.BDR"/MOV.BDR/, 0);
setState("javascript.0.MOV.DET"/MOV.DET/, 0);
setState("javascript.0.MOV.VAN"/MOV.VAN/, 0);
setState("javascript.0.MOV.TLT"/MOV.TLT/, 0);
setState("javascript.0.MOV.PRH"/MOV.PRH/, 0);
break;
! case 1: // если установлен только ключевой бит то отмечаем только его
setState("javascript.0.MOV.FLT", 1);
setState("javascript.0.MOV.KUH"/MOV.KUH/, 0);
setState("javascript.0.MOV.KOR"/MOV.KOR/, 0);
setState("javascript.0.MOV.BDR"/MOV.BDR/, 0);
setState("javascript.0.MOV.DET"/MOV.DET/, 0);
setState("javascript.0.MOV.VAN"/MOV.VAN/, 0);
setState("javascript.0.MOV.TLT"/MOV.TLT/, 0);
setState("javascript.0.MOV.PRH"/MOV.PRH/, 0);
break;default: // во всех других случаях разбираем бинарное старшее слово length1 = (bin16.length)-9; while (length1>=0) { //5 и меньше data[length1] = parseInt (bin16.charAt(length1),2); // пишем в массив побитно (с 9-го бита слова вверх) length1--; } setState("javascript.0.MOV.FLT", 1); setState("javascript.0.MOV.KUH"/*MOV.KUH*/, data[0]); setState("javascript.0.MOV.KOR"/*MOV.KOR*/, data[1]); setState("javascript.0.MOV.BDR"/*MOV.BDR*/, data[2]); setState("javascript.0.MOV.DET"/*MOV.DET*/, data[3]); setState("javascript.0.MOV.VAN"/*MOV.VAN*/, data[4]); setState("javascript.0.MOV.TLT"/*MOV.TLT*/, data[5]); setState("javascript.0.MOV.PRH"/*MOV.PRH*/, data[6]);
}
! });
не сильно оптимально, но работает)
-
Спасибо за скрипт, коллега. Как раз решал такую же задачу. Немного доработал его, возможно, будет полезно последователям.
! ````
var bin16;
! // Состояния входящих регистров в порядке их размещения в памяти ПЛК Beckhoff BC9000
createState('D3KitchenLight1',0); // %QX128.0
createState('D3LibraryLight1',0); // %QX128.1
createState('D3KitchenLight2',0); // %QX128.2
createState('D3LibraryLight2',0); // %QX128.3
createState('D3BedroomLight1',0); // %QX128.4
createState('D3LibraryLight3',0); // %QX128.5
createState('D3BedroomLight2',0); // %QX128.6
createState('D3LibraryLight4',0); // %QX128.7
createState('D3DressingRoomLight',0); // %QX129.0
createState('D3TankLight',0); // %QX129.1
createState('D3LobbyLight',0); // %QX129.2
createState('D3BathroomRadiator',0); // %QX129.3
createState('DLadderLight',0); // %QX129.4
createState('D3TankroomRadiator',0); // %QX129.5
createState('D3BathroomLight',0); // %QX129.6
createState('D3BathroomTowelHeater',0); // %QX129.7
! // код срабатывает только в случае, когда изменился какой либо из регистров
on('modbus.0.inputRegisters.0', function (obj) {
! // получаем из ячейки modbus 2-х байтное слово и переводим в двоичное представление,
// слово типа "1010011101"
bin16 = getState("modbus.0.inputRegisters.0").val.toString(2);
! // здесь дополняем строку до 16 симоволов лидирующими нулями
// и получаем строку типа "0000001010011101"
while (bin16.length < 16) {
bin16 = '0' + bin16;
}
! // Разбираем состояния в соотвествии с порядком битов unsigned 16 bit (little endian)
setState("javascript.0.D3KitchenLight1", bin16[7]);
setState("javascript.0.D3LibraryLight1", bin16[6]);
setState("javascript.0.D3KitchenLight2", bin16[5]);
setState("javascript.0.D3LibraryLight2", bin16[4]);
setState("javascript.0.D3BedroomLight1", bin16[3]);
setState("javascript.0.D3LibraryLight3", bin16[2]);
setState("javascript.0.D3BedroomLight2", bin16[1]);
setState("javascript.0.D3LibraryLight4", bin16[0]);
setState("javascript.0.D3DressingRoomLight", bin16[15]);
setState("javascript.0.D3TankLight", bin16[14]);
setState("javascript.0.D3LobbyLight", bin16[13]);
setState("javascript.0.D3BathroomRadiator", bin16[12]);
setState("javascript.0.DLadderLight", bin16[11]);
setState("javascript.0.D3TankroomRadiator", bin16[10]);
setState("javascript.0.D3BathroomLight", bin16[9]);
setState("javascript.0.D3BathroomTowelHeater", bin16[8]);
! });