Serial communication with arduino using nodejs - javascript

Im trying to control the arduino via using nodejs. My problem is that im trying to write an interger to the arduino but the value won't register. Can any1 help ?
The node.js serial communication code:
var serialport = require("serialport");
var SerialPort = serialport.SerialPort;
var serialPort = new SerialPort("/dev/cu.usbmodem14131", {
baudrate: 9600,
parser: serialport.parsers.readline("\n")
});
serialPort.on("open", function () {
console.log('open');
serialPort.write("45/r/n") // wrinting offset value to the arduino
serialPort.on('data', function(data) {
console.log(data);
});
});
Here the arduino code"
#include <Wire.h>
int offset = 0;
String inString = "";
void setup()
{
Serial.begin(9600);
delay(100);
}
void loop(){
Serial.println(offset); //printing the offset
while (Serial.available() > 0) {
int inChar = Serial.read();
// convert the incoming byte to a char
// and add it to the string:
inString += (char)inChar;
// if you get a newline, print the string,
// then the string's value:
if (inChar == '\n') {
Serial.print("Offset:");
Serial.println(inString.toInt());
offset = inString.toInt();
// clear the string for new input:
inString = "";
}
}
delay(1000);
}
I'm not really sure if i'm writing the value the wrong way or receiving it wrong, but arduino code work fine if I manually enter the value in the arduino IDE.
Thank you.

I'm not sure about your nodejs code but I think there is an issue with the arduino routine. I did notice your nodejs routine is sending /r/n and the Arduino routine is only looking for /n.
The while loop you have can completely execute in less then one serial character time so it may be adding 1 second delays between characters.
I would structure it to stay in the while loop until a newline is received. Following example has not been compiled, but demostrates the concept. It also filters out the '/r' character.
int inChar;
void loop(){
// clear the string for new input:
inString ="";
inChar=0;
while (inchar!= '\n') {
while (Serial.available() > 0) {
inchar = Serial.read();
// do you need to filter the '/r' for it to work correctly?
if (inchar != '/r') {
// convert the incoming byte to a char
// and add it to the string:
inString += (char)inChar;
}
}
}
// when you receive a newline, print the label and
// the string's value:
Serial.print("Offset:");
Serial.println(inString.toInt());
offset = inString.toInt();
delay(1000);
}

Related

Solidity and web3 sha3

I try to hash a tokenId with a seed in my smart contract. For simplicity and to avoid other errors I leave the seed out for now. I basically just want to hash a number on my contract and hash the same number on my javascript code and receive the same output.
Code looks something like this on Solidity:
function _tokenURI(uint256 tokenId) internal view returns (string memory) {
string memory currentBaseURI = _baseURI();
bytes32 hashedToken = keccak256(abi.encodePacked(tokenId));
return
bytes(currentBaseURI).length > 0
? string(abi.encodePacked(currentBaseURI, hashedToken, baseExtension))
: "";
}
which also leads to an error on client side invalid codepoint at offset. To tackle this I tried to cast bit32 to string using these functions
function _bytes32ToString(bytes32 _bytes32)
private
pure
returns (string memory)
{
uint8 i = 0;
bytes memory bytesArray = new bytes(64);
for (i = 0; i < bytesArray.length; i++) {
uint8 _f = uint8(_bytes32[i / 2] & 0x0f);
uint8 _l = uint8(_bytes32[i / 2] >> 4);
bytesArray[i] = _toByte(_f);
i = i + 1;
bytesArray[i] = _toByte(_l);
}
return string(bytesArray);
}
function _toByte(uint8 _uint8) private pure returns (bytes1) {
if (_uint8 < 10) {
return bytes1(_uint8 + 48);
} else {
return bytes1(_uint8 + 87);
}
}
though I'm not sure if this is equivalent. Code on the frontend looks like:
const hashed = web3.utils.soliditySha3(
{ type: "uint256", value: tokenId}
);
What do I need to change in order to receive the exact same output? And what does
invalid codepoint at offset
mean?
Maybe issue is that tokenId is not uint256 or Web3, Solidity version? I did few tests with Remix IDE and I recieved the same results.
Solidity code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Hash {
function getHashValue_1() public view returns(bytes32){
return keccak256(abi.encodePacked(uint256(234)));
}
// bytes32: 0x61c831beab28d67d1bb40b5ae1a11e2757fa842f031a2d0bc94a7867bc5d26c2
function getHashValue_3() public view returns(bytes32){
return keccak256(abi.encodePacked(uint256(10),string('StringSecretValue')));
}
// bytes32: 0x5938b4caf29ac4903ee34628c3dc1eb5c670a6bd392a006d0cb91f1fc5db3819
}
JS code:
(async () => {
try {
console.log('Web3 version is '+ Web3.version);
// Web3 version is 1.3.0
let theValueYouNeed = web3.utils.soliditySha3("234");
theValueYouNeed = web3.utils.soliditySha3({type: 'uint256', value: '234'});
theValueYouNeed = web3.utils.soliditySha3({t: 'uint256', v: '234'});
// above hashed value is 0x61c831beab28d67d1bb40b5ae1a11e2757fa842f031a2d0bc94a7867bc5d26c2
console.log('Hashed value 1 is '+theValueYouNeed);
theValueYouNeed = web3.utils.soliditySha3({t: 'uint256', v: '10'},{t: 'string', v: 'StringSecretValue'});
console.log('Hashed value 2 is '+theValueYouNeed);
// above hashed value is 0x5938b4caf29ac4903ee34628c3dc1eb5c670a6bd392a006d0cb91f1fc5db3819
} catch (e) {
console.log(e.message)
}
})()
I'm not sure but invalid codepoint at offset should mean that a designated value does not fall within the range or set of allowed values... So maybe there is something wrong with tokenId and you could do some tests with hardcoded values?
You get the invalid codepoint error because you mix string and byte data when you call abi.encodePacked(currentBaseURI, hashedToken, baseExtension)).
When Javascript gets the return value from the contract it expects a UTF8 string, but inside your hashedToken you have byte values that are not valid for a UTF8-encoded string.
This kind of error might be "intermittent". It might happen in just some cases. You're lucky to see it during development and not in production.
How to fix it?
You are on the right track converting the hash result to a string.
There is an alternative way to do it in this answer which uses less gas by using only bitwise operations.
To convert the hex value in Javascript you can use web3.utils.hexToNumberString().

adding regex int to a var

I'm trying to make a irc bot that takes input like this user: +1 I want to have a end result where I can have a main number being added to, from the # someone types with +#.
expected output: #x added: 1 rep: 1 executed[+] second execution
#x added: 1 rep: 2 executed[+]
actual output #x added: +1 rep: +1undefined executed[+] second is identical.
I've tried using Number(commandName), along with toString().replace(/\D\s/g,'') I got some promising results but they seemed to have some problems so I scrapped that code...
so in conclusion how can I add the numbers together and avoid the +?
const tmi = require('tmi.js');
// Define configuration options
const opts = {
identity: {
username: "x",
password: "x"
},
channels: [
"#x"
]
};
// Create a client with our options
const client = new tmi.client(opts);
// Register our event handlers (defined below)
client.on('message', onMessageHandler);
client.on('connected', onConnectedHandler);
// Connect to Twitch:
client.connect();
const totalnum = 0;
// Called every time a message comes in
function onMessageHandler(target, context, msg, self) {
if (self) {
return;
} // Ignore messages from the bot
// Remove whitespace from chat message
let commandName = msg.trim();
var regexadd = /([+]\d*)[^+\s]/;
// If the command is known, let's execute it
if (regexadd.exec(commandName)) {
var totalnum = addem(commandName, totalnum);
console.log(target, `added:`, commandName, `rep:`, totalnum, `executed[+]`)
} else {
console.log(`* Unknown command ${commandName}`);
}
function addem(x, y) {
return (x + y);
}
}
// Called every time the bot connects to Twitch chat
function onConnectedHandler(addr, port) {
console.log(`* Connected to ${addr}:${port}`);
}
I found a few things that appear to be wrong with your code:
You're not adding numbers. addem()'s first parameter is the name of the command, it should be the number captured in your regex capture group.
Your regex includes the + sign in the capture group, you probably wanted to exclude it
You should parse the result of exec to a hint either with ParseInt() or implicitly with +
You use RegExp.prototype.exec() instead of RegExp.prototype.match() to retrieve a capture group.
Here's what this could look like
var regexadd = /\+(\d*)[^+\s]/;
if (regexadd.exec(commandName)) {
var totalnum = addem(+commandName.match(regexadd)[1], totalnum);
console.log(target, `added:`, commandName, `rep:`, totalnum, `executed[+]`)
}
I also think it would be best to use RegExp.prototype.test() instead of RegExp.prototype.exec() for your if statement - you will limit results to true or false.

From Javascript Int to a Java String

So I have a variable in Javascript that can be both String and int, I need to send it to a java method. I though that, since it's easier to change a number into a string instead of the opposite, I set the variable into a string. I'm gonna post some code
This is obviously the javascript, the variable valore is the one that can be both Int and string
$(".save").click(function() {
var valore = $("#valore").val();
var connettore = $("#connettore option:selected").text().split(" ").join("");
$.get("select"+connettore+".do", {
nomecampo: $("#colonnaRiferim").val().toLowerCase(),
valore: valore
}, function (data) {
for (var i = 0; i < data.connettore.length; i++) {
var conn = data.connettore[i];
}
}
);
This is the Java function
#RequestMapping("selectCompensi")
#ResponseBody
#Transactional
public ModelWrapper<List<TracciatoCompensi>> selectCompensi(#RequestParam String nomecampo,
#RequestParam String valore){
Session s = hibernateFactory.getCurrentSession();
ModelWrapper<List<TracciatoCompensi>> resp = new ModelWrapper<List<TracciatoCompensi>>();
Criteria c = s.createCriteria(TracciatoCompensi.class)
.add(Restrictions.eq(nomecampo, valore));
List<TracciatoCompensi> aList = (List<TracciatoCompensi>) c.list();
Query query = s.createSQLQuery("INSERT INTO tracciato_compensi_clone (CODICEORDINE, CODICESERVIZIO, CODICEUNIVOCOCOMPONENTE, COEFFICIENTECANONEMESE, "+nomecampo+", compensi1, rev, mod_time, mod_user) ("
+"SELECT CODICEORDINE, CODICESERVIZIO, CODICEUNIVOCOCOMPONENTE, COEFFICIENTECANONEMESE, "+nomecampo+", "+nomecampo+", rev, mod_time, mod_user FROM tracciato_compensi WHERE "+nomecampo+" = '"+valore+"')");
resp.put("connettore", aList);
query.executeUpdate();
return resp;
}
You can ignore the Query, that stuff works, as so does the criteria and the rest. My problem seems obvious, if valore is numeric, then the function crash,
I tried to add a random character to the number, and I tried to convert it using toString() into javascript but even if I use the isNumeric() function of jquery and it says that it isn't numeric, it still crashes
The method you're looking for probably is String.valueOf(Object):
String valore1 = "5";
System.out.println(String.valueOf(valore1));
int valore2 = 5;
System.out.println(String.valueOf(valore2));
gives:
5
5
in the console.

Is there Any Way to Convert Mongo ObjectId into string by javascript/jquery

Is it possible to convert mongo objectId into string.
The above pictures shows data i received and shown in console.I need id value in string form .but ObjectId is returning as object
In Database id is look like this- 565d3bf4cefddf1748d1fc5e -objectId and i need id exactly like this –
According to the Mongo documentation:
a 4-byte value representing the seconds since the Unix epoch,
a 3-byte machine identifier,
a 2-byte process id, and
a 3-byte counter, starting with a random value.
You can check it out here: https://docs.mongodb.org/manual/reference/object-id/
So in javascript you could do something like this.
var mId = {
Timestamp:1448950573,
Machine:13565407,
Pid:1756,
Increment:8888962
};
function getId(mongoId) {
var result =
pad0(mongoId.Timestamp.toString(16), 8) +
pad0(mongoId.Machine.toString(16), 6) +
pad0(mongoId.Pid.toString(16), 4) +
pad0(mongoId.Increment.toString(16), 6);
return result;
}
function pad0(str, len) {
var zeros = "00000000000000000000000000";
if (str.length < len) {
return zeros.substr(0, len-str.length) + str;
}
return str;
}
console.log(getId(mId))
It produces "565d3b2dcefddf06dc87a282" which was not exactly the id you had, but that might just be a tweak or i was working with different data :D.
EDIT
Added a padding function so that zeros are not truncated.
Hope that helps
EDIT:
I assume you are using c# to connect to and serve documents from the mongo DB. In that case, there is a driver that also supports toString().
Here is an example using the mongo csharp driver:
using MongoDB.Bson;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
// ...
string outputFileName; // initialize to the output file
IMongoCollection<BsonDocument> collection; // initialize to the collection to read from
using (var streamWriter = new StreamWriter(outputFileName))
{
await collection.Find(new BsonDocument())
.ForEachAsync(async (document) =>
{
using (var stringWriter = new StringWriter())
using (var jsonWriter = new JsonWriter(stringWriter))
{
var context = BsonSerializationContext.CreateRoot(jsonWriter);
collection.DocumentSerializer.Serialize(context, document);
var line = stringWriter.ToString();
await streamWriter.WriteLineAsync(line);
}
});
}
ORIGINAL:
These are Mongo ObjectId's and if you haven't already deserialised the document they should support a toString method that will return a hexadecimal string.
but if you want this applied to the whole document, using JSON.stringify(MogoDocument) should deserialize this for you into a plain object.

rotating servos by pressing keyboard using arduino , johhny five or java script?

like when i press a specific key one of the servo rotate right as long
as i hold that key, and so on for a total of four servos and each to
have its specific keyboard key ,
example ( for servo 1 pressing "a" for left, "b" for right. for servo
2 "z"for left,"c" for right) i want to make it keyboard control.
i don't know the code to make the 4servos controlled by keyboard.. i
think i have to use firmata on arduino and the code written in
javascript ? its ok also or another method. thanks in advance
For sending data between Arduino and my computer I use processing, a fairly simple programming language similar to JavaScript. Using processing, you could establish a serial connection with the Arduino and send data back and forth. In your case, your processing code would get keyboard events and then send that data through usb to the Arduino. Here is a good tutorial: https://learn.sparkfun.com/tutorials/connecting-arduino-to-processing. If you need any further help, just ask.
Example Arduino Code:
char c = '.';
void setup() {
Serial.begin(9600);
delay(100); // Power up delay
}
void loop() {
if (Serial.available() > 0) {
c = Serial.read();
}
if(c == '.'){
//no key pressed
}
if(c == 'a'){
//a key pressed
}
}
Example Processing Code:
import processing.serial.*;
Serial myPort;
char valToWrite = '.';
void setup() {
smooth();
size(300, 350);
//Might need to change number in bracket based on the serial port your arduino is connected to
String portName = Serial.list()[3];
println(portName);
myPort = new Serial(this, portName, 9600);
myPort.bufferUntil('\n');
}
void draw() {
//Draw Something here, if you want visual representation
}
void keyPressed(){
valToWrite = key;
myPort.write(valToWrite);
}
void keyReleased(){
valToWrite = '.';
myPort.write(valToWrite);
}
Let me know if this works.

Categories