Access Linno from outside web client without going through a Sketch

Hi All,

  1. Is it possible to communicate to Linno directly from outside web client without going through a Sketch ? Is this possible in current Yun Architecture ?

  2. Added to this, Is it possible to perform Restart, Pause and Stop the ATmega32U4 processor from Linnio.
    Please direct me to documentation on this.

Thanks in Advance.

Regards,

BREL

HI

you can controll all IO's on the 32u4 side from the linino side via bridge.
i do this in my project.
You can do it with php, phyton ........
And with linino as webserver you can route it to the world :slight_smile:

Hi OttoF,

Thanks for the reply.

From your example,
Understanding is that YunServer is running from the Sketch ( it is initiated inside sketch). Most of Bridge communication is from Sketch Atmeg32U4 to Linino.
But I want an example of Linino talking to Sketch code or Atmega32U4
Is there an example of Bridge.Trasfer() API from linino to Atmega

Thanks

Regards
BREL

you can use the bridgeclient for php
download from here

this php script reads a sql database it runs every minute
and send the commands for io to 32u4

<?php

include_once ("bridgeclient.class.php");

$client = new bridgeclient();

if ($client->get("modus") == "a")
{
      $db=new SQLite3("/www/sd/Aqarium/Aquarium.db");

      $SQL = "select * from sollwertelicht order by Schaltzeit_ts";
      $resultSollwerteLicht = $db->query($SQL);

      $Sollwerte[10];
      $Dimmzeiten[10];

      for ($i = 1; $i <= 9; $i++) {
          $Sollwerte[$i] = 0;
          $Dimmzeiten[$i] = 0;
      }


      date_default_timezone_set('Europe/Berlin');
      //echo "Uhrzeit ".Date('H:i:s')." TS = ";
      $TS = Date('H') * 3600;
      $TS = $TS + (Date('i') * 60);
      $TS = $TS + Date('s');


      while ($SollwerteLicht = $resultSollwerteLicht->fetchArray()){

          if ($TS >= $SollwerteLicht[Schaltzeit_ts])
          {
             $Sollwerte[$SollwerteLicht[Kanalnummer]] = round($SollwerteLicht[Sollwert]*2.54);
             $Dimmzeiten[$SollwerteLicht[Kanalnummer]]= $SollwerteLicht[Dimmzeit];
          }
      }


      for ($i = 1; $i <= 9; $i++) {
          $Senden = $Senden.$i."#".$Senden.str_pad($Sollwerte[$i], 3, "0", STR_PAD_LEFT)."#".str_pad($Dimmzeiten[$i], 3, "0", STR_PAD_LEFT)."#";
          $client->put("command",$Senden);
          $Senden = "";
           usleep(100000); // 100000 µsec = 100 ms
      }


}

?>

and here my code from 32u4 to work with the datas from linino side

see the bridge.get and bridge.put commands

#include <Bridge.h>
#include <string.h>
#include <Process.h>

char data_r[11];

String Dummy = String(11);
String puffer = String(11);
int Kanal;

int datenlaenge;
int Fehlerzaehler;
int p_datenlaenge;

String istwerte;
String last_istwerte;

String Wert[10];
String Dimmzeit[10];

float Sollwert[10];
float LetzterSollwert[10];
float DiffSollwert[10];

float Regelwert[10];
float Dimmfaktor[10];
int KanalPin[8];

int SDimmzeit;
float FDimmzeit;


unsigned long time1;
unsigned long time2;
boolean sekundenimpuls;


void setup() {

  KanalPin[1] = 3;
  KanalPin[2] = 5;
  KanalPin[3] = 6;
  KanalPin[4] = 9;
  KanalPin[5] = 10;
  KanalPin[6] = 11;
  KanalPin[7] = 13;

  pinMode(13,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(3,OUTPUT);

  pinMode(A0, INPUT_PULLUP);
  pinMode(A1, OUTPUT); 
  pinMode(A2, OUTPUT); 
  pinMode(A3, OUTPUT); 
  pinMode(A4, OUTPUT); 
  pinMode(A5, OUTPUT); 

  digitalWrite(A5,HIGH);
  
  Bridge.begin();
  
  digitalWrite(A5,LOW);

  delay(1000);

  Bridge.put("handshake", "Bridge ok");
  delay(500);

  time1 = millis();
  time2 = time1;
  Process p;
  p.runShellCommand("/usr/bin/php-cli /www/sd/Aqarium/Automatik_cron.php"); 

}

void loop() {
  
  time1 = millis();
  if(time1 < time2){time2 = time1;}
  if ((time1 - time2) > 1000){sekundenimpuls = true; time2 = time1;}
  
  
  digitalWrite(A5,LOW);

  p_datenlaenge = Bridge.get("command",data_r,11); // kommt von Automatik_cron.php oder Manuell.php
  delay(10);

  digitalWrite(A5,HIGH);

  puffer = data_r;
  datenlaenge = puffer.length();

  if (datenlaenge > 0 && datenlaenge != 10)
  { 
    Fehlerzaehler = Fehlerzaehler + 1;
    Bridge.put("handshake", puffer + " Laenge " + String(datenlaenge) + " Fehlerx " + String(Fehlerzaehler) + " millis " + String(time1));
    delay(10);
  
  }
  

  if (datenlaenge == 10 )  // Neue Sollwerte übernehmen
  {
      Dummy = strtok(data_r,"#");
      Kanal = stringTOint(Dummy);

      Dummy = strtok(NULL,"#");
      Wert[Kanal] = Dummy;

      Dummy = strtok(NULL,"#");
      Dimmzeit[Kanal] = Dummy;

      LetzterSollwert[Kanal] = Sollwert[Kanal];
      Sollwert[Kanal] = stringTOint(Wert[Kanal]);

      if(LetzterSollwert[Kanal] > Sollwert[Kanal])
      {
        DiffSollwert[Kanal] = LetzterSollwert[Kanal] - Sollwert[Kanal];
      }
      if(LetzterSollwert[Kanal] < Sollwert[Kanal])
      {
        DiffSollwert[Kanal] = Sollwert[Kanal] - LetzterSollwert[Kanal];
      }
      
      SDimmzeit = stringTOint(Dimmzeit[Kanal]);
      FDimmzeit = float(SDimmzeit);
                
      if (SDimmzeit > 0)
      {
        Dimmfaktor[Kanal] = DiffSollwert[Kanal] / (FDimmzeit * 60);
      }else{
        Regelwert[Kanal] = Sollwert[Kanal];
      }
    
      Bridge.put("command","");
      delay(10);
  }


// Regelung PWM

if (sekundenimpuls)
{ 

  for(int i = 1; i <=7; i++)
  {
      if (Regelwert[i] < Sollwert[i])
      {
            if (Regelwert[i] + Dimmfaktor[i] > Sollwert[i])
                {
                  Regelwert[i] = Sollwert[i];
                }else{
                  Regelwert[i] = Regelwert[i] + Dimmfaktor[i];
                }
      }
      if (Regelwert[i] > Sollwert[i])
      {
            if (Regelwert[i] - Dimmfaktor[i] < Sollwert[i])
                {
                  Regelwert[i] = Sollwert[i];
                }else{
                  Regelwert[i] = Regelwert[i] - Dimmfaktor[i];
                }
      }
      analogWrite(KanalPin[i],int(Regelwert[i]));
  }

}

// Netzteile ein für Regelkanäle

  if (int(Regelwert[1]) > 0 || int(Regelwert[2]) > 0 || int(Regelwert[3]) > 0)
  {digitalWrite(A1,HIGH);}else{digitalWrite(A1,LOW);}

  if (int(Regelwert[4]) > 0 || int(Regelwert[5]) > 0 || int(Regelwert[6]) > 0  || int(Regelwert[7]) > 0)
  {digitalWrite(A2,HIGH);}else{digitalWrite(A2,LOW);}

// Schaltkanäle

  if (int(Sollwert[8]) > 0 )
  {digitalWrite(A3,HIGH);}else{digitalWrite(A3,LOW);}
  
  if (int(Sollwert[9]) > 0 )
  {digitalWrite(A4,HIGH);}else{digitalWrite(A4,LOW);}
  

// Istwertausgabe

 

  istwerte = "";
  for(int i = 1; i <=9; i++)
  {
     istwerte = istwerte + String(map(Regelwert[i],0,254,0,100))+ "#";
  }


  if (last_istwerte != istwerte)
  {
    last_istwerte = istwerte;
    Bridge.put("istwerte",istwerte);
    delay(10);
  }

/*  
 if(p_datenlaenge > 0)
 {
 
    Bridge.put("datenlaenge",String(p_datenlaenge));
    delay(10);
 
 }
*/

  sekundenimpuls = false;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int stringTOint(String wert)
{
  char carray[wert.length() + 1]; //determine size of the array
  wert.toCharArray(carray, sizeof(carray)); //put Stringinto an array
  int erg = atoi(carray); //convert the array into an Integer 
  return erg;
}

Super.

Thank you very much OttoF

Regards

BREL

As far as restart, stop and start control the documentation is the schematic for the Yun which is here:

Combined with some info on how to use the gpio's which I found here:

WARNING This is low level stuff, there are few if any protections if you do stupid things with gpio's. For instance I don't know what would happen if you set a gpio to output when it is wired as a input. It is quite possible you would burn it out if you set it low on the software side while it was held high by the connected hardware. The AR9331 datasheet might give this information. Don't go blindly monkeying around with the gpio's

So, we know that gpio18 is hooked to the 32U4 reset line. To set it up for output you need to:

echo 18 > /sys/class/gpio/export
echo out>/sys/class/gpio/gpio18

To stop the 32U4, pull the reset high

echo 1>/sys/class/gpio/gpio18

To start it again, pull the reset low

echo 0>/sys/class/gpio/gpio18

and a restart would be a stop and start combined

echo 1>/sys/class/gpio/gpio18
echo 0>sys/class/gpio/gpio18

If you are going to be doing this much you would probably want to make scripts to perform these functions.

I don't see a mechanism to pause/continue.

Cool.

Thank you very much NoblePepper.

Much appreciated

Kind Regards

Srini Murthy

You can also reset the mcu from the linino side with the reset-mcu command.

I should have remembered that, it would have saved me some research on how to make gpio's work, duh.

It's a premade script to do what I did the hard way:

#!/bin/sh

echo 18 > /sys/class/gpio/export
echo "high" > /sys/class/gpio/gpio18/direction
echo 1 > /sys/class/gpio/gpio18/value
echo 0 > /sys/class/gpio/gpio18/value
echo 18 > /sys/class/gpio/unexport

Hi NoblePepper and Newline,

Thank you very much for the reply

  1. I donot see gpio18 directory under /sys/class/gpio/. All I have is : export, gpio21, gpio22, gpio23, gpiochip0, and unexport directories. Am I missing some thing here. ( kindly see the image attached)

  2. similar to reset-mcu: Is there a command for just stop and pause.

Thanks and Regards
BREL

Hi NoblePepper and Newline,

Sorry, I did not read the first line

echo 18 > /sys/class/gpio/export. This creates gpio18 directory.

Regarding reset-mcu is there a one for stop

Thanks

BREL

Hi NoblePepper,

You mentioned these commands :
echo 1>/sys/class/gpio/gpio18
echo 0>sys/class/gpio/gpio18

You meant these right
echo 1>/sys/class/gpio/gpio18/value
echo 0>sys/class/gpio/gpio18/value

Please confirm

Thanks
BREL

Yes, the proper commands are

echo 1>/sys/class/gpio/gpio18/value
echo 0>sys/class/gpio/gpio18/value

, bad/lazy typing on my part.

For the script, I'll call it stop-mcu, start a console session on the Yun use either PuTTY on windows or picocom on linux.
Once you are in do this:

cd /usr/bin
cp reset-mcu stop-mcu
vim stop-mcu

delete the line that starts with echo 0 and save the file
If you aren't familiar with vim a lot of people find nano easier to work with, just opkg install nano and use it.

I think to "pause" a running sketch on the Leonardo side you need to get into the world of hardware debuggers using JTAG.

NoblePepper,

Thank you so much for all your help.

I am truly grateful,

regards

BREL