Possible to use a screen (ideally a touchscreen) with Opta?

Is it possible to use an LCD/OLED or ideally a touchscreen with the Opta?

I'm working on an industrial application that will require selection of one or more of several dozen instances on a machine and a touchscreen is the only realistic way I can think of to easily display all that information and allow easy input as well.

If it matters, I will only need two (potentially three) additional input pins and I only need one output relay.

I love the simplicity of the Opta and would very much like to use it for this project. That said, if it's not possible, I'd appreciate any suggestions for similar arduino boards that support touchscreens and allow for easy control of relays.

Thanks all!

The Opta is a weird bird as Arduinos go. It is optimized for industrial voltage levels analog input and doesn't accept normal digital logic level inputs. Additionally, it doesn't seem to have I2C or SPI I/O available even though I'm sure it's available on the controller chip(s) used. There is an expansion bus and I'm not familiar with what options are available through that.

If you have the RS-485 or wireless version you could conceivably communicate with a human interface display of some sort but you are possibly better off moving your post to the general forum where a classic Arduino solution will be offered.

I'm trying to develop an industrial application that requires the display and selection on/off of about 30 items. I think the only simple way to do this is with a touchscreen.

I'm quite comfortable writing software, not as good with hardware specification. For that reason, I've used the arudino Opta for my last few projects. Unfortunately, using an Opta with a touchscreen seems very difficult.

Can anyone suggest an arduino board / touchscreen combination that would be easy to work with? I will have three sensors (12 volt or 24 volt either way) that will need inputs and I need to control one relay on the output side. Ideally the screen would have a good refresh rate as there is a lot of information to display that changes a lot.

Thanks so much!

By far the easiest way is with a Raspberry pi and a touchscreen. Next easiest is probably using an M5 series unit, but their screens only go up to about 3" There is the infamous Cheap Yellow Display that has an ESP32 with a 7" screen for the low, low price of only $30, but the documentation is not very good and while doable (I have a controller that uses one), it's a lot of work.

tl;dr: Go with a Raspberry pi. Can probably use one of the cheap Pi zero units and a serial connection to your Opta.

1 Like

I would second the suggestion by @cedarlakeinstruments for use of a Raspberry Pi, e.g. the PiHut has several touch screens
not actually used a touch screen but have had a number of RPi 3B with displays of various sizes running videos in a museum without problems for approximately five years - videos are selected using a keypad or triggered using a PIR
I used Java as the program language to schedule the videos but C++, Python, etc may be used
make sure you use a good power supply !!

Third-ed. Arduinos are fine little systems, but in general they aren't powerful enough to implement anything but the simplest GUI. (Which goes double for the SW libraries and such "needed" for implementing GUIs. On an RPi with Python, you can spend a lot of time just choosing which GUI library you want to use.)
If your project has real-time or hardware connectivity issues that seem to require an Arduino, you can uses the RPi PLUS and Arduino.

1 Like

@optaindustrialmaker, do not cross-post. Threads merged.

Which Opta do you have? The serial port option is RS485 so that will determine how you would communicate with e.g. a Raspberry Pi. Which IDE are you using? Does it allow the sort of textual I/O necessary to drive a remote GUI?

For industrial applications, I find it much more interesting to use an OPTA with an HMI. This PLC + HMI standard is widely found in industries and it is best to maintain the standard for greater reliability in your own work. I don't think it's cool to use a Raspberry with a display.
Today I use my OPTA with an HMI through Modbus RS485, programming is not difficult, but the most complex thing is the HMI software that you use, but once the communication goes well, I guarantee that this application will be very interesting. .
Anyway, I have my code that I used for communication, it doesn't change much from IHM to IHM, it just changes memory addresses, but if you want, I can share it with you to help you.
I wasn't an HMI specialist, so maybe my entire application needs optimization, but it's still 100% functional

1 Like

You'd probably be surprised to know how many HMI's were just a Pi with a display :wink:

I may even be surprised, but as I said, industrial applications it is interesting to follow the PLC + HMI standard, but this depends largely on each person's opinion, this is mine and many industries ask for and follow this. :grinning:

I'd like to thank everyone for their input on this topic.

I researched the rasberry pi option as well as the Opta w/ RS485 possibility. Both would require significant new learning from me to make them work.

I found a touchscreen with a shield ready to go for the Mega rev 3 board. I'm going to combine this with a relay shield. The wiring won't be as simple as the Opta, and the voltage of the sensors and such will have to be adjusted, but I think this setup will sort of fall into the "devil I know" realm and i should be able to make it work.

Appreciate it guys.

A Raspberry Pi CM4 is a pretty good core for a Modbus RTU/TCP HMI.

Hi!
On some events that we´ve been present (Arduino company) our colleagues presented a setup running an Opta with an Modbus/rs485 HMI, with a few buttons and functions showing the features of the Opta.

I am interested in your code. I need a little help to get started with Opta + HMI. Thank you.

Hello, here is the code I used to connect to the HMI through Modbus RS485 on OPTA. I'm no expert, but it worked perfectly for me.
In addition, I also created an online dashboard on the Arduino platform, in addition to the HMI.

/* 
  Sketch generated by the Arduino IoT Cloud Thing "Untitled"
  https://create.arduino.cc/cloud/things/ce28a408-ef79-4e2d-a0b6-dea70ad05741 

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  float i;
  float med1;
  float med2;
  float p;
  float p1;
  float temperatura;
  float temperatura2;
  float v;
  float voltageA0;
  float voltageA1;
  CloudLight led;
  CloudLight nmax1;
  CloudLight nmax2;
  CloudLight sinalizacaob1;
  CloudLight sinalizacaob2;
  int b1;
  int b2;
  int ctr;
  int liga;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/
 



bool estadobotao1 = 1;
bool estadobotao2 = 0;
bool estadobotao3 = 0;

#include <ArduinoModbus.h>
#include <ArduinoRS485.h>

constexpr auto baudrate{ 19200 };
constexpr auto btime{ 1.0f / baudrate };
constexpr auto predl{ btime * 9.6f * 3.5f * 1e6 };
constexpr auto postdl{ btime * 9.6f * 3.5f * 1e6 };

#include "thingProperties.h"

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(115200);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 

  // Defined in thingProperties.h
  initProperties();
  

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
  delay(400);
  RS485.setDelays(predl, postdl);
  if (!ModbusRTUClient.begin(baudrate, SERIAL_8N2)) {
    Serial.println("Erro Modbus");
    while (1);
  }

  analogReadResolution(12);
  pinMode(LED_D0, OUTPUT);
  pinMode(LED_D1, OUTPUT);
  pinMode(LED_D2, OUTPUT);
  pinMode(LED_D3, OUTPUT);
  pinMode(LED_USER, OUTPUT);
  pinMode(BTN_USER, INPUT);
  pinMode(LEDR, OUTPUT);
  pinMode(D0, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
  pinMode(D3, OUTPUT); 
  
}

void loop() {
  ArduinoCloud.update();
  // Your code here 

  ctr++;
  ModbusRTUClient.beginTransmission(2, HOLDING_REGISTERS, 1, 10);
  ModbusRTUClient.write(ctr);
  ModbusRTUClient.write(2);
  ModbusRTUClient.write(3);
  ModbusRTUClient.write(v);
  ModbusRTUClient.write(p1);
  ModbusRTUClient.write(voltageA0);
  ModbusRTUClient.write(liga);
  ModbusRTUClient.write(b1);
  ModbusRTUClient.write(b2);
  ModbusRTUClient.write(voltageA1);
  auto estadoSaida = ModbusRTUClient.coilRead(2,1);
  

  Serial.println("Conectado com sucesso");

  if (!ModbusRTUClient.endTransmission()) {
    Serial.print("failed! ");
    Serial.println(ModbusRTUClient.lastError());
  }

  //0x09BA - Active Power Total 32490-32491, IEEE 754 T_Float, x 1W
  p = readdata(0x21, 0X9BA);
  //0x09C4 - Tensione 32500-32501, IEEE 754 T_Float, x 
  v = readdata(0x21, 0X9C4);
  // 0x9D4 - corrente 32516-32517, IEEE 754 T_Float, x 1A
  i = readdata(0x21, 0X9D4);

  Serial.println(String(p, 1) + "W " + String(v, 1) + "V " + String(i, 3) + "A ");
  delay(400);

  p1 = p*10;
  

  int sensorValueA0 = analogRead(A0);
  voltageA0 = sensorValueA0 * (3.0 / 4095.0)/ 0.3;
  med1 = voltageA0 * 10;

  int sensorValueA1 = analogRead(A1);
  voltageA1 = sensorValueA1 * (3.0 / 4095.0)/ 0.3;
  med2 = voltageA1 * 10;

  Serial.print("I1 value: ");
   Serial.print(sensorValueA0);
   Serial.print(" corresponding to ");
   Serial.print(voltageA0, 5); // Print the voltage as a float with 5 decimal digits
   Serial.println("Volts");

  Serial.print("I2 value: ");
   Serial.print(sensorValueA1);
   Serial.print(" corresponding to ");
   Serial.print(voltageA1, 5); // Print the voltage as a float with 5 decimal digits
   Serial.println("Volts");

  estadobotao2 = digitalRead(A2);
  estadobotao3 = digitalRead(A3);
  
  
    if(voltageA0 >= 8 || estadobotao2 == HIGH){
      digitalWrite(D2, HIGH);
      digitalWrite(LED_D2, HIGH);
    }else{
      digitalWrite(D2, LOW);
      digitalWrite(LED_D2, LOW);
    }  

    if(voltageA1 >= 9 || estadobotao3 == HIGH){
      digitalWrite(D3, HIGH);
      digitalWrite(LED_D3, HIGH);
    }else{
      digitalWrite(D3, LOW);
      digitalWrite(LED_D3, LOW);
    }

    if(med1 >= 80){
      sinalizacaob1 = HIGH;
    }else{
      sinalizacaob1 = LOW;
    }

    if(med2 >= 90){
      sinalizacaob2 = HIGH;
    }else{
      sinalizacaob2 = LOW;
    }

    if(med1 >=100){
      nmax1 = HIGH;
    }else{
      nmax1 = LOW;
    }

    if(med2 >=100){
      nmax2 = HIGH;
    }else{
      nmax2 = LOW;
    }

    estadobotao1 = digitalRead(BTN_USER);
    if(estadobotao1 == LOW || led == HIGH){
    digitalWrite(D1, HIGH);
    digitalWrite(LED_D1, HIGH);
    }else{
    digitalWrite(D1, LOW);
    digitalWrite(LED_D1, LOW);
    }

   if(estadoSaida){
    digitalWrite(LED_USER, HIGH);
    digitalWrite(LEDR, LOW);
    delay(300);
    digitalWrite(LED_USER, LOW);
    digitalWrite(LEDR, HIGH);

    delay(50);
    digitalWrite(LED_D0, LOW);
    digitalWrite(D0, LOW);
   }else{
    digitalWrite(LED_D0, HIGH);
    digitalWrite(D0, HIGH);
    digitalWrite(LED_USER, HIGH);
    digitalWrite(LEDR, HIGH);
   }

  int sensorValueA2 = analogRead(A4);
  float voltageA2 = sensorValueA2 * (3.0 / 4095.0)/ 0.3;
  temperatura = voltageA2 * 19;
  Serial.print("Temperatura: ");
  Serial.print(temperatura);
  Serial.println(" °C");


   // Read the input on analog input I1 corresponding to A0:
  int sensorValueA3 = analogRead(A5);
  float voltageA3 = sensorValueA3 * (3.0 / 4095.0)/ 0.3;
  temperatura2 = voltageA3 * 19;
  Serial.print("Temperatura 2: ");
  Serial.print(temperatura2);
  Serial.println(" °C");

  
}




float readdata(int addr, int reg) {
  float res = 0.0;
  if (!ModbusRTUClient.requestFrom(addr, INPUT_REGISTERS, reg, 2)) {
    Serial.println("Erro de comunicação");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    uint16_t word1 = ModbusRTUClient.read();
    uint16_t word2 = ModbusRTUClient.read();
    uint32_t parz = word1 << 16 | word2;
    res = *(float *)&parz;
  }
  return res;
}

/*
  Since Ctr is READ_WRITE variable, onCtrChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onCtrChange()  {
  // Add your code here to act upon Ctr change
}

Hi,
where can I find this setup presented by your colleagues, please?

Unfortunately, I do not have the code @florin_bendrea

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.