Optoingångar

Elektronikrelaterade (på komponentnivå) frågor och funderingar.
Användarvisningsbild
Icecap
Inlägg: 26093
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Optoingångar

Inlägg av Icecap »

OK, då lär högre spänning bara kunde ske vid sabortage - och då är allt möjligt.
FormerMazda
Inlägg: 6061
Blev medlem: 27 februari 2006, 14:59:36
Ort: Tranås (Jönköping)

Re: Optoingångar

Inlägg av FormerMazda »

Precis som med inbrottsskydd, man kan bara skydda sig till viss del.
Lås och larm stoppar buset och pundarna, medan mot ett riktat inbrott är det bara att städa efteråt.

Så vi kan summera med att detta skydd kommer duga åt mig.
Jag går all in och beställer alla komponenter på en gång, den blir det tillverkning, kul att löda lite också. :)

Uppdaterar status här i tråden.
FormerMazda
Inlägg: 6061
Blev medlem: 27 februari 2006, 14:59:36
Ort: Tranås (Jönköping)

Re: Optoingångar

Inlägg av FormerMazda »

Tro det eller ej, men kretsen funkar!
Eller ja, den funkar på så vis att duttar man ingången mot jord så sänker den så snyggt signalen till noll.
Och matar jag ingången med +32V (max labagg) så klampar den signalen till uC till runt 5V.

Så jag ska bara lösa en kompakt layout med kretskort.
Användarvisningsbild
Icecap
Inlägg: 26093
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Optoingångar

Inlägg av Icecap »

Bra!
Och det ska ju vara så också.
FormerMazda
Inlägg: 6061
Blev medlem: 27 februari 2006, 14:59:36
Ort: Tranås (Jönköping)

Re: Optoingångar

Inlägg av FormerMazda »

Då var monstrositeten byggd då, vet inte varför jag envisades med en kompakt kombo av skatbo och kretskort, men såhär blev den.
På de yttersta tomma paddarna ska kabel lödas in och dras till skruvplint för yttre anslutning av "riktig" kabel sen, allt ska sitta på DIN-skena i ett skåp, så det ska byggas mekanisk stabilt. Sen. :)

Men det funkar, alla ingångar går höga och kan sänkas genom att dra padden till GND. Totalt 32 ingångar, dessa ska man kunna läsa status på via modbus över RS485.
Funderar löst på om jag ska ta in nåt mer i denna, några analoga signaler eller DHT22 eller liknande. Men nja. Vet inte till vad jag skulle ha det.

Jag hade hellre designeat ett kretskort med IDC-kontakt och skruvplint på PCBt direkt. Sen bara flatkabel mellan arduino och det kortet. Kanske tagit med nån LED-indikering också.
Men då ska det ritas upp och beställas PCB med mera, det här löste jag här och nu, nästan gratis. Så det får duga.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
FormerMazda
Inlägg: 6061
Blev medlem: 27 februari 2006, 14:59:36
Ort: Tranås (Jönköping)

Re: Optoingångar

Inlägg av FormerMazda »

Nu är faktiskt hela modulen klar som denna monstrositet är en del av! :D
Tyckte den kunde få lite mer features, så det fick den.

Mekanisk är den ganska stabil faktiskt, men jo, helst hade jag fixat ett riktigt PCB och en låda.
Men det har jag varken kunskap eller nästan ens lust med. Nu. Kanske blir i framtiden?

Så på en basplatta med DIN-skenefäste sitter nu:
Plint in 24VDC
Plint ut 5VDC
Plintar ingångar, 32st samt anslutning 3st DHT22
Arduino MEGA 2560
DC-DC stepdown (24V till 5V)
TTL-RS845
4x20 LCD för att .. kul att se nåt.

Arduinon har ett program som i sin enkelhet scannar av ingångarna, läser av DHTerna, räknar ut daggpunkten på det, och slänger ut alltsammans på modbus och display.

Slänger in koden som snurrar i Arduinon, den är i mångas ögon garanterat inte snygg, men den funkar och därmed duger den. :D Lite som en annan.
Synpunkter tas gärna emot ändå. :) På koden då.

En ny funktion jag fann i samband med detta var TimedAction, i princip en funktion för att starta funktioner på intervall.
Skulle jag läst av DHT i LOOPen så tröttnar de flesta modbus-scanningarna då Arduinon slutar svara en liten stund varje gång, nu kör den funktionen med 2s intervall och då stör den inte.
Tappar typ 5 svar på 1200 med 1s intervall på frågningen. Går säkert att förbättra, men, hur var det nu, det duger!

Strömförbrukning vid 24V matning är 58mA, förbrukar 1,4W totalt med tänd display och allt. Det får den.

Programmet:

Kod: Markera allt

#include <Modbusino.h>    //Modbusservern - OBS! Hackat bibliotek, Modbusino.cpp Sök&Ersätt Serial. -> Serial3.
#include "DHT.h"          //DHT bibliotek för läsning givare
#include <TimedAction.h>  //För att köra funktioner vid vissa intervall, inte i loop-fart
#include <LiquidCrystal.h>//Displaybibliotek

const int rs = 13, en = 12, d4 = 11, d5 = 10, d6 = 9, d7 = 8; //Definiera displaypinnar
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);//Definiera displaypinnar

#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

ModbusinoSlave modbusino_slave(100); // Sätt upp modbus på ID 100
DHT dht1(4, DHTTYPE);//DHT1 på pin 4
DHT dht2(3, DHTTYPE);//DHT2 på pin 3
DHT dht3(2, DHTTYPE);//DHT3 på pin 2

float h1, h2, h3, t1, t2, t3, dp1, dp2, dp3; //humidity, temp, dewpoint
uint16_t ih1, ih2, ih3, it1, it2, it3, idp1, idp2, idp3; //Som ovan, men sen i x10 för modbus
uint16_t Holdingreg[15]; //Antal register
uint16_t DigIn1=0, DigIn2=0; //Två 16bitars för status ingångar
String sLine1, sLine2, sLine3, sLine4; //För Displayens rader
byte bState; // Ingången status

//** Läser av DHT fukt och temp. Beräknar daggpunkt. Lägg i INTs x 10 för modbus
void ReadSensors() {
  h1 = dht1.readHumidity();
  h2 = dht2.readHumidity();
  h3 = dht3.readHumidity();
  t1 = dht1.readTemperature();
  t2 = dht2.readTemperature();
  t3 = dht3.readTemperature();
  dp1 = calcDewpoint(h1, t1); dp2 = calcDewpoint(h2, t2); dp3 = calcDewpoint(h3, t3);
  ih1 = h1 * 10; ih2 = h2 * 10; ih3 = h3 * 10;
  it1 = t1 * 10; it2 = t2 * 10; it3 = t3 * 10;
  idp1 = dp1 * 10; idp2 = dp2 * 10; idp3 = dp3 * 10;
}

//** Kod till calcDewpoint kopierad rakt av från nätet, enheter °C och RH%
float calcDewpoint(float humi, float temp) {
  float k;
  k = log(humi/100) + (17.62 * temp) / (243.12 + temp);
  return 243.12 * k / (17.62 - k);
}

TimedAction ReadSensorsThread = TimedAction(2000,ReadSensors);//** Kör ReadSensors var 2 sekunder
TimedAction UpdateDispThread  = TimedAction(1000,UpdateDisp);//** Kör UpdateDisp var 1 sekunder

void setup() {
  
  modbusino_slave.setup(19200); //Kör modbus i 19200bps
  dht1.begin();
  dht2.begin();
  dht3.begin();
  lcd.begin(20, 4);
  // Input 22-53 som 32st digitala in
  for (int i = 22; i <= 53; i++) {
    pinMode(i, INPUT_PULLUP); //input
  }  
}

void loop() {
  
  ReadSensorsThread.check(); //Kollar om sensors ska läsas
  UpdateDispThread.check(); //Kollar om display ska uppdateras

  Holdingreg[1] = it1; Holdingreg[2] = it2; Holdingreg[3] = it3; //Stoppa ner temp
  Holdingreg[4] = ih1; Holdingreg[5] = ih2; Holdingreg[6] = ih3; //Stoppa ner fukt
  Holdingreg[7] = idp1; Holdingreg[8] = idp2; Holdingreg[9] = idp3; //Stoppa ner daggpunkt
  Holdingreg[11] = DigIn1; Holdingreg[12] = DigIn2; //Stoppa ner inputstatus som 16bit int

  modbusino_slave.loop(Holdingreg, 15); //Skriv ner värden

  ReadInputs(); //Läs inputs

}

void ReadInputs() {
  for (int scan = 22; scan <= 53; scan++) { //Inputs på DI 22 till 52 = 32st
    bState = digitalRead(scan);
    if (scan < 38) { bitWrite(DigIn1, scan-22, bState); }; //DI 22 till 37 = INT DigIn1
    if (scan > 37) { bitWrite(DigIn2, scan-38, bState); }; //DI 38 till 52 = INT DigIn2
  }    
}

void UpdateDisp() {
  sLine1 = "";sLine2 = "";sLine3 = "";sLine4 = ""; //Töm strängarna
  for (int scan1 = 0; scan1 <=15; scan1++) {
    sLine1 = sLine1 + bitRead(DigIn1, scan1); //Maska ut bitarna ur inten, bygg på strängen
    sLine2 = sLine2 + bitRead(DigIn2, scan1); //Maska ut bitarna ur inten, bygg på strängen
  }
  sLine3 = "Temp:" + String(t1,1) + " " + String(t2,1) + " " + String(t3,1) + " ";
  sLine4 = "Fukt:" + String(h1,1) + " " + String(h2,1) + " " + String(h3,1) + " ";
  lcd.setCursor(0, 0); lcd.print(sLine1);
  lcd.setCursor(0, 1); lcd.print(sLine2);
  lcd.setCursor(0, 2); lcd.print(sLine3);
  lcd.setCursor(0, 3); lcd.print(sLine4);
  
}
Skatboet:
20220309_155917.jpg
Skatboet annan vinkel:
20220309_155938.jpg
Urklipp ur ModScan, temp, fukt och daggpunkt är x10. Tyvärr får man välja att visa signed, unsigned eller bit eller så på alla värden. Så därför ser daggpunkt tokigt ut..
modbus.jpg
Edit: var visst fel version av programmet, uppdaterat. Edit igen, fel post! Återställt! :D
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Senast redigerad av FormerMazda 25 maj 2022, 14:08:40, redigerad totalt 2 gånger.
FormerMazda
Inlägg: 6061
Blev medlem: 27 februari 2006, 14:59:36
Ort: Tranås (Jönköping)

Re: Optoingångar

Inlägg av FormerMazda »

Tänkte uppdatera den här tråden lite, för när jag lekt en stund med SAIA-noderna ( EF-tråd ) så kunde jag inte släppa att det vore snyggare att ha dom på nåt vis istället för den .. kreativa ingångsmodulen jag byggde innan.

Så sagt och gjort, SAIA-modulerna byggdes om lite, och med endast 3 kontroll pinnar så får jag tillbaka 4 svar. Kalla svaren som om ingång 0-7 eller 8-15 är hög på modulen, och det är två moduler så därför 4 svar
Lite arduino-kod och test visade att det var precis så enkelt!

Släppte jag loopen lös i en MEGA2560 där koden skannar av alla ingångar och drar en utågång motsvarande en ingång så såg jag en fördröjning på 1.8ms mellan förändring på ingång och utgång.
Duger för att övervaka fönster tycker jag. :D
Jo, just den övningen var meningslös, men jag var nyfiken.

Den vackra ardunio-modulen byggdes om och SAIA-modulerna anslöts. Koden ändrades och utan kompileringsfel och på första försöket gick det igång!

Kod: Markera allt

#include <Modbusino.h>    //Modbusservern - OBS! Hackat bibliotek, Modbusino.cpp Sök&Ersätt Serial. -> Serial3.
#include "DHT.h"          //DHT bibliotek för läsning givare
#include <TimedAction.h>  //För att köra funktioner vid vissa intervall, inte i loop-fart
#include <LiquidCrystal.h>//Displaybibliotek
 
const int rs = 13, en = 12, d4 = 11, d5 = 10, d6 = 9, d7 = 8; //Definiera displaypinnar
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);//Definiera displaypinnar

#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

ModbusinoSlave modbusino_slave(100); // Sätt upp modbus på ID 100

DHT dht1(4, DHTTYPE);//DHT1 på pin 4
DHT dht2(3, DHTTYPE);//DHT2 på pin 3
DHT dht3(2, DHTTYPE);//DHT3 på pin 2

float h1, h2, h3, t1, t2, t3, dp1, dp2, dp3; //humidity, temp, dewpoint
uint16_t ih1, ih2, ih3, it1, it2, it3, idp1, idp2, idp3; //Som ovan, men sen i x10 för modbus
uint16_t Holdingreg[15]; //Antal register
uint16_t DigIn1 = 0, DigIn2 = 0; //Två 16bitars för status ingångar
String sLine1, sLine2, sLine3, sLine4; //För Displayens rader
int ctrl1 = 50, ctrl2 = 48, ctrl3 = 52; //Kontrollpinne I/O-moduler
int svar1 = 40; //Modul 1 låg 0-7
int svar2 = 42; //Modul 1 hög 8-15
int svar3 = 44; //Modul 2 låg 0-7
int svar4 = 46; //Modul 2 hög 8-15
bool ioA[16], ioB[16]; //I/O-modulers inputstatus

//** Läser av DHT fukt och temp. Beräknar daggpunkt. Lägg i INTs x 10 för modbus
void ReadSensors() {
  h1 = dht1.readHumidity();
  h2 = dht2.readHumidity();
  h3 = dht3.readHumidity();
  t1 = dht1.readTemperature();
  t2 = dht2.readTemperature();
  t3 = dht3.readTemperature();
  dp1 = calcDewpoint(h1, t1); dp2 = calcDewpoint(h2, t2); dp3 = calcDewpoint(h3, t3);
  ih1 = h1 * 10; ih2 = h2 * 10; ih3 = h3 * 10;
  it1 = t1 * 10; it2 = t2 * 10; it3 = t3 * 10;
  idp1 = dp1 * 10; idp2 = dp2 * 10; idp3 = dp3 * 10;
}

//** Kod till calcDewpoint kopierad rakt av från nätet, enheter °C och RH%
float calcDewpoint(float humi, float temp) {
  float k;
  k = log(humi / 100) + (17.62 * temp) / (243.12 + temp);
  return 243.12 * k / (17.62 - k);
}

TimedAction ReadSensorsThread = TimedAction(2000, ReadSensors); //** Kör ReadSensors var 2 sekunder
TimedAction UpdateDispThread  = TimedAction(1000, UpdateDisp); //** Kör UpdateDisp var 1 sekunder

void setup() {
  modbusino_slave.setup(19200); //Kör modbus i 19200bps
  dht1.begin();
  dht2.begin();
  dht3.begin();
  lcd.begin(20, 4);
  pinMode(ctrl1, OUTPUT); pinMode(ctrl2, OUTPUT); pinMode(ctrl3, OUTPUT);
  pinMode(svar1, INPUT); pinMode(svar2, INPUT); pinMode(svar3, INPUT); pinMode(svar4, INPUT);
}

void loop() {
  ReadSensorsThread.check(); //Kollar om sensors ska läsas
  UpdateDispThread.check(); //Kollar om display ska uppdateras

  Holdingreg[1] = it1; Holdingreg[2] = it2; Holdingreg[3] = it3; //Stoppa ner temp
  Holdingreg[4] = ih1; Holdingreg[5] = ih2; Holdingreg[6] = ih3; //Stoppa ner fukt
  Holdingreg[7] = idp1; Holdingreg[8] = idp2; Holdingreg[9] = idp3; //Stoppa ner daggpunkt
  Holdingreg[11] = DigIn1; Holdingreg[12] = DigIn2; //Stoppa ner inputstatus som 16bit int

  modbusino_slave.loop(Holdingreg, 15); //Skriv ner värden

  ReadInputs(); //Läs inputs
}

void ReadInputs() {

  for (int i = 0; i <= 7; i++) {
    controlNodes(i); //Sätt 3 bitar för läsning
    readNodes(i); //Läs av status på ingångar
  }

  for (int scan = 0; scan <= 15; scan++) {
    bitWrite(DigIn1, scan, ioA[scan]); //Sätt bit i register efter aktiv ingång
    bitWrite(DigIn2, scan, ioB[scan]); //Sätt bit i register efter aktiv ingång
  }
}

void controlNodes(int decin) {
  digitalWrite(ctrl1, bitRead(decin, 2));
  digitalWrite(ctrl2, bitRead(decin, 1));
  digitalWrite(ctrl3, bitRead(decin, 0));
}

void readNodes(int nr) {
  int out1 = digitalRead(svar1); //Modul 1 låg 0-7
  int out2 = digitalRead(svar2); //Modul 1 hög 8-15
  int out3 = digitalRead(svar3); //Modul 2 låg 0-7
  int out4 = digitalRead(svar4); //Modul 2 hög 8-15

  if (out1 == 0) { ioA[nr] = 1; } else { ioA[nr] = 0; }
  if (out2 == 0) { ioA[nr + 8] = 1; } else { ioA[nr + 8] = 0; }
  if (out3 == 0) { ioB[nr] = 1; } else { ioB[nr] = 0; }
  if (out4 == 0) { ioB[nr + 8] = 1; } else { ioB[nr + 8] = 0; }
}

void UpdateDisp() {
  sLine1 = ""; sLine2 = ""; sLine3 = ""; sLine4 = ""; //Töm strängarna
  for (int scan1 = 0; scan1 <= 15; scan1++) {
    sLine1 = sLine1 + bitRead(DigIn1, scan1); //Maska ut bitarna ur inten, bygg på strängen
    sLine2 = sLine2 + bitRead(DigIn2, scan1); //Maska ut bitarna ur inten, bygg på strängen
  }

  sLine3 = "Temp:" + String(t1, 1) + " " + String(t2, 1) + " " + String(t3, 1) + " ";
  sLine4 = "Fukt:" + String(h1, 1) + " " + String(h2, 1) + " " + String(h3, 1) + " ";
  lcd.setCursor(0, 0); lcd.print(sLine1);
  lcd.setCursor(0, 1); lcd.print(sLine2);
  lcd.setCursor(0, 2); lcd.print(sLine3);
  lcd.setCursor(0, 3); lcd.print(sLine4);
}
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Skriv svar