Arduino SBUS lichtmodule

Goedenavond,
Ik ben bezig met een project om via Sbus mijn Radiografische ontvanger uit te lezen. Het is de bedoeling dat ik via een Arduino de divese ledjes op mijn model kan aansturen. nu loop ik tegen het volgende probleem aan..

de ledjes van de achterlichten fungeren tegelijk ook als remlichten. ik stuur ze via PWM aan om een helderheid verschil te creeeren. het remlicht werkt maar zodra ik de code probeer voor het 'half'aansturen van het ledje gaat het mis en krijg ik conflicterende code en gaat het ledje op een verkeerde manier branden. kan iemand mij helpen?
mijn idee is dat met ledstates moet gaan werken maar kan iemand mij een duwtje in de goede richting helpen?

Misschien zal het helpen als je je programma laat zien.



/* ROBOTmaker 28.12.2016
 * This example decodes a Futaba SBUS or compatible stream and convert it to soft switches or PPM.
 * 
 * Thanks goes to https://www.ordinoscope.net/index.php/Electronique/Protocoles/SBUS for the arduino code which was converted to for our use
 * It is based on a verion found  :
 * - https://github.com/zendes/SBUS
 * - http://forum.arduino.cc/index.php?topic=99708.0
 * - https://mbed.org/users/Digixx/notebook/futaba-s-bus-controlled-by-mbed/
 * 
 * There are some inexpensibe SBUS to PPM decoders, such as
 * http://www.hobbyking.com/hobbyking/store/__37953__frsky_4_channel_s_bus_to_pwm_decoder.html
 * This code is more a proof of concept than a real alternative.
 *
 *Further details on our website:
 *http://www.robotmaker.eu/ROBOTmaker/quadcopter-3d-proximity-sensing/sbus-graphical-representation
 *
 * This code uses the RX0 as input. It's not possible to use a software serial port, because
 * there are too many conflicting interrupts between serial input and PWM generation.
 *
 * Since RX0 is also used to communicate with the FTDI, the SBUS must be disconnected while
 * flashing the Arduino.
 *
 * Furthermore, the SBUS uses an inverted serial communication. Why should the Futaba designers of the SBUS make life simple when
 * it's so much fun to make it more difficult? Inverting the signal is easy and can be done with a simple transistor / resistor (see our website) or an inverter:
 * http://www.hobbyking.com/hobbyking/store/__24523__ZYX_S_S_BUS_Connection_Cable.html
 * (the shortest end goes to the receiver, the longest to the Arduino)
 * Alternatively, if you use an X4R you can tap directly into the inverted signal provided on the PCB for a side connector. Details of how to do this are on our website. 
 * See http://www.robotmaker.eu/ROBOTmaker/quadcopter-3d-proximity-sensing/sbus-graphical-representation
 * 
 * The code works on an Arduino Pro Mini. It will probably work on others too, but I haven't tried on other versions yet
 * Ensure to Download the library ->  <SoftwareSerial.h> and <Servo.h> via the Arduino IDE otherwise the code won't compile
 * 
 * 
 * 
 * 
  */
#include <SoftwareSerial.h>
//#include <SoftwareServo.h>
#include <Servo.h>
#include <ezLED.h> // ezLED library
#define RAWR 2
#define RAWL 4
ezLED rawr(RAWR);  // create ezLED object 
ezLED rawl(RAWL);  // create ezLED object 
#define rxPin 19

Servo myservo8;  // create servo object to control a servo
int pos = 0;    // variable to store the servo position
int Brakelight = 0;

//Not used in the Demo
//Servo myservo9;  // create servo object to control a servo 
//Servo myservo10;  // create servo object to control a servo 
//Servo myservo11;  // create servo object to control a servo 
//SoftwareSerial InvertedSerialPort =  SoftwareSerial(rxPin, txPin, true); //(Tx,TX, Inverted mode ping this device uses inverted signaling
//For Piezo Buzzer

//***********************************************************************
//     Setup 
//***********************************************************************
void setup () 
{ 

  //The pins on the Arduino need to be defined. In this demo pin 9-13 are used. Pin 13 is the LED on the Arduino which is 
  //a simple mehod for debugging. The demo turns this on when the Channel 1 (often used for throttle) exceeds a predefined SBUS level. 
     pinMode(2, OUTPUT); //Richtingaanwijzer links
     pinMode(3, OUTPUT); 
     pinMode(4, OUTPUT); //Richtingaanwijzer rechts
     pinMode(5, OUTPUT); //Achteruitrijlicht
     pinMode(6, OUTPUT); //Koplampen
     pinMode(7, OUTPUT); //Remlicht
     pinMode(8, OUTPUT); //achterlicht
     pinMode(9, OUTPUT); //Debug with LED
     pinMode(10, OUTPUT); //Debug with LED
     pinMode(11, OUTPUT); //Debug with LED
     pinMode(12, OUTPUT); //Debug with LED
     pinMode(13, OUTPUT); //Debug with LED
     pinMode(rxPin, INPUT);
     Serial1.begin(100000,SERIAL_8E2); //The SBUS is a non standard baud rate which can be confirmed using an oscilloscope  
     Serial.begin(115200);
     rawr.blink(500, 500); // 500ms ON, 500ms OFF, blink immediately
     rawl.blink(500, 500); // 500ms ON, 500ms OFF, blink immediately
    
     
  }

//***********************************************************************
//     Loop
//***********************************************************************
void loop () 
{
  
  //Declare the variabes
  static byte          buffer[25];
  static int           channels[18];
  static int           errors = 0;
  static bool          failsafe = 0;
  static int           idx;
  static unsigned long last_refresh = 0;
  static int           lost = 0;
  byte b;
  int  i;
  int redPin = 3;
  int greenPin = 5;
  int bluePin = 6;
  word results;

 
  
  
  


 //Check the serial port for incoming data
 //This could also be done via the serialEvent()
  if (Serial1.available ()) {
      b = Serial1.read ();
       
     //this is a new package and it' not zero byte then it's probably the start byte B11110000 (sent MSB)
     //so start reading the 25 byte package
      if (idx == 0 && b != 0x0F) {  // start byte 15?
       // error - wait for the start byte
        
      } else {
        buffer[idx++] = b;  // fill the buffer with the bytes until the end byte B0000000 is recived
      }
   
    if (idx == 25) {  // If we've got 25 bytes then this is a good package so start to decode
      idx = 0;
      if (buffer[24] != 0x00) {
        errors++;
      } else 
      {
            //  Serial.println("Found Packet");
            // 25 byte packet received is little endian. Details of how the package is explained on our website:
            //http://www.robotmaker.eu/ROBOTmaker/quadcopter-3d-proximity-sensing/sbus-graphical-representation
            channels[1]  = ((buffer[1]    |buffer[2]<<8)                 & 0x07FF);
            channels[2]  = ((buffer[2]>>3 |buffer[3]<<5)                 & 0x07FF);
            channels[3]  = ((buffer[3]>>6 |buffer[4]<<2 |buffer[5]<<10)  & 0x07FF);
            channels[4]  = ((buffer[5]>>1 |buffer[6]<<7)                 & 0x07FF);
            channels[5]  = ((buffer[6]>>4 |buffer[7]<<4)                 & 0x07FF);
            channels[6]  = ((buffer[7]>>7 |buffer[8]<<1 |buffer[9]<<9)   & 0x07FF);
            channels[7]  = ((buffer[9]>>2 |buffer[10]<<6)                & 0x07FF);
            channels[8]  = ((buffer[10]>>5|buffer[11]<<3)                & 0x07FF);
            channels[9]  = ((buffer[12]   |buffer[13]<<8)                & 0x07FF);
            channels[10]  = ((buffer[13]>>3|buffer[14]<<5)                & 0x07FF);
            channels[11] = ((buffer[14]>>6|buffer[15]<<2|buffer[16]<<10) & 0x07FF);
            channels[12] = ((buffer[16]>>1|buffer[17]<<7)                & 0x07FF);
            channels[13] = ((buffer[17]>>4|buffer[18]<<4)                & 0x07FF);
            channels[14] = ((buffer[18]>>7|buffer[19]<<1|buffer[20]<<9)  & 0x07FF);
            channels[15] = ((buffer[20]>>2|buffer[21]<<6)                & 0x07FF);
            channels[16] = ((buffer[21]>>5|buffer[22]<<3)                & 0x07FF);
            channels[17] = ((buffer[23])      & 0x0001) ? 2047 : 0;
            channels[18] = ((buffer[23] >> 1) & 0x0001) ? 2047 : 0;
     
            failsafe = ((buffer[23] >> 3) & 0x0001) ? 1 : 0;
            if ((buffer[23] >> 2) & 0x0001) lost++;
            //serialPrint (lost); debg the signals lost

          
            //For this demo, the corresponding channels mapped below need to be also configured on the FrSky Taranis tranmitter accordingly.
            //Any of the Channels can of course be used trigger any of the pins on the Arduino 
            //Channels used in the demo are 5,6,7. Mapped these to the sliders on the transmitter to change RGB LED values
            //Channel 1 set to trigger the Internal Arduino LED on pin 13 once the threshold exceeds 1500
            //Channel 10 needs to be mapped to one of the switches on the Taranis which triggers a buzzer on pin 10 of the Arduino 
            //Channel 1 also triggers a servo connected to pin 8 on the Arduino. So moving the throttle will also move the servo accordingly
            
            
           

        
            //***********************************************************************
            //Turn on right Indicator lights if channel 1 (Steering) moves right.
            //***********************************************************************
             results=channels[1];
              Serial1.write (results);
            if (channels[1] < 400){
               rawr.loop(); // MUST call the led1.loop() function in loop()
              
              Serial.println ("RAW R");
             }
             else 
             {
              digitalWrite(2, LOW);
             }
             
             //***********************************************************************
            //Turn on left Indicator lights if channel 1 (Steering) moves left.
            //***********************************************************************
             results=channels[1];
              Serial1.write (results);
            if (channels[1] > 1800){
              
              rawl.loop(); // MUST call the led1.loop() function in loop()
              Serial.println ("RAW L");
             }
             else 
             {
              digitalWrite(4, LOW);
             }
 //***********************************************************************
           /* / //Turn on hazard lights if channel 11 exceeds 1500
            //***********************************************************************
             results=channels[1];
              Serial1.write (results);
            if (channels[11] > 1800){
              
              rawl.loop(); // MUST call the led1.loop() function in loop()
              rawl.loop(); // MUST call the led1.loop() function in loop()
              Serial.println ("RAW hazard");
             }
             if (channels[11] < 1000){
              
              rawl.cancel(); // MUST call the led1.loop() function in loop()
              rawl.cancel(); // MUST call the led1.loop() function in loop()
             
             }
             */

               //***********************************************************************
            //Brake lights channel 2 .
            //***********************************************************************
             results=channels[1];
              Serial1.write (results);
            if ((channels[2] >=970) && (channels[2] <=1010)) {
              
              digitalWrite(7, HIGH);
              Serial.println ("Brake light");
             }
             else 
             digitalWrite(7, LOW);
             {
              
             }

              //***********************************************************************
            //Back up lights channel 2 .
            //***********************************************************************
             results=channels[1];
              Serial1.write (results);
            if (channels[2] <970) {
              
              digitalWrite(5, HIGH);
              Serial.println ("Back up light");
             }
             else 
             {
              digitalWrite(5, LOW);
             }

              //***********************************************************************
            //head and tail lights Channel 6
            //***********************************************************************
             results=channels[1];
              Serial1.write (results);
            if (channels[6] > 1800){
              
             analogWrite(6, 100);
             analogWrite(8, 100);
              
              Serial.println ("head and tail light");
             }
             else 
             {
              digitalWrite(6, LOW);
              digitalWrite(8, LOW);
              
             }
            
            
             
             
             
             //*********************************************************************** 
             //Drive a Servo connected to channel 1 (which is mapped to thrust if you are using Mode 2) 
             //Servo connected to pin 8 on the Arduino
             //***********************************************************************  
               
    
              //***********************************************************************
              //Turn on or off a buzzer. Channel 10 is mapped to switch SH.
              // Buzzer connected to pin 10 on Arduino
              //***********************************************************************
              //if (channels[10] > 1500){
              //    digitalWrite(10, HIGH);  
              //   }
              // else 
              //   {
              //    digitalWrite(10, LOW); 
              // }
          } //closing - else
      } //closing - if (idx == 25)
    } //closing - if (Serial.available ())
} //closing void loop

wat ik nu heb gedaan is dezelfde led aan pin 7 en 8 verbonden om het gewenste effect te krijgen, pin 7 laat de led op volle sterkte branden en pin 7 op een veel lagere sterkte. zonder dat de code storing geeft

Tenzij je een serie weerstand op beide pinnen hebt denk ik dat dat een ongezonde oplossing is die je uiteindelijk je Arduino kan kosten. Je kunt een kortsluiting veroorzaken tussen die twee pinnen; als een pin hoog is en de andere laag (of omgekeerd) loopt er een (theoretisch) onbeperkte stroom.

Ik kan zien waar je beschreven probleem vandaan komt, je hebt twee kanalen die het achterlicht aansturen en die kunnen een conflict hebben. Ik zal proberen daar aan te werken.

Volgens mij kan deze tijdelijke oplossing geen schade veroorzaken omdat alle kanalen die ik gebruik achter een ULN2803A (transistor array) zitten

Heel erg bedankt dat u mij hiermee wilt helpen.

er zijn een aantal pinnen die PWM sturen en er is een manier om met je code ook iets te laten dimmen wel opletten dat je de timers die je gebruikt in je sbus niet dubbel gebruikt

Hieronder een mogelijke oplossing.

In plaats van het activaren van de remlichten als je het commando ontvangt houd je alleen bij of derem lichten geactiveerd moeten worden. Ik gebruik daarvoor een bool in loop()

void loop()
{
  // sterretje
  bool breakOn = false;
  ...
  ...
}

Als je nu het commando ontvangt voor de remlichten, zet je die variabele true of false maar je doet verder niks met de achterlichten

        //***********************************************************************
        //Brake lights channel 2 .
        //***********************************************************************
        results = channels[1];
        Serial1.write(results);
        if ((channels[2] >= 970) && (channels[2] <= 1010))
        {
          // sterretje
          breakOn = true;
          //digitalWrite(7, HIGH);
          Serial.println("Brake light");
        }
        else
        {
          // sterretje
          breakOn = false;
          //digitalWrite(7, LOW);
        }

Nu kun je bij het in/uit schakelen van de koplampen en de achterlichten bepalen wat er moet gebeuren met de achterlichten.

        //***********************************************************************
        //head and tail lights Channel 6
        //***********************************************************************
        results = channels[1];
        Serial1.write(results);
        if (channels[6] > 1800)
        {
          // head lights on
          analogWrite(6, 100);
          Serial.println("head and tail light");
          // sterretje
          // not breaking
          if (breakOn == false)
          {
            // tail lights on
            analogWrite(8, 100);
          }
          // breaking
          else
          {
            // tail lights bright
            digitalWrite(8, HIGH);
          }
        }
        else
        {
          // head lights off
          digitalWrite(6, LOW);
          // sterretje
          // not breaking
          if (breakOn == false)
          {
            // tail lights off
            digitalWrite(8, LOW);
          }
          // breaking
          else
          {
            // tail lights bright
            digitalWrite(8, HIGH);
          }
        }

Ik weet niets van de Futuba SBUS; programma compileert maar ik kan het niet testen.

Nadat je het bovenstaande getest hebt, een opmerking. Je gebruikt magische nummers voor de pinnen. Dat is niet zo handig:

  1. Als je b.v. een pin wilt wijzigen moet je dat op verschillen plekken doen en er is altijd de mogelijkheid dat je er eentje vergeet.
  2. Je hebt veel meer kans dat je een fout maakt.

Je hebt het min-of-meer goed gedaan met #define RAWR 2 en #define RAWL 4 maar later gebruik je weer 2 en 4 in pinMode(). Ik stel voor dat je de volgende verandering aanbrengt

/*
#define RAWR 2
#define RAWL 4
ezLED rawr(RAWR);  // create ezLED object
ezLED rawl(RAWL);  // create ezLED object
#define rxPin 19
*/

const uint8_t pinRawRechts = 2;
const uint8_t pinRawLinks = 4;
const uint8_t pinAchteruitrijlicht = 5;
const uint8_t pinKoplamp = 6;
const uint8_t pinAchterlicht = 8;

const uint8_t pinDbg1 = 9;
const uint8_t pinDbg2 = 10;
const uint8_t pinDbg3 = 11;
const uint8_t pinDbg4 = 12;
const uint8_t pinDbg5 = 13;

ezLED rawr(pinRawRechts);  // create ezLED object
ezLED rawl(pinRawLinks);   // create ezLED object

En vervolgens overal gebruik maakt van die namen.

Verder is het te adviseren van pin 19 af te blijven als je Serial1 gebruikt; ik vermoed dat dat een overblijfsel is van eerdere code met SoftwareSerial. Hieronder volledige programma met beide wijzigingen.

/* ROBOTmaker 28.12.2016
 * This example decodes a Futaba SBUS or compatible stream and convert it to soft switches or PPM.
 * 
 * Thanks goes to https://www.ordinoscope.net/index.php/Electronique/Protocoles/SBUS for the arduino code which was converted to for our use
 * It is based on a verion found  :
 * - https://github.com/zendes/SBUS
 * - http://forum.arduino.cc/index.php?topic=99708.0
 * - https://mbed.org/users/Digixx/notebook/futaba-s-bus-controlled-by-mbed/
 * 
 * There are some inexpensibe SBUS to PPM decoders, such as
 * http://www.hobbyking.com/hobbyking/store/__37953__frsky_4_channel_s_bus_to_pwm_decoder.html
 * This code is more a proof of concept than a real alternative.
 *
 *Further details on our website:
 *http://www.robotmaker.eu/ROBOTmaker/quadcopter-3d-proximity-sensing/sbus-graphical-representation
 *
 * This code uses the RX0 as input. It's not possible to use a software serial port, because
 * there are too many conflicting interrupts between serial input and PWM generation.
 *
 * Since RX0 is also used to communicate with the FTDI, the SBUS must be disconnected while
 * flashing the Arduino.
 *
 * Furthermore, the SBUS uses an inverted serial communication. Why should the Futaba designers of the SBUS make life simple when
 * it's so much fun to make it more difficult? Inverting the signal is easy and can be done with a simple transistor / resistor (see our website) or an inverter:
 * http://www.hobbyking.com/hobbyking/store/__24523__ZYX_S_S_BUS_Connection_Cable.html
 * (the shortest end goes to the receiver, the longest to the Arduino)
 * Alternatively, if you use an X4R you can tap directly into the inverted signal provided on the PCB for a side connector. Details of how to do this are on our website. 
 * See http://www.robotmaker.eu/ROBOTmaker/quadcopter-3d-proximity-sensing/sbus-graphical-representation
 * 
 * The code works on an Arduino Pro Mini. It will probably work on others too, but I haven't tried on other versions yet
 * Ensure to Download the library ->  <SoftwareSerial.h> and <Servo.h> via the Arduino IDE otherwise the code won't compile
 * 
 * 
 * 
 * 
  */
#include <SoftwareSerial.h>
//#include <SoftwareServo.h>
#include <Servo.h>
#include <ezLED.h>  // ezLED library


/*
#define RAWR 2
#define RAWL 4
ezLED rawr(RAWR);  // create ezLED object
ezLED rawl(RAWL);  // create ezLED object
#define rxPin 19
*/

const uint8_t pinRawRechts = 2;
const uint8_t pinRawLinks = 4;
const uint8_t pinAchteruitrijlicht = 5;
const uint8_t pinKoplamp = 6;
const uint8_t pinAchterlicht = 8;

const uint8_t pinDbg1 = 9;
const uint8_t pinDbg2 = 10;
const uint8_t pinDbg3 = 11;
const uint8_t pinDbg4 = 12;
const uint8_t pinDbg5 = 13;

ezLED rawr(pinRawRechts);  // create ezLED object
ezLED rawl(pinRawLinks);   // create ezLED object





Servo myservo8;  // create servo object to control a servo
int pos = 0;     // variable to store the servo position
int Brakelight = 0;

//Not used in the Demo
//Servo myservo9;  // create servo object to control a servo
//Servo myservo10;  // create servo object to control a servo
//Servo myservo11;  // create servo object to control a servo
//SoftwareSerial InvertedSerialPort =  SoftwareSerial(rxPin, txPin, true); //(Tx,TX, Inverted mode ping this device uses inverted signaling
//For Piezo Buzzer

//***********************************************************************
//     Setup
//***********************************************************************
void setup()
{

  //The pins on the Arduino need to be defined. In this demo pin 9-13 are used. Pin 13 is the LED on the Arduino which is
  //a simple mehod for debugging. The demo turns this on when the Channel 1 (often used for throttle) exceeds a predefined SBUS level.
  pinMode(pinRawRechts, OUTPUT);          //Richtingaanwijzer links
  pinMode(3, OUTPUT);                     //
  pinMode(pinRawLinks, OUTPUT);           //Richtingaanwijzer rechts
  pinMode(pinAchteruitrijlicht, OUTPUT);  //Achteruitrijlicht
  pinMode(pinKoplamp, OUTPUT);            //Koplampen
  pinMode(pinAchterlicht, OUTPUT);        //achterlicht
  pinMode(pinDbg1, OUTPUT);               //Debug with LED
  pinMode(pinDbg2, OUTPUT);               //Debug with LED
  pinMode(pinDbg3, OUTPUT);               //Debug with LED
  pinMode(pinDbg4, OUTPUT);               //Debug with LED
  pinMode(pinDbg5, OUTPUT);               //Debug with LED
  Serial1.begin(100000, SERIAL_8E2);      //The SBUS is a non standard baud rate which can be confirmed using an oscilloscope
  Serial.begin(115200);
  rawr.blink(500, 500);  // 500ms ON, 500ms OFF, blink immediately
  rawl.blink(500, 500);  // 500ms ON, 500ms OFF, blink immediately
}

//***********************************************************************
//     Loop
//***********************************************************************
void loop()
{
  bool breakOn = false;

  //Declare the variabes
  static byte buffer[25];
  static int channels[18];
  static int errors = 0;
  static bool failsafe = 0;
  static int idx;
  static unsigned long last_refresh = 0;
  static int lost = 0;
  byte b;
  int i;
  int redPin = 3;
  int greenPin = 5;
  int bluePin = 6;
  word results;

  //Check the serial port for incoming data
  //This could also be done via the serialEvent()
  if (Serial1.available())
  {
    b = Serial1.read();

    //this is a new package and it' not zero byte then it's probably the start byte B11110000 (sent MSB)
    //so start reading the 25 byte package
    if (idx == 0 && b != 0x0F)
    {  // start byte 15?
       // error - wait for the start byte
    }
    else
    {
      buffer[idx++] = b;  // fill the buffer with the bytes until the end byte B0000000 is recived
    }

    if (idx == 25)
    {  // If we've got 25 bytes then this is a good package so start to decode
      idx = 0;
      if (buffer[24] != 0x00)
      {
        errors++;
      }
      else
      {
        //  Serial.println("Found Packet");
        // 25 byte packet received is little endian. Details of how the package is explained on our website:
        //http://www.robotmaker.eu/ROBOTmaker/quadcopter-3d-proximity-sensing/sbus-graphical-representation
        channels[1] = ((buffer[1] | buffer[2] << 8) & 0x07FF);
        channels[2] = ((buffer[2] >> 3 | buffer[3] << 5) & 0x07FF);
        channels[3] = ((buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10) & 0x07FF);
        channels[4] = ((buffer[5] >> 1 | buffer[6] << 7) & 0x07FF);
        channels[5] = ((buffer[6] >> 4 | buffer[7] << 4) & 0x07FF);
        channels[6] = ((buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9) & 0x07FF);
        channels[7] = ((buffer[9] >> 2 | buffer[10] << 6) & 0x07FF);
        channels[8] = ((buffer[10] >> 5 | buffer[11] << 3) & 0x07FF);
        channels[9] = ((buffer[12] | buffer[13] << 8) & 0x07FF);
        channels[10] = ((buffer[13] >> 3 | buffer[14] << 5) & 0x07FF);
        channels[11] = ((buffer[14] >> 6 | buffer[15] << 2 | buffer[16] << 10) & 0x07FF);
        channels[12] = ((buffer[16] >> 1 | buffer[17] << 7) & 0x07FF);
        channels[13] = ((buffer[17] >> 4 | buffer[18] << 4) & 0x07FF);
        channels[14] = ((buffer[18] >> 7 | buffer[19] << 1 | buffer[20] << 9) & 0x07FF);
        channels[15] = ((buffer[20] >> 2 | buffer[21] << 6) & 0x07FF);
        channels[16] = ((buffer[21] >> 5 | buffer[22] << 3) & 0x07FF);
        channels[17] = ((buffer[23]) & 0x0001) ? 2047 : 0;
        channels[18] = ((buffer[23] >> 1) & 0x0001) ? 2047 : 0;

        failsafe = ((buffer[23] >> 3) & 0x0001) ? 1 : 0;
        if ((buffer[23] >> 2) & 0x0001) lost++;
        //serialPrint (lost); debg the signals lost


        //For this demo, the corresponding channels mapped below need to be also configured on the FrSky Taranis tranmitter accordingly.
        //Any of the Channels can of course be used trigger any of the pins on the Arduino
        //Channels used in the demo are 5,6,7. Mapped these to the sliders on the transmitter to change RGB LED values
        //Channel 1 set to trigger the Internal Arduino LED on pin 13 once the threshold exceeds 1500
        //Channel 10 needs to be mapped to one of the switches on the Taranis which triggers a buzzer on pin 10 of the Arduino
        //Channel 1 also triggers a servo connected to pin 8 on the Arduino. So moving the throttle will also move the servo accordingly





        //***********************************************************************
        //Turn on right Indicator lights if channel 1 (Steering) moves right.
        //***********************************************************************
        results = channels[1];
        Serial1.write(results);
        if (channels[1] < 400)
        {
          rawr.loop();  // MUST call the led1.loop() function in loop()

          Serial.println("RAW R");
        }
        else
        {
          digitalWrite(pinRawRechts, LOW);
        }

        //***********************************************************************
        //Turn on left Indicator lights if channel 1 (Steering) moves left.
        //***********************************************************************
        results = channels[1];
        Serial1.write(results);
        if (channels[1] > 1800)
        {

          rawl.loop();  // MUST call the led1.loop() function in loop()
          Serial.println("RAW L");
        }
        else
        {
          digitalWrite(pinRawLinks, LOW);
        }
        //***********************************************************************
        /* / //Turn on hazard lights if channel 11 exceeds 1500
            //***********************************************************************
             results=channels[1];
              Serial1.write (results);
            if (channels[11] > 1800){
              
              rawl.loop(); // MUST call the led1.loop() function in loop()
              rawl.loop(); // MUST call the led1.loop() function in loop()
              Serial.println ("RAW hazard");
             }
             if (channels[11] < 1000){
              
              rawl.cancel(); // MUST call the led1.loop() function in loop()
              rawl.cancel(); // MUST call the led1.loop() function in loop()
             
             }
             */

        //***********************************************************************
        //Brake lights channel 2 .
        //***********************************************************************
        results = channels[1];
        Serial1.write(results);
        if ((channels[2] >= 970) && (channels[2] <= 1010))
        {
          breakOn = true;
          Serial.println("Brake light");
        }
        else
        {
          breakOn = false;
        }

        //***********************************************************************
        //Back up lights channel 2 .
        //***********************************************************************
        results = channels[1];
        Serial1.write(results);
        if (channels[2] < 970)
        {
          digitalWrite(pinAchteruitrijlicht, HIGH);
          Serial.println("Back up light");
        }
        else
        {
          digitalWrite(pinAchteruitrijlicht, LOW);
        }

        //***********************************************************************
        //head and tail lights Channel 6
        //***********************************************************************
        results = channels[1];
        Serial1.write(results);
        if (channels[6] > 1800)
        {
          // head lights on
          analogWrite(pinKoplamp, 100);
          Serial.println("head and tail light");
          // not breaking
          if (breakOn == false)
          {
            // tail lights on
            analogWrite(pinAchterlicht, 100);
          }
          // breaking
          else
          {
            // tail lights bright
            digitalWrite(pinAchterlicht, HIGH);
          }
        }
        else
        {
          // head lights off
          digitalWrite(pinKoplamp, LOW);
          // not breaking
          if (breakOn == false)
          {
            // tail lights off
            digitalWrite(pinAchterlicht, LOW);
          }
          // breaking
          else
          {
            // tail lights bright
            digitalWrite(pinAchterlicht, HIGH);
          }
        }

        //***********************************************************************
        //Drive a Servo connected to channel 1 (which is mapped to thrust if you are using Mode 2)
        //Servo connected to pin 8 on the Arduino
        //***********************************************************************


        //***********************************************************************
        //Turn on or off a buzzer. Channel 10 is mapped to switch SH.
        // Buzzer connected to pin 10 on Arduino
        //***********************************************************************
        //if (channels[10] > 1500){
        //    digitalWrite(10, HIGH);
        //   }
        // else
        //   {
        //    digitalWrite(10, LOW);
        // }
      }  //closing - else
    }    //closing - if (idx == 25)
  }      //closing - if (Serial.available ())
}  //closing void loop
1 Like

Één woord: WOUW!! ik heb de wijzigingen doorgevoerd en het werkt feilloos! Ik ga proberen deze code op meer kanalen te gebruiken echt heel erg bedankt. ik wil je graag trakteren op een biertje (of wat anders natuurlijk) heb je een Paypal account?

Ster, thx voor je manier van becommentariëren van je programma. Met name het afsluiten van de accolades is heel verduidelijkend voor mij in heel complexe procedures. Ik ga deze manier zeker toepassen....

@Frits1956, dat kwam van @the_mechanic1987 :wink:

Ik gebruik het soms maar in mijn programmas is er in het algemeen geen noodzaak voor. Als je loop() verder opsplitst in meerdere functies wordt de noodzaak een stuk kleiner.

1 Like

Je hebt een bug in je programma !!

static int channels[18]; declareert een array van 18 elementen. De index van die elementen loopt van 0 tot 17 (en niet van 1 to 18) en daarom is channels[18] = ((buffer[23] >> 1) & 0x0001) ? 2047 : 0; een bug. Je overschrijft een geheugen locatie die niet bij het array hoort.

Ik zie dat helaas nu pas dus die fout zit ook in het programma dat ik je gegeven heb in post #9 maar je de indexering volledig aanassen, anders krijg je niet-gedefinieerd gedrag in je programma.

Mijn main is over het algemeen heel kort en bestaat meestal uit aanroepen van functies met parameters. Ik werk samen met anderen aan projecten voor het museum waar ik vrijwilliger bij ben. Ik doe het programmeerwerk en anderen de techniek en electronica. We zijn allen hobbyisten en hebben weinig kennis van wat de anderen doen. Dat maakt het enigszins lastig en ik probeer in mijn comment duidelijk te maken hoe het programma in elkaar zit, waar een nieuw stukje begint en wat bij elkaar hoort. Het comment bij het afsluiten met de accolades zal het voor hen een stuk duidelijker maken.
Dus: nogmaals bedankt, ook the_mechanic1987 bedankt.

Heel scherp! Dat deel heb ik zelf niet geschreven, ik ga het uitzoeken. Kan het ook een bewuste keuze zijn geweest?

Nee.

Waar heb je het vandaan gehaald? Er zitten iets teveel links in de commentaren om ze allemaal te doorlopen.

Dit is de site van de maker zelf en tevens de enige info die gegeven wordt

Hier staat meer info, het uitlezen van het sbus signaal zal op de zelfde wijze verlopen omdat het een vast protocol is.

Because you don't have a problem with the IDE, your topic has been moved to a more suitable location on the forum.



/* ROBOTmaker 28.12.2016
 * This example decodes a Futaba SBUS or compatible stream and convert it to soft switches or PPM.
 * 
 * Thanks goes to https://www.ordinoscope.net/index.php/Electronique/Protocoles/SBUS for the arduino code which was converted to for our use
 * It is based on a verion found  :
 * - https://github.com/zendes/SBUS
 * - http://forum.arduino.cc/index.php?topic=99708.0
 * - https://mbed.org/users/Digixx/notebook/futaba-s-bus-controlled-by-mbed/
 * 
 * There are some inexpensibe SBUS to PPM decoders, such as
 * http://www.hobbyking.com/hobbyking/store/__37953__frsky_4_channel_s_bus_to_pwm_decoder.html
 * This code is more a proof of concept than a real alternative.
 *
 *Further details on our website:
 *http://www.robotmaker.eu/ROBOTmaker/quadcopter-3d-proximity-sensing/sbus-graphical-representation
 *
 * This code uses the RX0 as input. It's not possible to use a software serial port, because
 * there are too many conflicting interrupts between serial input and PWM generation.
 *
 * Since RX0 is also used to communicate with the FTDI, the SBUS must be disconnected while
 * flashing the Arduino.
 *
 * Furthermore, the SBUS uses an inverted serial communication. Why should the Futaba designers of the SBUS make life simple when
 * it's so much fun to make it more difficult? Inverting the signal is easy and can be done with a simple transistor / resistor (see our website) or an inverter:
 * http://www.hobbyking.com/hobbyking/store/__24523__ZYX_S_S_BUS_Connection_Cable.html
 * (the shortest end goes to the receiver, the longest to the Arduino)
 * Alternatively, if you use an X4R you can tap directly into the inverted signal provided on the PCB for a side connector. Details of how to do this are on our website. 
 * See http://www.robotmaker.eu/ROBOTmaker/quadcopter-3d-proximity-sensing/sbus-graphical-representation
 * 
 * The code works on an Arduino Pro Mini. It will probably work on others too, but I haven't tried on other versions yet
 * Ensure to Download the library ->  <SoftwareSerial.h> and <Servo.h> via the Arduino IDE otherwise the code won't compile
 * 
 * 
 * 
 * 
 * 
  */
#include <SoftwareSerial.h>
//#include <SoftwareServo.h>
#include <Servo.h>
#include <ezLED.h> // ezLED library


/*/#define RAWR 2
//#define RAWL 4
ezLED rawr(RAWR);  // create ezLED object 
ezLED rawl(RAWL);  // create ezLED object 
#define rxPin 19
*/

const uint8_t pinRawR = 2;
const uint8_t pinAchterlicht = 3;
const uint8_t pinRawL = 4;
const uint8_t pinAchteruitrijlicht = 5;
const uint8_t pinKoplamp = 6;
const uint8_t pinVerstralers = 7;

const uint8_t pinDbg2 = 8;
const uint8_t pinDbg3 = 9;
const int rawL_SHORT = 1000; 
const int rawR_SHORT = 1000; 
const int rawL_LONG = 1000; 
const int rawR_LONG = 1000; 

ezLED rawr(pinRawR);  // create ezLED object
ezLED rawl(pinRawL);   // create ezLED object

Servo myservo8;  // create servo object to control a servo

int pos = 0;    // variable to store the servo position
int Brakelight = 0;
int Koplamp = 0;
int stadslichtenAan = 0; 
int grootlichtAan = 0;
int rawRAan = 0;
int rawLAan = 0;

int rawRUit;     // the current reading from the input pin
int rawLUit;    // the current reading from the input pin
unsigned long rawR_Press_Time  = 0;
unsigned long rawR_Release_Time = 0;
unsigned long rawL_Press_Time  = 0;
unsigned long rawL_Release_Time = 0;
bool rawR_kort = false;
bool rawR_lang = false;
bool rawL_kort = false;
bool rawL_lang = false;
int status_rawR = false;
int status_rawL = false;

//Not used in the Demo
//Servo myservo9;  // create servo object to control a servo 
//Servo myservo10;  // create servo object to control a servo 
//Servo myservo11;  // create servo object to control a servo 
//SoftwareSerial InvertedSerialPort =  SoftwareSerial(rxPin, txPin, true); //(Tx,TX, Inverted mode ping this device uses inverted signaling
//For Piezo Buzzer

//***********************************************************************
//     Setup 
//***********************************************************************
void setup () 
{ 

  //The pins on the Arduino need to be defined. In this demo pin 9-13 are used. Pin 13 is the LED on the Arduino which is 
  //a simple mehod for debugging. The demo turns this on when the Channel 1 (often used for throttle) exceeds a predefined SBUS level. 
  pinMode(pinRawL, OUTPUT);          //Richtingaanwijzer links
  pinMode(pinAchterlicht, OUTPUT);        //achterlicht                    
  pinMode(pinRawR, OUTPUT);           //Richtingaanwijzer rechts
  pinMode(pinAchteruitrijlicht, OUTPUT);  //Achteruitrijlicht
  pinMode(pinKoplamp, OUTPUT);            //Koplampen
  pinMode(pinVerstralers, OUTPUT);               //Debug with LED       
  pinMode(pinDbg2, OUTPUT);               //Debug with LED
  pinMode(pinDbg3, OUTPUT);               //Debug with LED
  //pinMode(NAW, OUTPUT);               //Debug with LED
  //pinMode(NAW, OUTPUT);               //Debug with LED
  //pinMode(NAW, OUTPUT);               //Debug with LED
  Serial1.begin(100000, SERIAL_8E2);      //The SBUS is a non standard baud rate which can be confirmed using an oscilloscope
  Serial.begin(115200);
  rawr.blink(500, 500);  // 500ms ON, 500ms OFF, blink immediately
  rawl.blink(500, 500);  // 500ms ON, 500ms OFF, blink immediately
    
     
  }
//**********************************************************************
// waarde 190 staat ongeveer gelijk aan 1000 op de zender 
//**********************************************************************


//***********************************************************************
//     Loop
//***********************************************************************
void loop () 
{
  
 //Declare the variabes
  static byte buffer[25];
  static int channels[18];
  static int errors = 0;
  static bool failsafe = 0;
  static int idx;
  static unsigned long last_refresh = 0;
  static int lost = 0;
  byte b;
  int i;
  word results;
  bool brakeOn = false;
  bool dimlichtAan = false; 
  bool stadslichtenAan = false; 
  bool grootlichtAan = false;

 //Check the serial port for incoming data
 //This could also be done via the serialEvent()
  if (Serial1.available ()) {
      b = Serial1.read ();
       
     //this is a new package and it' not zero byte then it's probably the start byte B11110000 (sent MSB)
     //so start reading the 25 byte package
      if (idx == 0 && b != 0x0F) {  // start byte 15?
       // error - wait for the start byte
        
      } else {
        buffer[idx++] = b;  // fill the buffer with the bytes until the end byte B0000000 is recived
      }
   
    if (idx == 25) {  // If we've got 25 bytes then this is a good package so start to decode
      idx = 0;
      if (buffer[24] != 0x00) {
        errors++;
      } else 
      {
            //  Serial.println("Found Packet");
            // 25 byte packet received is little endian. Details of how the package is explained on our website:
            //http://www.robotmaker.eu/ROBOTmaker/quadcopter-3d-proximity-sensing/sbus-graphical-representation
            channels[1]  = ((buffer[1]    |buffer[2]<<8)                 & 0x07FF);
            channels[2]  = ((buffer[2]>>3 |buffer[3]<<5)                 & 0x07FF);
            channels[3]  = ((buffer[3]>>6 |buffer[4]<<2 |buffer[5]<<10)  & 0x07FF);
            channels[4]  = ((buffer[5]>>1 |buffer[6]<<7)                 & 0x07FF);
            channels[5]  = ((buffer[6]>>4 |buffer[7]<<4)                 & 0x07FF);
            channels[6]  = ((buffer[7]>>7 |buffer[8]<<1 |buffer[9]<<9)   & 0x07FF);
            channels[7]  = ((buffer[9]>>2 |buffer[10]<<6)                & 0x07FF);
            channels[8]  = ((buffer[10]>>5|buffer[11]<<3)                & 0x07FF);
            channels[9]  = ((buffer[12]   |buffer[13]<<8)                & 0x07FF);
            channels[10]  = ((buffer[13]>>3|buffer[14]<<5)                & 0x07FF);
            channels[11] = ((buffer[14]>>6|buffer[15]<<2|buffer[16]<<10) & 0x07FF);
            channels[12] = ((buffer[16]>>1|buffer[17]<<7)                & 0x07FF);
            channels[13] = ((buffer[17]>>4|buffer[18]<<4)                & 0x07FF);
            channels[14] = ((buffer[18]>>7|buffer[19]<<1|buffer[20]<<9)  & 0x07FF);
            channels[15] = ((buffer[20]>>2|buffer[21]<<6)                & 0x07FF);
            channels[16] = ((buffer[21]>>5|buffer[22]<<3)                & 0x07FF);
            channels[17] = ((buffer[23])      & 0x0001) ? 2047 : 0;
            channels[18] = ((buffer[23] >> 1) & 0x0001) ? 2047 : 0;
     
            failsafe = ((buffer[23] >> 3) & 0x0001) ? 1 : 0;
            if ((buffer[23] >> 2) & 0x0001) lost++;
            //serialPrint (lost); debg the signals lost

          
            //For this demo, the corresponding channels mapped below need to be also configured on the FrSky Taranis tranmitter accordingly.
            //Any of the Channels can of course be used trigger any of the pins on the Arduino 
            //Channels used in the demo are 5,6,7. Mapped these to the sliders on the transmitter to change RGB LED values
            //Channel 1 set to trigger the Internal Arduino LED on pin 13 once the threshold exceeds 1500
            //Channel 10 needs to be mapped to one of the switches on the Taranis which triggers a buzzer on pin 10 of the Arduino 
            //Channel 1 also triggers a servo connected to pin 8 on the Arduino. So moving the throttle will also move the servo accordingly
            
            
           
            /*
        
            //***********************************************************************
            //Turn on right Indicator lights if channel 1 (Steering) moves right.
            //***********************************************************************
             results=channels[1];
              Serial1.write (results);
            if (channels[1] < 400){
               rawr.loop(); // MUST call the led1.loop() function in loop()
              
              Serial.println ("RAW R");
             }
             else 
             {
              digitalWrite(pinRawR, LOW);
             }
             
            //***********************************************************************
            //Turn on left Indicator lights if channel 1 (Steering) moves left.
            //***********************************************************************
             results=channels[1];
              Serial1.write (results);
            if (channels[1] > 1800){
              
              rawl.loop(); // MUST call the led1.loop() function in loop()
              Serial.println ("RAW L");
             }
             else 
             {
              digitalWrite(pinRawL, LOW);
             }
            */




//***********************************************************************
//Turn signals experiment moet op linker stick KANAAL NOG AANPASSEN!!!!
//***********************************************************************

//**********************************************************************
//Turn on right Indicator lights if channel 1 (Steering) moves right.
//**********************************************************************

             results=channels[1];
              Serial1.write (results);
            if (channels[1] < 400)
            {
               rawRAan = true; 
              
              Serial.println ("RAW R bediend");
             }
             else 
             {
              rawRAan = false; 
             }

             
//**********************************************************************
//Turn on left Indicator lights if channel 1 (Steering) moves left.
//**********************************************************************
             results=channels[1];
              Serial1.write (results);
            if (channels[1] > 1800)
            {
               rawLAan = true; 
              
              Serial.println ("RAW L bediend");
             }
             else 
             {
              rawLAan = false; 
             }

          
//*********************************************************************
// Script voor Richtingaanwijzer rechts
//*********************************************************************

 if(rawRAan  == true && rawRUit == LOW)        // button is pressed
 {
    rawR_Press_Time = millis();
    rawR_kort = true;
    rawR_lang = false;
 }
  else if(rawRAan == false && rawRUit == true) // button is released
  {
    rawR_kort = false;
    rawR_Release_Time = millis();

    long rawR_pressDuration  = rawR_Release_Time - rawR_Press_Time;

    if( rawR_pressDuration < rawR_SHORT )
      Serial.println("Richtingaanwijzer rechts aan");

      
  
    }
  if(rawR_kort == true && rawR_lang == false) 
  {
    long rawR_pressDuration = millis() - rawR_Press_Time;

    if( rawR_pressDuration > rawR_SHORT ) 
    {
      Serial.println(" Gevarenlicht aan ");
      rawR_lang = true;
    }
  }

  
  // save the the last state
  rawRAan = rawRUit;

  if (rawR_kort == true)
  {
    Serial.println ("RAW R");
    status_rawR = !status_rawR;
    rawr.loop(); // MUST call the led1.loop() function in loop()

               
              
              
             }
             else 
             {
              digitalWrite(pinRawR, LOW);
             }
 

//*********************************************************************
// Script voor Richtingaanwijzer links
//*********************************************************************

 if(rawLAan  == true && rawLUit == LOW)        // button is pressed
 {
    rawL_Press_Time = millis();
    rawL_kort = true;
    rawL_lang = false;
 }
  else if(rawLAan == false && rawLUit == true) // button is released
  {
    rawL_kort = false;
    rawL_Release_Time = millis();

    long rawL_pressDuration  = rawL_Release_Time - rawL_Press_Time;

    if( rawL_pressDuration < rawL_SHORT )
      Serial.println("Richtingaanwijzer links aan");
  
    }
  if(rawL_kort == true && rawL_lang == false) 
  {
    long rawL_pressDuration = millis() - rawL_Press_Time;

    if( rawL_pressDuration > rawL_SHORT ) 
    {
      Serial.println(" Optie vrij, werklampen? ");
      rawL_lang = true;
    }
  }

    
  
  // save the the last state
  rawLAan = rawLUit;
         

//***********************************************************************
//Brake lights channel 2 .
//***********************************************************************
        results = channels[1];
        Serial1.write(results);
        if ((channels[2] >= 970) && (channels[2] <= 1010))
        {
          brakeOn = true;
          Serial.println("Brake light");
        }
        else
        {
          brakeOn = false;  
        }

         
//***********************************************************************
//Back up lights channel 2 .
//***********************************************************************
             results=channels[1];
              Serial1.write (results);
            if (channels[2] <970) {
              
              digitalWrite(pinAchteruitrijlicht, HIGH);
              Serial.println ("Back up light");
             }
             else 
             {
              digitalWrite(pinAchteruitrijlicht, LOW);
             }


//***********************************************************************
//head and tail lights Channel 6
//***********************************************************************
        results = channels[1];
        Serial1.write(results);
        if (channels[6] > 1800)
        {
          // head lights on
          stadslichtenAan = true;
          Serial.println("Stadslichten en achterlicht aan");
          
          
          // not braking
          if (brakeOn == false)
          {
            // tail lights on
            analogWrite(pinAchterlicht, 50);
          }
          // braking
          else
          {
            // tail lights bright
            digitalWrite(pinAchterlicht, HIGH);
          }
        }
        else
        {
          // head lights off
          digitalWrite(pinKoplamp, LOW);
          
          // not braking
          if (brakeOn == false)
          {
            // tail lights off
            digitalWrite(pinAchterlicht, LOW);
          }
          // braking
          else
          {
            // tail lights bright
            digitalWrite(pinAchterlicht, HIGH);
          }
        }


//***********************************************************************
//  Dimlicht channel 7 .
//***********************************************************************
        results = channels[1];
        Serial1.write(results);
        if ((channels[7] >= 500) && (channels[7] <= 1800))
        {
         
          dimlichtAan = true;
          Serial.println("dimlicht aan");
        }
        else
        {
          
          dimlichtAan = false;
          
        }


//***********************************************************************
// Dimlicht
//***********************************************************************
        if (stadslichtenAan == true) {
          // dimlicht aan
          if (dimlichtAan == true)
          {
            // Zet dimlichten aan 
            analogWrite(pinKoplamp, 180);
          }
          else {
          
            analogWrite(pinKoplamp, 60);
          }}

     
//***********************************************************************
// Grootlicht
//***********************************************************************
        results = channels[1];
        Serial1.write(results);
        if (channels[7] > 1800)
        {
          // head lights on
          grootlichtAan = true;
          Serial.println("grootlicht aan");
        }
          //dimlicht aan
          if (grootlichtAan == true) {
          // grootlicht uit
          if (dimlichtAan == false)
          {
            // dimlichten aan 
            analogWrite(pinKoplamp, 255);
            
          }}


//******************************************************************************* 
//Verstralers aan
//*******************************************************************************
          if (grootlichtAan == true) {
            analogWrite(pinVerstralers, 255);
          }
           else if (stadslichtenAan == true) {
           analogWrite(pinVerstralers, 60); 
          }
          else if ((grootlichtAan == false) && (stadslichtenAan == false)) {
            analogWrite(pinVerstralers, 0); 
          } 

              
          } //closing - else
      } //closing - if (idx == 25)
    } //closing - if (Serial.available ())
} //closing void loop

@sterretje zou je hier eens naar kunnen kijken? ik heb het nog niet getest enkel gecompiled. het gaat om het stuk van het aansturen van de rechter richtingaanwijzer. ik heb het gevoel dat ik een fout maak.