Arduino Nano Somfy serial

Arduino specifieke Software
Berichten: 3
Geregistreerd: 02 Jul 2020, 16:25

Arduino Nano Somfy serial

Berichtdoor Eugene » 02 Jul 2020, 16:52

Beste mede programmeurs,

Ik ben bezig met een project met een Arduino nano die ik gekoppeld heb aan een SOmfy controller. Ik zou graag met de nano mijn Somfy zonneschermen gaan bedienen

Vervolgens heb ik een aantal pinnen van de nano gekoppeld aan de controller. ( A0 Led1, A1 led 2, A2 led 3, A3 led 4, 12 Up, 10 down, 11 stop, 9 select knop, +3,3V &de Gnd).

Ik zou graag een 3tal characters naar de Arduino sturen. Deze zouden in de buffer "cmd" moeten komen te staan. Vervolgens zou de nano moeten kijken in welk kanaal de controller zich bevind en anders naar het juiste kanaal schakelen d.m.v. de slectie toets. Als dit glukt is mag het scherm naar beneden of boven stuurd worden afhankelijk van het commando. Voorbeeld van een commando wat altijd begint met een 'c'

SOMFY CHANNEL COMMAND:

c<channel><action>
<channel>: number between 1-5
<action>: 'u' for up
'd' for down
's' for stop

example: "c2u" sends an up command to the Somfy remote on channel 2

Als ik de serial monitor open komt de code tot "Arduino started!" Maar als ik dan vervolgens een commando stuur gebeurt er niets. :( Ik zie niet waar het fout gaat.. ik denk dat de data niet in 'cmd' komt te staan waar door de switch case niet word doorlopen maar mischien heb ik het fout… Kan iemand mij een tip geven / weer verder op weg helpen?

Alvast bedankt!

Hierbij de volledige code (Ik weet dat het een lap tekst is maar dit voor komt vast veel vragen)

Code: Alles selecteren
// Test Somfy

// digital pin numbers for LED connections
#define SOMFY_LED1_APIN 14
#define SOMFY_LED2_APIN 15
#define SOMFY_LED3_APIN 16
#define SOMFY_LED4_APIN 17

// digital pin numbers for button connections
#define SOMFY_BUTTON_UP   12
#define SOMFY_BUTTON_DOWN 10
#define SOMFY_BUTTON_MY   11
#define SOMFY_BUTTON_MENU 9

boolean upPress = false;
boolean downPress = false;
boolean myPress = false;
boolean progPress = false;
 boolean selectPress = false;
 unsigned long holdTime = 0;
int repeatSend = 0;
char incomingChar;
boolean test = false;

// the setup routine runs once when you press reset:
void setup() {               
  // initialize the digital pins as an output.
  pinMode(SOMFY_BUTTON_UP,   OUTPUT);
  pinMode(SOMFY_BUTTON_DOWN, OUTPUT);
  pinMode(SOMFY_BUTTON_MY,   OUTPUT);
  pinMode(SOMFY_BUTTON_MENU, OUTPUT);
 
  // delay setup to prevent digital outs to go high during serial initialization
  delay(1000);
   
 
  Serial.begin(9600); // set up Serial library at 9600 bps
  Serial.println("Arduino started!");
}

// function to press a button on the remote
int press_button(int button){
  digitalWrite(button, HIGH);
  delay(150);
  digitalWrite(button, LOW);
}

// function to get the current channel on the remote
// LEDs need to be blinking, i.e. channel selection button must have been pressed
int get_channel(){
 
  int sel_channel=0;  // the current channel
  int iLED1=1;        // status LED1: 1=OFF, 0=ON
  int iLED2=1;        // status LED2: 1=OFF, 0=ON
  int iLED3=1;        // status LED3: 1=OFF, 0=ON
  int iLED4=1;        // status LED4: 1=OFF, 0=ON
  int iLEDs;          // status LED1-4 in a byte
 
  // read the LEDs from the remote and determine the current channel
  // make sure we detect a blinking LED, they go on and off for about 70ms
  // the body of the loop takes <1ms, so check every 10ms during 100ms to capture a full cycle
  // time1=millis();
  for (int i=0; i<10; i++){
    iLED1 &= digitalRead(SOMFY_LED1_APIN);
    iLED2 &= digitalRead(SOMFY_LED2_APIN);
    iLED3 &= digitalRead(SOMFY_LED3_APIN);
    iLED4 &= digitalRead(SOMFY_LED4_APIN);
    delay(10);
  }
 
  iLEDs = iLED4<<3 | iLED3<<2 | iLED2<<1 | iLED1;
  switch(iLEDs){
    case 14: sel_channel=1; break; // LED1, channel 1 selected
    case 13: sel_channel=2; break; // LED2, channel 2 selected
    case 11: sel_channel=3; break; // LED3, channel 3 selected
    case 7:  sel_channel=4; break; // LED4, channel 4 selected
    case 0:  sel_channel=5; break; // ALL,  channel 5 selected
   
    default:  sel_channel=0;       // no LEDs are blinking
  }
 
  return sel_channel;
}

// function to select a channel on the remote
// return true if succeeded
// return false if something has gone wrong
bool select_channel(int ch){
 
  int curr;    // current channel
  int prev=-1; // previous channel
  int t=0;     // counter, if after 10 channel reads after button press the channel is not OK, something is wrong
 
  // while the current channel is not equal to channel 'ch' go to the next channel by pressing the channel select button
  // the button is only pressed when the previous channel selection changed, because get_channel
  while((curr=get_channel())!=ch && t<10){
    t++;
    if (prev<0 || (curr!=prev && curr>0)){
      press_button(SOMFY_BUTTON_MENU);
      prev=curr;
      t=0;
    }
  }
 
  return t<10 || curr==ch;
}

// do something with the 'cmd' received from the serial
int process_cmd(char* cmd, char* msg){
// A command consists of max 3 characters:
//
//  SOMFY CHANNEL COMMAND:
//
//      c<channel><action>
//         
//        <channel>: number between 1-5
//        <action>:  'u' for up
//                   'd' for down
//                   's' for stop
//         
//  example: "c2u" sends an up command to the Somfy remote on channel 2

char  ich;     // the channel to select
cmd=incomingChar;

msg[0]=0;

if (test){
  switch (cmd[0]){           
    case 'c': // Somfy channel command
       // get the channel number
       ich=cmd[1]-'1'+1;
       
       // select the channel
       if (ich>=1 && ich<=5){     
         if(select_channel(ich)){
       
           // perform the action
           switch(cmd[2]){
             case 'u': press_button(SOMFY_BUTTON_UP);   
               sprintf(msg,"Selected channel %d, pressed button UP",ich);

             break;
             case 'd': press_button(SOMFY_BUTTON_DOWN);
                sprintf(msg,"Selected channel %d, pressed button DOWN",ich);
                test = false;
           
             break;       
             case 's': press_button(SOMFY_BUTTON_MY);   
                sprintf(msg,"Selected channel %d, pressed button MY",ich);
           
             break;   
   
             default:
                sprintf(msg,"Unknown command: ",cmd);
                test = false;
            }
          }
          else{
            sprintf(msg,"Channel selection failed");
            test = false;
           //Serial.println("Channel selection failed!");
          }
        }
        break;
       
  }
 }
}

void loop(){
 
    char cmd; // buffer to store the command
   
   while (Serial.available() == 0) { delay(50); } // wait until serial command comes in
  if (Serial.available() > 0) {
    cmd = Serial.read();
    Serial.println(cmd);
    if (incomingChar == 'c') {test = true;} 
    }
    }

Advertisement

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Arduino Nano Somfy serial

Berichtdoor Koepel » 02 Jul 2020, 20:03

De compiler is in staat om niet-gebruikte functies en variabelen er uit te laten.
Dit is wat de compiler daarna gaat compileren:
Code: Alles selecteren
// digital pin numbers for button connections
#define SOMFY_BUTTON_UP   12
#define SOMFY_BUTTON_DOWN 10
#define SOMFY_BUTTON_MY   11
#define SOMFY_BUTTON_MENU 9


// the setup routine runs once when you press reset:
void setup()
{
  // initialize the digital pins as an output.
  pinMode(SOMFY_BUTTON_UP,   OUTPUT);
  pinMode(SOMFY_BUTTON_DOWN, OUTPUT);
  pinMode(SOMFY_BUTTON_MY,   OUTPUT);
  pinMode(SOMFY_BUTTON_MENU, OUTPUT);

  // delay setup to prevent digital outs to go high during serial initialization
  delay(1000);

  Serial.begin(9600); // set up Serial library at 9600 bps
  Serial.println("Arduino started!");
}


void loop()
{
  char cmd; // buffer to store the command

  while (Serial.available() == 0)
  {
    delay(50);  // wait until serial command comes in
  }
 
  if (Serial.available() > 0)
  {
    cmd = Serial.read();
    Serial.println(cmd);
  }
}


Dat is 1898 bytes Flash geheugen en 204 bytes SRAM. Dat is exact hetzelfde als je gehele sketch. Je sketch doet dus niet zo veel :(

Kun je bij menu: Bestand / Voorkeuren / Compiler waarschuwingen die op "Allemaal" zetten ? Kijk dan eens naar de waarschuwingen, daar zitten serieuze problemen tussen.

Hoe is het met je programmeerkennis in 'c' en 'c++' ? Heb je kennis van programmeren in een andere taal of met een script-taal ?

Mijn tip is eigenlijk nog een stap eerder. Stel dat door het opstarten of door een storing de sychronisatie verkeerd gaat, dan weet de sketch niet welke drie tekens bij elkaar horen. Kun je een duidelijke beschrijving geven van hoe die drie tekens worden overgestuurd ? Komt daar een LineFeed achter of een CarriageReturn of helemaal niets of beide ? Of wil je een timeout ?
Volgens mij is er eerst een functie nodig die de drie tekens (drie tekens die bij elkaar horen) er uit haalt, en dan door kan sturen.

Berichten: 3
Geregistreerd: 02 Jul 2020, 16:25

Re: Arduino Nano Somfy serial

Berichtdoor Eugene » 02 Jul 2020, 20:40

@Koepel bedankt voor je reactie.

Bedankt voor de tip van de compiler ( Er komt nu meer uit dan ik gedacht had)

Ik wilde eigenlijk 2 stukken code samen voegen. Deze code werk namenlijk wel maar daar van werkt de selectie niet zoals ik zou willen. De controller gaat namenlijk na een xtijd in een besparings stand waardoor er 2x binnen 5 sec. op de selectie toets gedrukt moet worden om van kanaal te veranderen. Deze code word afgesloten met een 'e' maar bevat geen kanaal keuze. Dit zou ik dus heel graag geautomatiseerd hebben ;).

Code: Alles selecteren
// Somfy Test

int progPin = 8;
int upPin = 12;
int downPin = 10;
int myPin = 11;
int selectPin = 9;
int ledPin = 13;

boolean upPress = false;
boolean downPress = false;
boolean myPress = false;
boolean progPress = false;
 boolean selectPress = false;
 unsigned long holdTime = 0;
int repeatSend = 0;

char incomingChar;

void setup() {
  Serial.begin(9600);
  Serial.println("SomfyDuino 0.71");
  Serial.println("TEST");
  Serial.println("-----");
  Serial.println("receives single serial characters like:");
  Serial.println("u - prepare to press UP");
  Serial.println("d - prepare to press DOWN");
  Serial.println("m - prepare to press My");
  Serial.println("p - prepare to press PROG");
  Serial.println("s - prepare to press SELECT");
  Serial.println("r - increase send count by one");
  Serial.println("any digit X - increase hold time by X*100 ms");
  Serial.println("e - Execute! Runs a defined (multi button) press and hold");
  Serial.println("");
  Serial.println("Example: regular UP: u5e ");
  Serial.println("         3 second UP/DOWN: ud9993e ");
  Serial.println("         5 second PROG: p999995e ");
  Serial.println("");

  pinMode(progPin, OUTPUT);
  pinMode(upPin, OUTPUT);
  pinMode(downPin, OUTPUT);
  pinMode(myPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(selectPin, OUTPUT);
  digitalWrite(progPin, HIGH);
  digitalWrite(upPin, HIGH);
  digitalWrite(downPin, HIGH);
  digitalWrite(myPin, HIGH);
  digitalWrite(selectPin, HIGH);
  digitalWrite(ledPin, LOW);
}


void loop() {
 
   while (Serial.available() == 0) { delay(50); } // wait until serial command comes in
  if (Serial.available() > 0) {
    incomingChar = Serial.read();
    Serial.println(incomingChar);
    if (incomingChar == 'u') {upPress = true;}
    if (incomingChar == 'd') {downPress = true;}
    if (incomingChar == 'm') {myPress = true;}
    if (incomingChar == 'p') {progPress = true;}
    if (incomingChar == 's') {selectPress = true;}
    if (incomingChar == '1') {holdTime += 100;}
    if (incomingChar == '2') {holdTime += 200;}
    if (incomingChar == '3') {holdTime += 300;}
    if (incomingChar == '4') {holdTime += 400;}
    if (incomingChar == '5') {holdTime += 500;}
    if (incomingChar == '6') {holdTime += 600;}
    if (incomingChar == '7') {holdTime += 700;}
    if (incomingChar == '8') {holdTime += 800;}
    if (incomingChar == '9') {holdTime += 900;}
    if (incomingChar == 'r') {repeatSend++;}
    if (incomingChar == 'e') {somSend();}
  }
}

void somSend() {
  Serial.print("Pressing: ");
 
  for(int i=0; i <= repeatSend; i++) {
    if (upPress) {digitalWrite(upPin, LOW); upPress = false; Serial.print("up ");}
    if (downPress) {digitalWrite(downPin, LOW); downPress = false; Serial.print("down ");}
    if (myPress) {digitalWrite(myPin, LOW); myPress = false; Serial.print("my ");}
    if (progPress) {digitalWrite(progPin, LOW); progPress = false; Serial.print("prog ");}
    if (selectPress) {digitalWrite(selectPin, LOW); selectPress = false; Serial.print("select ");}
    digitalWrite(ledPin, HIGH);

    Serial.print("for ");
    Serial.print(holdTime);
    Serial.println(" ms");

    delay(holdTime);

    digitalWrite(progPin, HIGH);
    digitalWrite(upPin, HIGH);
    digitalWrite(downPin, HIGH);
    digitalWrite(myPin, HIGH);
    digitalWrite(selectPin, HIGH);
    digitalWrite(ledPin, LOW);

    delay(holdTime);
  }

  holdTime = 0;
  repeatSend = 0;

  Serial.println("done.");
}

Berichten: 3
Geregistreerd: 02 Jul 2020, 16:25

Re: Arduino Nano Somfy serial

Berichtdoor Eugene » 03 Jul 2020, 11:24

Het is gelukt! Het ging fout met het inlezen van de karakters ik heb nu de functie Serial.readString() gebruikt en de switch case in de loop geplaats. Toch bedankt voor jullie hulp. ;) ;) :D

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Bing [Bot], RussellAlets en 29 gasten