Skip to content

Commit db3686d

Browse files
Added code
1 parent febf249 commit db3686d

File tree

1 file changed

+254
-6
lines changed

1 file changed

+254
-6
lines changed

content/hardware/02.hero/shields/spe-shield/tutorials/getting-started/spe-getting-started.md

Lines changed: 254 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -387,12 +387,101 @@ The architecture consists of three layers: a central control node that issues co
387387

388388
### Central Control Node (Server)
389389

390-
The central control node (Node 7) acts as the command center of the system, sending LED control commands to specific Opta boards through their associated gateway nodes. Operating on the SPE network, this node provides a simple serial interface where operators can type commands like "LED 3" to toggle specific LEDs on remote Optas.
390+
The central control node (Node 7) acts as the command center of the system, sending LED control commands to specific Opta boards through their associated gateway nodes. Operating on the SPE network, this node provides a simple serial interface where operators can type commands like "LED 3" to toggle the LEDs on remote Optas.
391391

392392
![Central SPE Controller](assets/SPE-rs485-transducer-main.png)
393393

394394
```arduino
395-
work in progress
395+
// SPE Server Node 7 - Sends LED commands
396+
#include <Arduino_10BASE_T1S.h>
397+
#include <SPI.h>
398+
399+
const uint8_t MY_ID = 7; // Server is node 7
400+
401+
// Network setup
402+
IPAddress myIP(192, 168, 42, 100 + MY_ID);
403+
IPAddress netmask(255, 255, 255, 0);
404+
IPAddress gateway(192, 168, 42, 100);
405+
406+
TC6::TC6_Io* io;
407+
TC6::TC6_Arduino_10BASE_T1S* network;
408+
Arduino_10BASE_T1S_UDP* udp;
409+
410+
void setup() {
411+
Serial.begin(115200);
412+
delay(1000);
413+
414+
Serial.println("\n=== SPE LED Control Server ===");
415+
Serial.println("Commands:");
416+
Serial.println(" LED 0 - Toggle LED on Opta at node 0");
417+
Serial.println(" LED 1 - Toggle LED on Opta at node 1");
418+
Serial.println(" (etc. for other nodes)");
419+
Serial.println("\nType command and press Enter\n");
420+
421+
// Initialize hardware
422+
io = new TC6::TC6_Io(SPI, CS_PIN, RESET_PIN, IRQ_PIN);
423+
network = new TC6::TC6_Arduino_10BASE_T1S(io);
424+
udp = new Arduino_10BASE_T1S_UDP();
425+
426+
pinMode(IRQ_PIN, INPUT_PULLUP);
427+
attachInterrupt(digitalPinToInterrupt(IRQ_PIN), []() {
428+
io->onInterrupt();
429+
}, FALLING);
430+
431+
if (!io->begin()) {
432+
Serial.println("IO failed!");
433+
while(1);
434+
}
435+
436+
MacAddress mac = MacAddress::create_from_uid();
437+
T1SPlcaSettings plca(MY_ID);
438+
T1SMacSettings mac_settings;
439+
440+
if (!network->begin(myIP, netmask, gateway, mac, plca, mac_settings)) {
441+
Serial.println("Network failed!");
442+
while(1);
443+
}
444+
445+
network->digitalWrite(TC6::DIO::A0, false);
446+
network->digitalWrite(TC6::DIO::A1, false);
447+
448+
if (!udp->begin(8888)) {
449+
Serial.println("UDP failed!");
450+
while(1);
451+
}
452+
453+
Serial.println("Ready! Enter LED commands:");
454+
}
455+
456+
void loop() {
457+
network->service();
458+
459+
// Check for user commands
460+
if (Serial.available()) {
461+
String cmd = Serial.readStringUntil('\n');
462+
cmd.trim();
463+
cmd.toUpperCase();
464+
465+
// Check if it's a valid LED command
466+
if (cmd.startsWith("LED ")) {
467+
int targetNode = cmd.substring(4).toInt();
468+
469+
// Send to the target node
470+
IPAddress targetIP(192, 168, 42, 100 + targetNode);
471+
472+
udp->beginPacket(targetIP, 8888);
473+
udp->print(cmd);
474+
udp->endPacket();
475+
476+
Serial.print("Sent '");
477+
Serial.print(cmd);
478+
Serial.print("' to node ");
479+
Serial.println(targetNode);
480+
} else {
481+
Serial.println("Invalid command. Use: LED 0, LED 1, etc.");
482+
}
483+
}
484+
}
396485
```
397486

398487
### Transducer Node SPE/RS-485
@@ -401,10 +490,125 @@ The gateway nodes serve as protocol translators between the SPE network and RS-4
401490

402491
![Shields Addressing the Endpoints Across Protocols](assets/SPE-rs485-transducer-transducer.png)
403492

404-
When an Opta board responds via RS-485, the gateway captures the response and sends it back to the central controller as a UDP packet. This bidirectional translation allows transparent communication between the SPE-based control system and RS-485 devices, making it possible to control multiple Opta boards from a single point on the network.
405493

406494
```arduino
407-
In Progress
495+
// SPE/RS-485 Gateway Node - Forwards LED commands to Opta
496+
#include <Arduino_10BASE_T1S.h>
497+
#include <SPI.h>
498+
499+
const uint8_t MY_ID = 0; // Gateway node ID (change for each gateway)
500+
501+
// Network setup
502+
IPAddress myIP(192, 168, 42, 100 + MY_ID);
503+
IPAddress netmask(255, 255, 255, 0);
504+
IPAddress gateway(192, 168, 42, 100);
505+
506+
// RS-485 control pins
507+
#define RS485_DE_PIN 7
508+
#define RS485_RE_PIN 8
509+
510+
TC6::TC6_Io* io;
511+
TC6::TC6_Arduino_10BASE_T1S* network;
512+
Arduino_10BASE_T1S_UDP* udp;
513+
514+
void setup() {
515+
Serial.begin(115200); // USB debug
516+
Serial1.begin(9600); // RS-485 to Opta
517+
delay(1000);
518+
519+
Serial.print("\n=== SPE/RS-485 Gateway Node ");
520+
Serial.print(MY_ID);
521+
Serial.println(" ===");
522+
Serial.println("Forwarding LED commands to Opta");
523+
524+
// Setup RS-485 pins
525+
pinMode(RS485_DE_PIN, OUTPUT);
526+
pinMode(RS485_RE_PIN, OUTPUT);
527+
setTransmitMode(); // We only transmit to Opta
528+
529+
// Initialize SPE network
530+
io = new TC6::TC6_Io(SPI, CS_PIN, RESET_PIN, IRQ_PIN);
531+
network = new TC6::TC6_Arduino_10BASE_T1S(io);
532+
udp = new Arduino_10BASE_T1S_UDP();
533+
534+
pinMode(IRQ_PIN, INPUT_PULLUP);
535+
attachInterrupt(digitalPinToInterrupt(IRQ_PIN), []() {
536+
io->onInterrupt();
537+
}, FALLING);
538+
539+
if (!io->begin()) {
540+
Serial.println("IO failed!");
541+
while(1);
542+
}
543+
544+
MacAddress mac = MacAddress::create_from_uid();
545+
T1SPlcaSettings plca(MY_ID);
546+
T1SMacSettings mac_settings;
547+
548+
if (!network->begin(myIP, netmask, gateway, mac, plca, mac_settings)) {
549+
Serial.println("Network failed!");
550+
while(1);
551+
}
552+
553+
network->digitalWrite(TC6::DIO::A0, false);
554+
network->digitalWrite(TC6::DIO::A1, false);
555+
556+
if (!udp->begin(8888)) {
557+
Serial.println("UDP failed!");
558+
while(1);
559+
}
560+
561+
Serial.println("Gateway ready!");
562+
}
563+
564+
void loop() {
565+
network->service();
566+
567+
// Check for SPE packets
568+
int packetSize = udp->parsePacket();
569+
if (packetSize > 0) {
570+
char buffer[64];
571+
int len = udp->read((byte*)buffer, 63);
572+
buffer[len] = '\0';
573+
574+
String cmd = String(buffer);
575+
cmd.trim();
576+
577+
Serial.print("SPE received: ");
578+
Serial.println(cmd);
579+
580+
// Check if this LED command is for our node
581+
if (cmd.startsWith("LED ")) {
582+
int targetNode = cmd.substring(4).toInt();
583+
if (targetNode == MY_ID) {
584+
sendRS485("T"); // Send 'T' to toggle
585+
Serial.println("Command for this node - sent toggle to Opta");
586+
} else {
587+
Serial.println("Command for different node, ignoring");
588+
}
589+
}
590+
}
591+
}
592+
593+
void setTransmitMode() {
594+
digitalWrite(RS485_RE_PIN, HIGH); // Disable receiver
595+
digitalWrite(RS485_DE_PIN, HIGH); // Enable driver
596+
delay(10);
597+
}
598+
599+
void sendRS485(String msg) {
600+
setTransmitMode();
601+
602+
// Clear any garbage first
603+
while(Serial1.available()) {
604+
Serial1.read();
605+
}
606+
607+
delay(10);
608+
Serial1.println(msg);
609+
Serial1.flush();
610+
delay(10);
611+
}
408612
```
409613

410614
### Opta RS-485 Interface
@@ -413,10 +617,54 @@ The Arduino Opta boards represent the end devices in this system, receiving comm
413617

414618
![Opta as Endpoint](assets/SPE-rs485-transducer-end.png)
415619

416-
When an Opta receives a command, it parses the instruction, performs the requested operation. This simple protocol allows the central SPE controller to remotely monitor and control multiple Opta boards across the RS-485 network, creating a flexible and scalable industrial control system.
620+
When an Opta receives a command, it parses the instruction, performs the requested operation. This simple protocol allows the central SPE controller to remotely monitor and control multiple Opta boards across the RS-485 network, creating a flexible and scalable system.
417621

418622
```arduino
419-
In progress
623+
// Arduino Opta - Toggles built-in LED on command
624+
#include <ArduinoRS485.h>
625+
626+
bool ledState = false;
627+
628+
void setup() {
629+
Serial.begin(115200); // USB debug
630+
delay(2000);
631+
632+
Serial.println("\n=== Opta LED Controller ===");
633+
Serial.println("Toggles built-in LED on command");
634+
635+
// Initialize RS-485 with delays
636+
RS485.begin(9600);
637+
RS485.setDelays(1000, 1000); // Pre and post delays in microseconds
638+
RS485.receive(); // Set to receive mode
639+
640+
// Setup built-in LED
641+
pinMode(LED_BUILTIN, OUTPUT);
642+
digitalWrite(LED_BUILTIN, LOW);
643+
644+
// Flash LED to show ready
645+
for (int i = 0; i < 3; i++) {
646+
digitalWrite(LED_BUILTIN, HIGH);
647+
delay(200);
648+
digitalWrite(LED_BUILTIN, LOW);
649+
delay(200);
650+
}
651+
652+
Serial.println("Ready for commands!");
653+
}
654+
655+
void loop() {
656+
// Read RS-485 character by character
657+
while (RS485.available()) {
658+
char c = RS485.read();
659+
660+
// 0xDE = toggle
661+
if ((byte)c == 0xDE) {
662+
Serial.println("LED Toggle - received");
663+
ledState = !ledState;
664+
digitalWrite(LED_BUILTIN, ledState);
665+
}
666+
}
667+
}
420668
```
421669

422670
## Troubleshooting

0 commit comments

Comments
 (0)