to start off, this might not be a problem with arduino code or arduino, but I figured I would post here because I really just can not figure out what is wrong.
I am working on this project just for fun to send key strokes from the keyboard, through the computer, and out through the USB to my arduino mega. No additional hardware is here, just the computer, the arduino, and the USB cable.
I am using Microsoft Visual Studio Express 2012 to write code to receive key strokes and send them to the USB. This is the code I am using:
#include "stdafx.h"
#include "conio.h"
using namespace System;
using namespace System::IO::Ports;
int main(array<System::String ^> ^args)
{
String^ portName;
String^ key;
int baudRate=9600;
Console::WriteLine("type in a port name and hit ENTER");
portName=Console::ReadLine();
//arduino settings
SerialPort^ arduino;
arduino = gcnew SerialPort(portName, baudRate);
//open port
try
{
arduino->Open();
while(1)
{
int k = getch();
key = k.ToString();
Console::WriteLine(key);
arduino->Write(key);
if (k == 32)
return 0;
}
}
catch (IO::IOException^ e )
{
Console::WriteLine(e->GetType()->Name+": Port is not ready");
}
}
This code works fine, and sends commands to the arduino. I might as well ask this as well, but after 35 key strokes it just stops sending key strokes, I am unsure as to why, but that is not an arduino problem (I don't think).
So when the certain value for key gets sent to the arduino, it changes. For example, the values that are assigned to the variable key for pressing the number 1 and 2 are 49 and 50, respectively. However, when they get sent to the arduino, the values are different some how. 1 is now 57, and 2 is now 48. I am unsure as to why this is happening. I tried 4 and 5 and they both have their values shift down 2 like the key 2. This is the code I have on the arduino:
int ledPin = 13;
int key=0;
int c;
void setup()
{
pinMode(ledPin, OUTPUT); // pin will be used to for output
Serial.begin(9600); // same as in your c++ script
}
void loop()
{
if (Serial.available() > 0)
{
key = Serial.read(); // used to read incoming data
if (key == 57)
{
digitalWrite(ledPin, HIGH);
}
else if (key == 48)
{
digitalWrite(ledPin, LOW);
}
}
c = key;
Serial.println(c);
}
As of right now it is just to switch a light on and off. I am hoping to involve many more keys and having the values be consistent would be very convenient. Anyways, if anyone could help me with why the values are different that would be awesome. I am not completely new to programming but I am certainly no expert and have not gotten too far into advanced stuff.
Thank you for any help or advice.
This has to do with what you are sending through visual studio. You are converting a keypress to its ASCII value, then converting that ASCII value to string, then sending that string through serial. The arduino is expecting a number, not a string.
For example, if you press the 1 key, your visual studio code converts that to an ASCII number 49, which is then converted to string "49", which the Arduino receives - but since you are sending "49", which is a "4" and an "9", the Arduino is reading 9 which corresponds to 57, as you have seen.
Similarly, pressing 2 converts it to "50", and the Arduino reads "0" which corresponds to the value 48 which you were getting.
To fix this, send the number directly, don't convert it into a string.
Related
I want to send multibyte integers,(eg. 1000,10000, etc) from raspberry pi to arduino. It can either be in the form of int or string(will convert it into integer on arduino's side) through i2c. Now, I am able to send data but only till 255, If I try to send 1000, the output on ARduino serial terminal will be 232 and not 1000. I tried to search over the internet for like 4-5 hours, but no luck. Can someone please guide me?
import smbus
import time
bus = smbus.SMBus(1)
address = 0x04
a=1000
#a=str(a)
def writeString(a,b,c,d):
bus.write_i2c_block_data(address, a, [b, c, d])
return -1
while True:
try:
writeString(1000,a,5,0)
time.sleep(1) #delay one second
except KeyboardInterrupt:
quit()
Arduino:
#include <Wire.h>
int data [4];
int x = 0;
void setup() {
Serial.begin(9600);
Wire.begin(0x04);
Wire.onReceive(receiveData); //callback for i2c. Jump to void recieveData() function when pi sends data
}
void loop () {
delay(100); //Delay 0.1 seconds. Something for the arduino to do when it is not inside the reciveData() function. This also might be to prevent data collisions.
}
void receiveData(int byteCount) {
while(Wire.available()) { //Wire.available() returns the number of bytes available for retrieval with Wire.read(). Or it returns TRUE for values >0.
data[x]=Wire.read();
x++;
}
Serial.println("----");
Serial.print(data[0]);
Serial.print("\t");
Serial.print(data[1]);
Serial.print("\t");
Serial.print(data[2]);
Serial.print("\t");
Serial.println(data[3]);
// Serial.print("----");
}
I2C sends and receives BYTES. 1000 in hex is 0x3E8. 232 in hex is 0xE8. Only the low byte is sent.
I'm using an app to either turn on an LED or change the angle of a micro servo depending on which button is pressed (using Arduino). My code works for the LED (while the button is pressed, the LED is on) but nothing happens when I press the button meant to change the angle of the servo to 40.
// Bluetooth serial:
#include <SoftwareSerial.h> // import the serial library
// setup the bluetooth coms
SoftwareSerial BTSerial(8,7);
#include <Servo.h>
int servoPin = 0;
Servo servo;
int angle = 0; // servo position in degrees
int input = 0;
int led2 = 13;
void setup() {
// put your setup code here, to run once:
servo.attach(servoPin);
Serial.begin(9600); // coms w/ computer
BTSerial.begin(9600); // coms w/ Bluetooth
pinMode(led2, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
if (BTSerial.available())
{
input = BTSerial.read();
digitalWrite(led2, LOW);
switch(input) {
case 'E':
angle = 40;
break;
case 'C':
digitalWrite(led2, HIGH);
break;
}
servo.write(angle);
}
}
The input is right as I checked by also turning the LED on in case 'E' where it worked as normal. I had also tried using servo.write() within the case function as well but this didn't work either.
case 'E':
servo.write(40);
break;
You cannot use digital pins 0 or 1 as input:
As mentioned, those are serial send and receive pins. If you power your computer through USB, it can interfere if you try to use them, since it's reading from both the USB to Serial and the pin. Also you have an issue with anything connected (well, not anything, but remove it just to be safe) when you're trying to program. If you use the pins as intended, and program then run it off battery, it should be no problem at all.
Most of us stay away from it because it's a bit of a hassle
Depending on your Arduino model, servo.attach only supports pins 9 and 10:
Note that in Arduino 0016 and earlier, the Servo library supports only servos on only two pins: 9 and 10.
Or you could just use one of those anyway.
I am having trouble with the arduino sound sensor and LEDs. I keep on getting the value of 0 in my serial monitor, the same thing happens with another sound sensor that I have. I am currently trying to make it light up the LEDs based on the sound but with the serial monitor reading 0 it will not activate the code. There should be a picture attached. The lights on the sound sensor is lighting up so I know the GND and 5V is working. Since it is hard to tell I am using 330 ohm resisters. I got the sound sensor from an elegoo starter kit, so I know it might be cheap. The picture is in the link at the end. Thank you.
int MicPin = A0;
int MicValue1 = 0;
int MicValue2 = 0;
int led1 = 2;
int led2 = 4;
int led3 = 6;
int led4 = 8;
void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(MicPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
MicValue1 = analogRead(MicPin);
Serial.println(MicValue1);
delay(1);
MicValue2 = analogRead(MicPin);
Serial.println(MicValue2);
if (MicValue1 - MicValue2 > 1) {
digitalWrite(led1, HIGH);
delay(2000);
}
else {
digitalWrite(led1, LOW);
}
}
enter image description here
I assume that you have a simple analog-output sensor module that provides 10bit analog values based on the environment volume level. If this assumption is correct, you wired all pins correctly and the received value is always out of range or at the maximum, you maybe had to integrate a resistor to get a valid value. Try a small resistor and increase the resistance until you receive suitable values. Maybe the documentation of your module provides further information.
There is a small rotating knob connected to the sensor on which we need to rotate to adjust particular resistance values, you can see different values in serial monitor out.
Useful link
I'm working on a Bluetooth controlled Arduino robotic arm.
I want that when I send an integer, a servo moves, and when I send another Int, it stops. All I have found on forums are systems where the servo moves to a specific position, but I want it to really rotate, by incrementing its angle.
Here is my code, which doesn't work:
#include <Servo.h>
int val;
int angle;
int charsRead;
char buffer[10];
Servo servo;
void setup() {
Serial.begin(9600);
servo.attach(6);
angle = servo.read();
}
void loop() {
servo.write(170);
serialCheck();
if(val == 4021){
servo.write(angle++);
delay(50);
}
}
else if(val == 4022){
servo.write(angle);
}
serialCheck();
}
void serialCheck(){
while(Serial.available() > 0){
charsRead = Serial.readBytesUntil('\n', buffer, sizeof(buffer) - 1);
buffer[charsRead] = '\0';
val = atoi(buffer);
Serial.println(val);
}
}
The app I use basically sends '4021' when I long press a button, and sends '4022' when I release it.
I've been working on this for hours and I haven't found anyone on any forum who has had the same issue...
Please help.
Your problem lies here:
void loop() {
servo.write(170);
...
}
What this piece of code does is set servo angle to 170 at every iteration of loop. As this will happen thousands times per second, it will essentially overwrite any servo settings introduced via serial commands. What you should do is to move servo.write(170); to setup(), before servo.read(), which I think will yield middle position currently, or even some undefined result. According to Arduino documentation it will:
Read the current angle of the servo (the value passed to the last call
to write()).
And BTW: servo has limited range of movement, so you should check if the desired angle doesn't exceed servo limits.
i am using two arduino mcu to connect two lines of LED-matrix display. I tried using i2c communication to connect a master mcu (which controls the first line of the LED-matrix display) and slave mcu (which controls the second line of LED-matrix display). I need to pass a string data(consist of 300 characters) from the master to the slave, so that i can display the same string to the second line of the LED-matrix display.
The problem is, I can't pass a string variable using Wire.read() from master to slave. My solution to this, was to convert the string to character before using wire.read() to transmit the data, but the slave cannot receive the whole string, only the first few characters. I also had problem in the timing of the display, the second line of the LED-matrix(which is controlled by the slave), displays the string very late.
This is the sample code for the master mcu
//Master Code
String inData;
String LED_DATA;
char buf[300];
void Input(void){
while(Serial.available() > 0)
{
char received = Serial.read();
inData+=received;
if(received == '~')
{
LED_DATA = inData;
inData.toCharArray(buf,300);
Wire.beginTransmission(5);
Wire.write(buf);
Wire.endTransmission();
}
}
}
And this is the sample code for the slave
//slave
char LED_DATA[100];
void setup(){
Wire.begin(5);
Wire.onReceive(receiveEvent);
}
void receiveEvent(int howMany){
while(Wire.available()){
LED_DATA[300] = Wire.read();
}
}
I am new to arduino and microcontroller. What is the easiest way possible to solve my problem? Thank you very much.
You can pass string to Wire.write(), by passing the variable as a char * . So if String a = "test"; was the earlier declaration, try using Char* a = "test"; it will send the data through