Blynk on Udoo Neo running!

Whatever this does, it does in the CLI window as a separate child process (if I understand correctly)… I have no idea how you would get any value response back from it into your script.

DOH!
I really want this board working with blynk beacuse I spent almost 300 € in hardware for a water level project…
Is there a way to map the CLI output to the virtual pin like you did here:

 var myValue = // use whatever command to setup your devices GPIO input to this variable

 // Automatically update sensor value every 2 seconds
 setInterval(function() {
  // use whatever command to read your GPIOs variable... in this case myValue
  blynk.virtualWrite(0, myValue);  // Send the value of the variable myValue to a Widget on V0
}, 2000);

But I didn’t do anything with CLI or child processes there. That was just a dummy example to show the Blynk and timer relevant parts. Besides…

Yes, it has been a whole hour, but I still don’t know how :blush:

I would focus on running the relevant GPIO commands INSIDE your script. I did briefly poke around at that boards documentation, but again without the hardware in hand (and a nice dark room with LCD light for days on end :stuck_out_tongue_winking_eye: ) I really have no idea how to interpret or control that boards GPIO from Linux.

Perhaps you might consider spending about $10-$30 more and getting an ESP8266, ESP32 or even a lower cost RPi like the ZeroW or 3 Model A+ - Buy a Raspberry Pi – Raspberry Pi

Much more support, particularly for the ESP lineup and C++ code with Blynk. But even the RPis have a metric butt ton of community support on the web.

I understand your point of view but my choice has been influenced by many factors, you can make yourself an idea in this previous post.
Anyway I’ll try to call the value inside the script as you said and will see.
Thank you for your support my friend!

Ah, ethernet… well the RPi model 3B+ has that - https://www.raspberrypi.org/products/raspberry-pi-3-model-b-plus/

I am running the slightly older RPi 3B on Ethernet, with Blynk and lots of GPIO connections…

You would still be using Linux… getting things done with more backup and support availed. And as you gain in experience, you will be able to transfer that to your UDOO board as well… so no real losses at all.

I know and I was decided to buy it but then I would have to use something to convert my 12 V POE supply to 5 V, instead with the Udoo I can power the board and the sensor with one ethernet cable only. :slight_smile:

Yes, I saw that, but that is a relatively easy fix… Although I am unsure why you have 12v POE… generally it is 48v… higher voltage means less loss over distance.

EDIT - looks like this was already suggested…

Double EDIT - this one goes to 5v with micro USB.

But it seems that learning to manage that fansnazy board’s dual-personality GPIO the way you want… not so much simple :stuck_out_tongue_winking_eye:

Anyhow, it was just a suggestion.

Yes this has 48 V on the injector side but 12 V on the splitter because the sensor only allows 9-32 V range.
And I knew I would have to do an extra effort somwhere else for having the hardware so easy to setup, even if I have to code a new libray for handling the pins, I’ll do that so others can benefit also.

1 Like

But once it is done, it is done… you could take your device end POE, make up a basic power distribution board that splits off 12v for the sensor and 5v for the MCU, and never touch it again! Also potentially allows for easy switching or adding of other sensors or MCUs down the road should you need (within current limits of course)… Just saying… lots of ways to pet the kitty (I like cats, so no skinning :stuck_out_tongue_winking_eye: )

I managed to put together this lua code that should be able to incorporate the value, but because of a colon inside the string to call i get this error. :face_with_head_bandage:

#!/usr/bin/env lua

--[[
  This is the default example for Linux, Windows, OpenWrt
]]

local socket = require("socket")
local use_ssl, ssl = pcall(require, "ssl")

local Blynk = require("blynk.socket")
local Timer = require("timer")

assert(#arg >= 1, "Please specify Auth Token")
local auth = arg[1]

local blynk = Blynk.new(auth, {
  heartbeat = 10, -- default h-beat is 30
  --log = print,
})

local function connectBlynk()
  local host = "blynk-cloud.com"

  local sock = assert(socket.tcp())
  sock:setoption("tcp-nodelay", true)

  if use_ssl then
	print("Connecting Blynk (secure)...")
	sock:connect(host, 443)
	local opts = {
	  mode = "client",
	  protocol = "tlsv1"
	}
	sock = assert(ssl.wrap(sock, opts))
	sock:dohandshake()
  else
	print("Connecting Blynk...")
	sock:connect(host, 80)
  end

  -- tell Blynk to use this socket
  blynk:connect(sock)
end

blynk:on("connected", function(ping)
  print("Ready. Ping: "..math.floor(ping*1000).."ms")
  -- whenever we connect, request an update of V1
  blynk:syncVirtual(1)
end)

blynk:on("disconnected", function()
  print("Disconnected.")
  -- auto-reconnect after 5 seconds
  socket.sleep(5)
  connectBlynk()
end)

function exec_out(cmd)
  local file = io.popen(cmd)
  if not file then return nil end
  local output = file:read('*all')
  file:close()
  -- print("Run: "..cmd.." -> "..output)
  return output
end

function read_file(path)
  local file = io.open(path, "rb")
  if not file then return nil end
  local content = file:read "*a"
  file:close()
  -- print("Read: "..path.." -> "..content)
  return content
end

function getArpClients()
  return tonumber(exec_out("cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw"))
end

function getUptime()
  return tonumber(exec_out("cat /proc/uptime | awk '{print $1}'"))
end

-- callback to run when V1 changes
blynk:on("V1", function(param)
  print("V1:", tonumber(param[1]), tonumber(param[2]))
end)

-- callback to run when cloud requests V2 value
blynk:on("readV2", function(param)
  blynk:virtualWrite(2, os.time())
end)

-- create a timer to update widget property
local tmr1 = Timer:new{interval = 5000, func = function()
  blynk:setProperty(2, "label", os.time())
end}

local tmr2 = Timer:new{interval = 5*60*1000, func = function()
  blynk:virtualWrite(10, getArpClients())
  blynk:virtualWrite(11, string.format("%.1f h", getUptime()/60/60))
end}

connectBlynk()

while true do
  blynk:run()
  tmr1:run()
end

I know nothing about Lua…

Are you sure it is the colon that is causing the issue (you have at least 4 of them in different print commands) and not some other misinterpreted escape sequence?

Reading this I found out that the backlash had to be escaped in order to be considered as a literal string because otherwise the parser treat it like a special character.

So now the script runs but I’m still not recieving any value on the app…

Are you confirming that data is even getting pulled back into the script, with CLI prints?

No, but I can confirm that the app works and is recieving the “os.time” on pin V2

EDIT:

I confirm, data is getting pulled back into the script with CLI prints!

For today I had enough, time to head to bed, at least one little step forward was made :confused:

EUREKA!

	#!/usr/bin/env lua

--[[
  This is the default example for Linux, Windows, OpenWrt
]]

local socket = require("socket")
local use_ssl, ssl = pcall(require, "ssl")

local Blynk = require("blynk.socket")
local Timer = require("timer")

assert(#arg >= 1, "Please specify Auth Token")
local auth = arg[1]

local blynk = Blynk.new(auth, {
  heartbeat = 10, -- default h-beat is 30
  --log = print,
})

local function connectBlynk()
  local host = "blynk-cloud.com"

  local sock = assert(socket.tcp())
  sock:setoption("tcp-nodelay", true)

  if use_ssl then
	print("Connecting Blynk (secure)...")
	sock:connect(host, 443)
	local opts = {
	  mode = "client",
	  protocol = "tlsv1"
	}
	sock = assert(ssl.wrap(sock, opts))
	sock:dohandshake()
  else
	print("Connecting Blynk...")
	sock:connect(host, 80)
  end

  -- tell Blynk to use this socket
  blynk:connect(sock)
end

function exec_out(cmd)
  local file = io.popen(cmd)
  if not file then return nil end
  local output = file:read('*all')
  file:close()
  -- print("Run: "..cmd.." -> "..output)
  return output
end

function read_file(path)
  local file = io.open(path, "rb")
  if not file then return nil end
  local content = file:read "*a"
  file:close()
  -- print("Read: "..path.." -> "..content)
  return content
end

function getArpClients()
  return tonumber(exec_out('cat /sys/bus/iio/devices/iio\\:device0/in_voltage0_raw'))
end

function getUptime()
  return tonumber(exec_out("cat /proc/uptime | awk '{print $1}'"))
end

-- callback to run when V1 changes
blynk:on("V1", function(param)
  print("V1:", tonumber(param[1]), tonumber(param[2]))
end)

-- callback to run when cloud requests V2 value
blynk:on("readV2", function(param)
  blynk:virtualWrite(2, os.time())
end)

-- create a timer to update widget property
local tmr1 = Timer:new{interval = 5000, func = function()
 blynk:virtualWrite(10, getArpClients())
 blynk:virtualWrite(11, string.format("%.1f h", getUptime()/60/60))
end}

connectBlynk()

while true do
  blynk:run()
  tmr1:run()
end

No more unsupported board!

1 Like

me too :joy:
and I ask myself why to use Lua :fearful:

Well, I am glad you understand whatever solved your issue :blush: If you can, would you mind explaining a little bit about what the solution was? Thanks.

1 Like

Yes, basically as I stated in previuos post

but then, as you can see by my CLI screenshot it wasn’t enough because it seemed that the command was passed correctly but not executed, so that took me a few head bangs and most of the day to figure out why, since copying and pasting manually from the output of the lua script returned the value properly, while executing it didn’t .

In few words reading this carefully and again and again brought me to the not so explicit way of passing the command even without escaping the special char (backlash).
Best solution is to enclose the string inside double square brackets so the parser treats it as non lua code (still can be code for other language, html page for example).

Now I only have to map the voltage that I’m receiving to the sensor depth range and ad few other math calculations before deploying everything in place.

Thanks for now.

Lawrence

1 Like

DONE!

2 Likes