Всем КУ. Мой первый пост, прошу не судить строго.
Возникла по работе необходимость считывать визуально состояние оборудования и, при необходимости, производить перезапуск криокомпрессора удаленно. Под рукой была Arduino UNO, к ней приобретены датчик освещенности, пока что 2 реле и 2 соленоида на 12 В(не суть важно). В дальнейшем то дело обрастет датчиками температуры, влажности и давления, но пока того нет в готовом виде.
Причина написания поста — это то, что в интернете нашлось очень мало информации по возможностям Processing 3, особенно в русскоязычной его части. Надеюсь, что таким же чайникам, как я, то когда-то пригодится, чтобы не тупить как я последнюю неделю.
Скетч для Ардуино простой, как три рубля: при получении определенных значений из ком порта дунька устанавливает значение на пинах и пишет об том ответ в ком порт, а так же замеряет освещенность и, так же, отчитывается об том. В дальнейшем он будет расширен.
Скетч Ардуино:
Это, думаю, и ежу понятно, но в связи с тем, что функционалом моей приблуды в дальнейшем будут пользоваться другие люди, то захотелось написать простенькое, но понятное GUI. Выбор пал на Processing, так как я был ранее знаком с Arduino IDE, которая, в свою очередь, построена на основе Processing.
В апплете использована библиотека ControlP5 для отрисовки элементов управления.
Лично для меня возникли проблемы с реализацией и поиском информации относительно следующих вещей — 1) запуск второго окна из приложения, 2) закрывание 2-го окна, но чтобы при том основное окно продолжало работать, 3) ради прикола — установка картинок в качестве фона и кнопок, полупрозрачность кнопок.
Итак, скетч Processing:
Полученная мной программа:
Раз
Два
Прошу сильно не пинать — мой первый проект на Processing, надеюсь кому нибудь помоет разобраться с такими простейшими, как оказалось вещами. А если кто подскажет, как оптимизировать мой г… код — буду рад.
Возникла по работе необходимость считывать визуально состояние оборудования и, при необходимости, производить перезапуск криокомпрессора удаленно. Под рукой была Arduino UNO, к ней приобретены датчик освещенности, пока что 2 реле и 2 соленоида на 12 В(не суть важно). В дальнейшем то дело обрастет датчиками температуры, влажности и давления, но пока того нет в готовом виде.
Причина написания поста — это то, что в интернете нашлось очень мало информации по возможностям Processing 3, особенно в русскоязычной его части. Надеюсь, что таким же чайникам, как я, то когда-то пригодится, чтобы не тупить как я последнюю неделю.
Скетч для Ардуино простой, как три рубля: при получении определенных значений из ком порта дунька устанавливает значение на пинах и пишет об том ответ в ком порт, а так же замеряет освещенность и, так же, отчитывается об том. В дальнейшем он будет расширен.
Скетч Ардуино:
#include <Wire.h>
#include <BH1750.h>
int val;
BH1750 lightMeter;
void setup() {
Serial.begin(9600);
lightMeter.begin();
Serial.println("Running...");
pinMode (7, OUTPUT);
pinMode(6, OUTPUT);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
}
void loop() {
uint16_t lux = lightMeter.readLightLevel();
if (Serial.available()) {
val = Serial.read();
if (val == '0') {
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
Serial.println("Оба реле ВЫКЛЮЧЕНЫ");
}
if (val == '1') {
digitalWrite(7, HIGH);
digitalWrite(6, LOW);
Serial.println("Реле 1 включено");
}
if (val == '2') {
digitalWrite(7, LOW);
digitalWrite(6, HIGH);
Serial.println("Включено реле 2");
}
if (val == '3') {
digitalWrite(7, LOW);
digitalWrite(6, LOW);
Serial.println("ВКЛЮЧЕНЫ оба реле");
}
if (val == '4') {
if (lux >= 800) {
Serial.print("Light: ");
Serial.print(lux);
Serial.println(" lx Все отлично ");
}
else {
Serial.print("Light: ");
Serial.print(lux);
Serial.println(" lx Мне ТЕМНО!!!!!!!");
}
}
}
}
Это, думаю, и ежу понятно, но в связи с тем, что функционалом моей приблуды в дальнейшем будут пользоваться другие люди, то захотелось написать простенькое, но понятное GUI. Выбор пал на Processing, так как я был ранее знаком с Arduino IDE, которая, в свою очередь, построена на основе Processing.
В апплете использована библиотека ControlP5 для отрисовки элементов управления.
Лично для меня возникли проблемы с реализацией и поиском информации относительно следующих вещей — 1) запуск второго окна из приложения, 2) закрывание 2-го окна, но чтобы при том основное окно продолжало работать, 3) ради прикола — установка картинок в качестве фона и кнопок, полупрозрачность кнопок.
Итак, скетч Processing:
Листинг кода
import processing.serial.*;
import controlP5.*;
import java.util.Date;
Serial port;
Textfield recived;
Textfield recived1;
Textfield recived2;
Textfield recived3;
Textfield recived4;
Textfield recived5;
String val;
String data;
String DateTab;
String Dat;
int data2=0;
String time;
Button vyvod;
PrintWriter output;
Table table2;
int i=0;
ControlP5 cp5;
ControlP5 ax;
PFont font;
PFont font2;
String[] args = {"YourSketchNameHere"};
SecondApplet sa;
PImage fon;
PImage fon2;
PImage titlebaricon; // Объявление переменных и классов
void setup() {
titlebaricon = loadImage("data/myicon.png");
surface.setIcon(titlebaricon);
surface.setTitle("Контроль МРТ"); //Установил свою иконку и название приложения)))
printArray(Serial.list());
port = new Serial(this, "/dev/ttyUSB0", 9600); //инициализирую com порт (под Ubuntu, для Windows указываем //com port)
cp5 = new ControlP5(this);
font = createFont("Arial", 20); //устанавливаю шрифт
fon = loadImage("data/phil.bmp"); //моя картинка в качестве фона
fon2 = loadImage("data/fon2.bmp"); /* размер картинки должен соответствовать размерам окна из void settings()*/
PImage img;
img = loadImage("data/image1.bmp"); //кнопки - собранные мной в папку "data" рисунки
image(img, 0, 0);
tint(0, 255, 0, 126); //Прозрачность кнопки - 50% и окрашивает в зеленый цвет
image(img, 50, 0);
PImage img2;
img2 = loadImage("data/image2.bmp");
image(img2, 0, 0);
image(img2, 50, 0); //делаю то же для всех моих кнопок
//только tint() должна вызываться один раз в моем примере.
PImage img3; // цвет и прозрачность всех кнопок будет одинакова.
img3 = loadImage("data/image3.bmp");
image(img3, 0, 0);
image(img3, 50, 0);
PImage img4;
img4 = loadImage("data/image4.bmp");
image(img4, 0, 0);
image(img4, 50, 0);
PImage img5;
img5 = loadImage("data/imagezapros.bmp");
image(img5, 0, 0);
image(img5, 50, 0);
PImage img6;
img6 = loadImage("data/temper.bmp");
image(img6, 0, 0);
image(img6, 50, 0);
cp5.addButton("Relay_1")
.setSize (100, 50)
.setPosition(50, 50)
.setFont(font)
.setImage(img)
.setLabel("Реле 1");
cp5.addButton("Relay_2")
.setSize (100, 50)
.setPosition(250, 50)
.setFont(font)
.setImage(img2)
.setLabel("Реле 2");
cp5.addButton("Relay_ON")
.setSize (300, 50)
.setPosition(50, 120)
.setFont(font)
.setLabel("Реле ВКЛ")
.setImage(img3);
cp5.addButton("Relay_OFF")
.setSize (300, 50)
.setPosition(50, 190)
.setFont(font)
.setLabel("Реле ВЫКЛ")
.setImage(img4);
cp5.addButton("Zapros_sostoyaniya")
.setSize (300, 50)
.setPosition(50, 260)
.setFont(font)
.setLabel("Запрос состояния")
.setImage(img5);
recived=cp5.addTextfield(" ")
.setSize(380,100)
.setPosition(10, 340)
.setColorValueLabel(0)
.setFont(font)
.setColorBackground(color(255, 255, 255));
cp5.addButton("temps")
.setSize (380, 50)
.setPosition(10, 500)
.setColorBackground(color(70, 100, 0))
.setColorForeground(color(0, 0, 0))
.setFont(font)
.setLabel("Температура")
.setImage(img6);
}
void settings(){
size(400, 560);
}
void draw() {
background(fon);
fill(0, 0, 0);
textFont(font);
text("Контроль МРТ", 135, 30);
int s = second();
int m = minute();
int h = hour();
int d = day();
int mo = month();
int y = year();
DateTab = str(d)+ "." + str(mo) + "." + str(y) + (" ") + str(h) + (":") + str(m) + (":") + str(s);
if ( port.available() > 0){
val = port.readString();
if(data2==0){ // до сих пор все должно быть понятно - обрабатываю события кнопок,
recived.setText(val); // пишу-читаю com порт, сохраняю дату-время и значение датчика.
} /* data2 - переменная, чтобы считанные в Second Applet показания не отображались в textfield основного окна программы. */
}
sa = new SecondApplet();
}
void Relay_1(){
port.write("1");
}
void Relay_2(){
port.write("2");
}
void Relay_ON(){
port.write("3");
}
void Relay_OFF(){
port.write("0");
}
void Zapros_sostoyaniya(){
data2=0;
port.write("4");
}
void save123(){ // Веду журнал в виде электронной таблицы
data2=1;
port.write("4");
delay(600);
port.available();
Dat=DateTab + " " + val;
table2 = loadTable("data/Journaltemp.ods"); // открываю файл
table2.setString(0, 0, "t"); //устанавливаю некое значение в ячейку 0.0
table2.removeColumn(0); /*удаляю столбец 0, иначе каждый раз создается новый столбец и таблица растет вширь*/
TableRow newRow = table2.addRow(); //создаю новую строку
newRow.setString(0, Dat); /*пишу в 0 столбец новой строки дату и показания датчика (пока освещенности)*/
saveTable(table2, "data/Journaltemp.ods"); //сохраняю значения в таблице
data2=0;
}
void temps(){
PApplet.runSketch(args, sa); //Запускаю окно Second Applet
}
public class SecondApplet extends PApplet {
public void setup(){
surface.setTitle("Контроль Температуры");
surface.setIcon(titlebaricon);
font2 = createFont("Arial", 20); /*можно установить свой шрифт, кнопки, текстовые поля и т.д.*/
ax = new ControlP5(this);
ax.addButton("test1")
.setSize(159, 70)
.setPosition(1, 300)
.setFont(font2)
.setLabel("Измерить");
ax.addButton("test2")
.setSize(158, 70)
.setPosition(161, 300)
.setFont(font2)
.setLabel("Измерить");
ax.addButton("test3")
.setSize(159, 70)
.setPosition(320, 300)
.setFont(font2)
.setLabel("Измерить");
ax.addButton("test4")
.setSize(159, 70)
.setPosition(480, 300)
.setFont(font2)
.setLabel("Измерить");
ax.addButton("test5")
.setSize(159, 70)
.setPosition(640, 300)
.setFont(font2)
.setLabel("Измерить");
ax.addButton("obj")
.setSize (790, 50)
.setPosition(5, 540)
.setColorBackground(color(70, 100, 0))
.setColorForeground(color(0, 0, 0))
.setFont(font)
.setLabel("Журнал");
recived1 = ax.addTextfield(" ")
.setSize(157, 70)
.setPosition(2, 370)
.setColorValueLabel(0)
.setFont(font)
.setColorBackground(color(255, 255, 255));
recived2=ax.addTextfield(" ")
.setSize(156, 70)
.setPosition(162, 370)
.setColorValueLabel(0)
.setFont(font)
.setColorBackground(color(255, 255, 255));
recived3=ax.addTextfield(" ")
.setSize(157, 70)
.setPosition(321, 370)
.setColorValueLabel(0)
.setFont(font)
.setColorBackground(color(255, 255, 255));
recived4=ax.addTextfield(" ")
.setSize(157, 70)
.setPosition(481, 370)
.setColorValueLabel(0)
.setFont(font)
.setColorBackground(color(255, 255, 255));
recived5=ax.addTextfield(" ")
.setSize(157, 70)
.setPosition(641, 370)
.setColorValueLabel(0)
.setFont(font)
.setColorBackground(color(255, 255, 255));
}
public void settings() {
size(800, 600); // а здесь размер
}
public void draw() {
background(fon2); //а здесь фон))
textFont(font2);
}
public void test1(){
recived1.setText(" 11111");
}
public void test2(){
recived2.setText(" 22222");
}
public void test3(){
recived3.setText(" 33333"); //обрабатываю события кнопок окна Second Applet
}
public void test4(){
recived4.setText(" 44444");
}
public void test5(){
recived5.setText(" 55555");
}
public void obj(){
save123(); /* для ведения журнала в виде электронной таблицы отсылаю к коду в теле основной программы*/
}
public void exitActual(){} //функция выхода из окна по кнопке [X] в верхнем поле окна.
} // при том первое окно продолжит работу, пока в нем не будет нажато [X].
Полученная мной программа:
Раз
Два
Прошу сильно не пинать — мой первый проект на Processing, надеюсь кому нибудь помоет разобраться с такими простейшими, как оказалось вещами. А если кто подскажет, как оптимизировать мой г… код — буду рад.