Hallo zusammen,
im rahmen meines techniker abschluss projektes binden wir einen arduino one an eine SPS mithilfe von Snap7 und einem shield an.
Die LED sind verdrahtet und und eine platine mit widerständen wurde gelötet. Das Problem ist, dass immer nur ein Pin angesteuert wird. Es ist hier immer der erste definierte pin der dann ein Signal weitergibt.
Die anderen 3 pins werden nicht angesteuert.
wenn ich die pins wechsel, dann leuchten die led, also jede einzelne verbindung funktioniert.
Ich frage mich ob das Programm mit der Snap 7 anbindung zu groß ist und wir auf einen Mega gehen müssen.
Hat damit vielleicht jemand erfahrung?
Hier das Programm, ist von der funktion noch nicht final.
#include <Ethernet.h>
#include "Settimino.h"
#include <Adafruit_NeoPixel.h>
// ---------- Netzwerk ----------
byte mac[] = { 0xA8, 0x61, 0x0A, 0xAE, 0x3A, 0xE2 };
IPAddress ipArduino(192,168,0,3);
IPAddress ipPLC(192,168,0,1);
IPAddress dns(0,0,0,0), gw(0,0,0,0), mask(255,255,255,0);
S7Client Client;
// ---------- LED-Hardware ----------
#define PIN_STRIP_1 2
#define PIN_STRIP_2 3
#define PIN_STRIP_3 4
#define PIN_STRIP_4 5
const uint8_t STRIPS = 4;
// 134 LEDs aktiv + 1 LED Offset = 135 Puffer
const uint16_t NUM_LEDS_MAX = 135;
Adafruit_NeoPixel strip[STRIPS] = {
Adafruit_NeoPixel(NUM_LEDS_MAX, PIN_STRIP_1, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS_MAX, PIN_STRIP_2, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS_MAX, PIN_STRIP_3, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS_MAX, PIN_STRIP_4, NEO_GRB + NEO_KHZ800)
};
// reale Längen je Band
uint16_t activeLen[STRIPS] = { 134, 58, 58, 58 };
// erste physische LED (Index 0) bleibt unbenutzt
const uint8_t LED_OFFSET = 1;
// ---------- PLC Offsets ----------
const int DB_NUM = 10;
// SPS -> Arduino
const int OFF_SELECTED_MODE = 2; // BYTE
const int OFF_TEST_ENABLE_B = 3; // BYTE (Bit0 = Test)
const int OFF_TEST_STRIP = 4; // BYTE (0 = alle, 1..4 = Strip)
const int OFF_TEST_R = 5; // BYTE
const int OFF_TEST_G = 6; // BYTE
const int OFF_TEST_B = 7; // BYTE
const int OFF_TEST_BRIGHT = 8; // BYTE (0 = Default)
// Arduino -> SPS
const int OFF_STATE_BYTE20 = 20; // BYTE (Bit0=Ready, Bit1=Error)
const int OFF_ERROR_CODE = 22; // INT
const int OFF_HEARTBEAT = 24; // WORD
// Bereich 0..18
const int BYTES_TO_READ = 19;
// ---------- Mode Bits ----------
#define SM_STOERUNG 0x01
#define SM_HAND 0x20
#define SM_AUTO 0x40
// ---------- Laufzeit ----------
uint32_t tAnim=0, tRead=0, tState=0;
uint8_t selectedMode = 0;
bool testEnable=false;
uint8_t testStrip=0;
uint8_t testR=255, testG=255, testB=255;
uint8_t testBright=0;
bool ardReady=false, ardError=false;
int16_t ardErrCode=0;
uint16_t ardHeartbeat=0;
const uint8_t DEFAULT_BRIGHTNESS = 80;
// ---------- Helpers ----------
static inline uint32_t C(uint8_t r,uint8_t g,uint8_t b){
return ((uint32_t)r<<16)|((uint32_t)g<<8)|b;
}
static inline void setPix(uint8_t s, uint16_t logicalIdx, uint32_t col){
if(s>=STRIPS) return;
if(logicalIdx>=activeLen[s]) return;
uint16_t physIdx = logicalIdx + LED_OFFSET;
if(physIdx>=NUM_LEDS_MAX) return;
strip[s].setPixelColor(physIdx, col);
}
static void setAll(uint32_t col){
for(uint8_t s=0;s<STRIPS;s++){
for(uint16_t i=0;i<activeLen[s];i++) setPix(s,i,col);
}
}
static float breathe01(uint32_t t,uint16_t per){
float x=(t%per)/(float)per;
return (sin(x*2*PI)+1.0f)*0.5f;
}
static float breatheScaled(uint32_t t,uint16_t per,float low,float high){
float f=breathe01(t,per);
return low + f*(high-low);
}
static void fillStripSolid(uint8_t s,uint32_t col){
for(uint16_t i=0;i<activeLen[s];i++) setPix(s,i,col);
}
static void fillStripBreatheScaled(uint8_t s,uint32_t baseCol,uint32_t now){
float f=breatheScaled(now,2000,0.40f,1.00f);
uint8_t r=(uint8_t)(((baseCol>>16)&0xFF)*f);
uint8_t g=(uint8_t)(((baseCol>>8 )&0xFF)*f);
uint8_t b=(uint8_t)(( baseCol &0xFF)*f);
fillStripSolid(s,C(r,g,b));
}
static void fillStripChase(uint8_t s,uint32_t col,uint32_t now){
if(activeLen[s]==0) return;
uint8_t phase=(now/100)%activeLen[s];
for(uint16_t i=0;i<activeLen[s];i++){
bool on=((i+phase)%6)==0;
setPix(s,i,on?col:0);
}
}
// ---------- PLC Lesen ----------
uint8_t dbBuf[BYTES_TO_READ];
static void pollPLC(){
if(!Client.Connected){
Client.Disconnect();
if(Client.ConnectTo(ipPLC,0,1)!=0){
ardError=true; ardErrCode=11;
return;
}
}
int rc=Client.ReadArea(S7AreaDB, DB_NUM, 0, BYTES_TO_READ, S7WLByte, dbBuf);
if(rc!=0){
ardError=true; ardErrCode=12;
return;
}
selectedMode = dbBuf[OFF_SELECTED_MODE];
testEnable = (dbBuf[OFF_TEST_ENABLE_B] & 0x01)!=0;
testStrip = dbBuf[OFF_TEST_STRIP];
testR = dbBuf[OFF_TEST_R];
testG = dbBuf[OFF_TEST_G];
testB = dbBuf[OFF_TEST_B];
testBright = dbBuf[OFF_TEST_BRIGHT];
// Helligkeit
uint8_t effB = (testBright > 0) ? testBright : DEFAULT_BRIGHTNESS;
for(uint8_t s=0;s<STRIPS;s++) strip[s].setBrightness(effB);
ardError=false;
ardErrCode=0;
}
// ---------- PLC Schreiben ----------
static void pushStateToPLC(){
uint8_t state=0;
if(ardReady) state|=1<<0;
if(ardError) state|=1<<1;
Client.WriteArea(S7AreaDB,DB_NUM,OFF_STATE_BYTE20,1,S7WLByte,&state);
uint8_t wb[2];
S7.SetIntAt(wb,0,ardErrCode);
Client.WriteArea(S7AreaDB,DB_NUM,OFF_ERROR_CODE,2,S7WLByte,wb);
ardHeartbeat++;
uint8_t hb[2];
S7.SetWordAt(hb,0,ardHeartbeat);
Client.WriteArea(S7AreaDB,DB_NUM,OFF_HEARTBEAT,2,S7WLByte,hb);
}
// ---------- Rendering: Test ----------
static void renderTEST(){
uint32_t c=C(testR,testG,testB);
if(testStrip==0){
// alle Strips
for(uint8_t s=0;s<STRIPS;s++){
fillStripSolid(s,c);
}
} else if(testStrip>=1 && testStrip<=STRIPS){
uint8_t s=testStrip-1;
fillStripSolid(s,c);
}
}
// ---------- Rendering: Auto ----------
static void renderAUTO(uint32_t now){
for(uint8_t s=0;s<STRIPS;s++){
// grünes Atmen
fillStripBreatheScaled(s,C(0,200,0),now);
}
}
// ---------- Rendering: Hand ----------
static void renderHAND(uint32_t now){
for(uint8_t s=0;s<STRIPS;s++){
// warmes Orange atmen
fillStripBreatheScaled(s,C(255,180,40),now);
// weißes Lauflicht
fillStripChase(s,C(255,255,255),now);
}
}
// ---------- Rendering: Störung ----------
static void renderFAULT(uint32_t now){
uint8_t v = (uint8_t)(breatheScaled(now,900,0.1f,1.0f)*255);
for(uint8_t s=0;s<STRIPS;s++){
for(uint16_t i=0;i<activeLen[s];i++){
setPix(s,i,C(v,0,0));
}
}
}
// ---------- Rendering: alles aus ----------
static void renderOFF(){
setAll(0);
}
// ---------- Setup ----------
void setup(){
Serial.begin(115200);
while(!Serial){;}
Ethernet.init(10);
Ethernet.begin(mac,ipArduino,dns,gw,mask);
delay(400);
for(uint8_t s=0;s<STRIPS;s++){
strip[s].begin();
strip[s].setBrightness(DEFAULT_BRIGHTNESS);
strip[s].setPixelColor(0,0); // erste LED sicher aus
strip[s].show();
}
int cr=Client.ConnectTo(ipPLC,0,1);
if(cr==0){
ardReady=true;
ardError=false;
} else {
ardReady=false;
ardError=true;
ardErrCode=10;
}
}
// ---------- Loop ----------
void loop(){
uint32_t now=millis();
// PLC lesen
if(now - tRead >= 100){
tRead=now;
pollPLC();
}
// LED-Animation
if(now - tAnim >= 15){
tAnim=now;
if(testEnable){
// Testmodus hat Vorrang
setAll(0);
renderTEST();
} else {
bool isStoer = (selectedMode & SM_STOERUNG)!=0;
bool isHand = (selectedMode & SM_HAND)!=0;
bool isAuto = (selectedMode & SM_AUTO)!=0;
if(isStoer) renderFAULT(now);
else if(isHand) renderHAND(now);
else if(isAuto) renderAUTO(now);
else renderOFF();
}
// erste physische LED immer AUS – verhindert Flackern
for(uint8_t s=0;s<STRIPS;s++){
strip[s].setPixelColor(0,0);
strip[s].show();
}
}
// Status zur SPS
if(now - tState >= 500){
tState=now;
pushStateToPLC();
}
}
tippe oder füge den Code hier ein
tippe oder füge den Code hier ein