Arduino Interfacing via Lua - linux

I want to communicate with my Arduino. I have the Arduino IDE installed and if I use it, everything works perfectly fine. Here is my sketch:
const int ledPin = 11; // the pin that the LED is attached to
void setup() {
// initialize the serial communication:
Serial.begin(9600);
// initialize the ledPin as an output:
pinMode(ledPin, OUTPUT);
}
void loop() {
byte brightness;
// check if data has been sent from the computer:
if (Serial.available()) {
// read the most recent byte (which will be from 0 to 255):
brightness = (Serial.read()-48)*28;
// set the brightness of the LED:
analogWrite(ledPin, brightness);
Serial.println(brightness);
}
}
If I start the Serial Monitor now and type in "9", I get back an 252 and the LED jumps to full brightness. And if you type "0", the LED goes off!
This is what I wanted to recreate in Lua. I downloaded rs232 and then I wrote this script:
local rs232 = require "rs232"
local e, p = rs232.open('/dev/ttyACM0',{
baud = '_9600';
data_bits = '_8';
parity = 'NONE';
stop_bits = '_1';
flow_control = 'OFF';
rts = 'ON';
})
input=io.read()
p:write(input)
print(p:read(1))
p:close()
But nothing happens. Even without the p.read() part.
Please help.
PS: My system is Linux CentOS 7 and the board is a Uno

Related

Processing/Bluetooth to Arduino

I want to light up a LED wirelessly through processing.
what I have so far.
I can (wirelessly) turn on my LED using a serial terminal called "Bluterm".
I can turn on my LED by pressing 1 or 0 to switch LED on and off in processing.
How can I leave Bluterm out of my equation and use processing to send the 1 and 0 through bluetooth.
Here is my code for processing:
import processing.serial.*;
Serial port;
String string;
void setup(){
String portName = Serial.list()[2]; //change the 0 to a 1 or 2 etc. to match your port
port = new Serial(this, portName, 9600);
port.bufferUntil('\n');
}
void draw() {
printArray(string);
}
void keyPressed() {
if (key =='1'){port.write('1');}
if (key=='0') {port.write('0');}
}
void serialEvent(Serial port) {
string = port.readStringUntil('\n');}
and the Arduino code
char data;
int led = 13;
void setup() {
pinMode(led, OUTPUT);
Serial.begin(9600);
}
void loop() {
if (Serial.available()>0){
data = Serial.read();
}
if (data=='1'){
Serial.println("HELLO");
digitalWrite(led, HIGH);
}
else if (data=='0'){
digitalWrite(led, LOW);
Serial.println("BYE");}
}
I'm kind of lost, can processing talk to bluetooth or do I always need a terminal?
If something isn't clear pls don't hesitate to ask,
Thank you for your time,
Juriaan
The Processing code makes sense.
It could do with a bit of formatting and error checking, but it's all pretty much there:
import processing.serial.*;
Serial port;
String string = "";
void setup() {
String portName = Serial.list()[2]; //change the 0 to a 1 or 2 etc. to match your port
try{
port = new Serial(this, portName, 9600);
port.bufferUntil('\n');
}catch(Exception e){
e.printStackTrace();
}
}
void draw() {
background(0);
text(string,10,15);
}
void keyPressed() {
if(port != null){
if (key =='1') {
port.write('1');
}
if (key=='0') {
port.write('0');
}
}
}
void serialEvent(Serial port) {
string = port.readString();
if(string == null){
println("null serial string");
string = "";
}
}
The Arduino code looks legit too.
What's unclear is what Bluetooth module you're using and how you're setting it up.
For example, if you're using something like BlueSmirf, be sure to use the guide
supplied.
The main points are:
Make sure you're using the SerialPortProfile (SPP) Bluetooth Profile
Double check you're wiring: the way your Arduino code reads you would be connect BT module's TX to Arduino's RX pin 0 and BT module's RX pin to Arduino's TX pin 1. Note you may want to do that after you upload your firmware with Arduino (as pin's 0 and 1 are Arduino's hardware Serial), otherwise goto point 3 :) (recommeded)
If you use an Arduino with multiple hardware serial ports (like Arduino mega) go with those (e.g. Serial1 instead of Serial) otherwise use a SoftwareSerial library with a low baud rate (like 9600), avoiding high baud rates.
Update
The HC-05 module uses 3.3V logic, while the Arduino uses 5V logic.
Uses a bidirectional 3.3V <-> 5V logic level converter or resistors, otherwise you risk frying your HC-05 module:
A quick search returns a detailed HowToMechatronics.com Arduino and HC-05 Bluetooth Module Tutorial
i see u are using a hc05 bluetooth device i have this myself but i dont really get what u want to use for sending the 1 and 0 to your hc05 and are you only using a led becouse if it is i would be able to help on (if you wanna send the bluetooth signals with a mobile app try the blynk app fron app store or google play store)

ESP8266 / Arduino modbus RTU Buffer data conversion

I am using ESP8266 and ModbusMaster.h library to communicate with RS485 enabled power meter. Communication works fine but responses are the ones are confusing me and I can not get correct values. My power meter shows 1.49 kWh but response from Modbus is 16318. Here is my code:
#include <ArduinoOTA.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <ModbusMaster.h>
#include <ESP8266WiFi.h>
/*
Debug. Change to 0 when you are finished debugging.
*/
const int debug = 1;
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
int timerTask1, timerTask2, timerTask3;
float battBhargeCurrent, bvoltage, ctemp, btemp, bremaining, lpower, lcurrent, pvvoltage, pvcurrent, pvpower;
float stats_today_pv_volt_min, stats_today_pv_volt_max;
uint8_t result;
// this is to check if we can write since rs485 is half duplex
bool rs485DataReceived = true;
float data[100];
ModbusMaster node;
SimpleTimer timer;
// tracer requires no handshaking
void preTransmission() {}
void postTransmission() {}
// a list of the regisities to query in order
typedef void (*RegistryList[])();
RegistryList Registries = {
AddressRegistry_0001 // samo potrosnju
};
// keep log of where we are
uint8_t currentRegistryNumber = 0;
// function to switch to next registry
void nextRegistryNumber() {
currentRegistryNumber = (currentRegistryNumber + 1) % ARRAY_SIZE( Registries);
}
void setup()
{
// Serial.begin(115200);
Serial.begin(9600, SERIAL_8E1); //, SERIAL_8E1
// Modbus slave ID 1
node.begin(1, Serial);
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
// WiFi.mode(WIFI_STA);
while (Blynk.connect() == false) {}
ArduinoOTA.setHostname(OTA_HOSTNAME);
ArduinoOTA.begin();
timerTask1 = timer.setInterval(9000, updateBlynk);
timerTask2 = timer.setInterval(9000, doRegistryNumber);
timerTask3 = timer.setInterval(9000, nextRegistryNumber);
}
// --------------------------------------------------------------------------------
void doRegistryNumber() {
Registries[currentRegistryNumber]();
}
void AddressRegistry_0001() {
uint8_t j;
uint16_t dataval[2];
result = node.readHoldingRegisters(0x00, 2);
if (result == node.ku8MBSuccess)
{
for (j = 0; j < 2; j++) // set to 0,1 for two
datablocks
{
dataval[j] = node.getResponseBuffer(j);
}
terminal.println("---------- Show power---------");
terminal.println("kWh: ");
terminal.println(dataval[0]);
terminal.println("crc: ");
terminal.println(dataval[1]);
terminal.println("-----------------------");
terminal.flush();
node.clearResponseBuffer();
node.clearTransmitBuffer();
} else {
rs485DataReceived = false;
}
}
void loop()
{
Blynk.run();
// ArduinoOTA.handle();
timer.run();
}
I have tried similar thing but with Raspberry Pi and USB-RS485 and it works.
Sample of NodeJS code is below. It looks similar to Arduino code.
// create an empty modbus client
var ModbusRTU = require("modbus-serial");
var client = new ModbusRTU();
// open connection to a serial port
client.connectRTUBuffered("/dev/ttyUSB0", { baudRate: 9600, parity: 'even' }, read);
function write() {
client.setID(1);
// write the values 0, 0xffff to registers starting at address 5
// on device number 1.
client.writeRegisters(5, [0 , 0xffff])
.then(read);
}
function read() {
// read the 2 registers starting at address 5
// on device number 1.
console.log("Ocitavanje registra 0000: ");
client.readHoldingRegisters(0000, 12)
.then(function(d) {
var floatA = d.buffer.readFloatBE(0);
// var floatB = d.buffer.readFloatBE(4);
// var floatC = d.buffer.readFloatBE(8);
// console.log("Receive:", floatA, floatB, floatC); })
console.log("Potrosnja u kWh: ", floatA); })
.catch(function(e) {
console.log(e.message); })
.then(close);
}
function close() {
client.close();
}
This code displays 1.493748298302 in console.
How can I implement this var floatA = d.buffer.readFloatBE(0); in Arduino? Looks like that readFloatBE(0) does the trick, but available only in NodeJS / javascript.
Here i part of datasheet for my device
Here is what I am getting as result from original software that came with device:
If someone could point me in better direction I would be thenkfull.
UPDATE:
I found ShortBus Modbus Scanner software and tested readings.
Library read result as Unsigned integer, but need Floating Point and Word Order swapped. It is shown on image below.
Can someone tell how to set proper conversion please.
Right, so indeed the issue is with the part done by var floatA = d.buffer.readFloatBE(0);Modbus returns an array of bytes, and the client has to interpret those bytes, ideally done by the library you're using, but if not available on Arduino, you may try manually with byte decoding functions, with the following considerattions:
Modbus registers are 16 bit in length, so length 1 = 16 bits, length
2 = 32 bits, hence the data type noted on the docs as float32 means
"2 registers used for this value, interpret as float".
Therefore, on client.readHoldingRegisters(0000, 12)you're asking to read the register with address 00, and size 12... so this makes no sense, you only need 2 registers.
On your sample Node code, first you're writing
2 registers to address 5 in client.writeRegisters(5, [0 , 0xffff])
register 5 = 0, and register 6 = 0xFFFF, why? Then you go and read
from address 0, in read(), which is the address for Total KwH per
your docs.
So, you should get an array of bytes, and you need to
decode them as a float. Modbus is Big Endian for words and bytes, so
you need to use those in the decoding functions. I don't know exactly
what is available in Arduino, but hopefully you can figure it out
with this extra info.
I suppose that if you just send the buffer to print, you'll get an integer interpretation of the value, hence the problem

Arduino transmission Data by HC-05(Bluetooth)

platform:Arduino UNO, Arduino Mega2560, HC-05
Here shows the detail.
In Arduino UNO(Master), I encode
Serial.print("A 1 2 3 4 5;");
In Arduino Mega2560(slave), I encode
void setup()
{
//connect to the PC
Serial.begin(9600);
//connect to the Arduino UNO(By bluetooth)
Serial1.begin(38400);
}
void loop()
{
//its value > 0
Serial.println(Serial1.available());
//output : 128 or 248
Serial.print(Serial1.read());
delay(1000);
}
The value of Serial.available() > 0 is true,
but the print result of Serial.print(Serial1.read()); is abnormal. it print
I want to know the reason and its solution.Thanks!
I'm assuming that you made sure that both the Bluetooth devices are connected properly and the baud rates are matched.
Now, one problem might be the buffer might be full. On the sender's side, provide a delay equal to or slightly higher than the delay on the receiver's side.
Next, on the receiver side, change void loop to this:
void loop(){
if(Serial1.avaialable() > 0){
char value = Serial1.read();
Serial.println(value);
delay(1000);
}
}

Bluetooth Mate Gold connected to Arduino Mega not Receiving Data from Tera Term

I'm having trouble communicating between Tera Term and an Arduino Mega over a bluetooth connection. My goal is to be able to set up the Mega so it can be later used to exchange text commands with a C++ application. Using the code I've found on this site, I can use the Arduino IDE Serial Monitor to send text to the Tera Term terminal, but I cannot send text from the Tera Term terminal to the Arduino. It never recognizes text was sent from the terminal. The bluetooth module I am using is the Bluetooth Mate Gold from SparkFun. The code's purpose is to detect incoming chars and then activate an LED. My code is shown below:
#include <SoftwareSerial.h>
int bluetoothTx = 15;
int bluetoothRx = 14;
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
void setup() {
pinMode(13, OUTPUT);
//Setup usb serial connection to computer
Serial.begin(9600);
//Setup Bluetooth serial connection to android
bluetooth.begin(115200);
bluetooth.print("$$$");
delay(100);
bluetooth.println("U,9600,N");
bluetooth.begin(9600);
}
void loop() {
//Read from bluetooth and write to usb serial
if(bluetooth.available()) {
char toSend = (char)bluetooth.read();
Serial.print(toSend);
flashLED();
}
//Read from usb serial to bluetooth
if(Serial.available()) {
char toSend = (char)Serial.read();
bluetooth.print(toSend);
flashLED();
}
}
void flashLED() {
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
}
The only thing that seems to work from Tera Term is entering command mode using "$$$." Doing that, I can run commands such as "D." I'm not sure why I can't send chars from Tera Term to the Arduino and have them be read. Any suggestions are appreciated.
I just built the same thing and i had to add a delay of 500 ms before configuring the module. I also had problems with receiving data since i used pin that did not support the PCINT interrupt.
delay(500);
bluetooth.begin(115200);
bluetooth.print("$");
bluetooth.print("$");
bluetooth.print("$");
delay(100);
bluetooth.println("U,9600,N");
bluetooth.begin(9600);

What do I add to this code to make the audio play out of my PC speakers via Arduino?

I am running this code on an Arduino. Using the Arduino, is there a way to pass the audio to my PC speakers?
//This imports the audio class
#include <PCM.h>
//This is the sound being played
const unsigned char sound1[] PROGMEM = {129, 127, 126, 127, 128, 128, 128, 12};
//constant variables
const int knockSensor = A0;
const int threshold1 = 10;
//This create a variable
int sensorReading = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
sensorReading = analogRead(knockSensor);
if (sensorReading >= threshold1) {
Serial.println(threshold1);
startPlayback(sound1, sizeof(sound1));
}
delay(200);
}
Assuming that the Arduino board isn't physically connected to your PC, you should send the value Arduino is reading to PC, via Serial. A program running at the PC would get this values via seria port and could, then, use the Operating System to play that data as sound. If you're on Linux that would be really easy, by writting data to /dev/audio

Resources