I cannot send data to my Arduino through usb serial connection - linux

So, I have an arduino uno R3 SMD edition and I want to send commands to it while it's running. It has an adafruit v2 motor shield connected to it, which is powered separately from the arduino. The arduino is connected to my laptop by a usb cable.
Now, the motor shield works and I can send code to the arduino to make it do things. I can't get the arduino to receive anything I send to it while it's running from the serial connection though. I can print to the monitor in the arduino ide from arduino code though. I'm on debian linux stretch btw. My arduino ide is from the debian repos.
Here is all the code I'm trying to use:
Arduino Code
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);
void setup()
{
Serial.begin(115200);
AFMS.begin();
myMotor->setSpeed(300);
}
char input;
int dir;
void loop()
{
dir = 0;
if (Serial.available() > 0) {
input = Serial.read();
Serial.print(input);
if (input == 1) {
dir = FORWARD;
}
if (input == 2) {
dir = BACKWARD;
}
}
if (dir != 0) {
myMotor->step(360, dir, DOUBLE);
delay(1000);
}
}
Controller Code on Laptop
#include <stdlib.h>
#include <stdio.h>
int
main(int argc, char **argv)
{
FILE *arduino;
int c;
arduino = fopen("/dev/ttyACM0", "w");
if (arduino == NULL) {
fprintf(stdout, "NOOOOOOOOOOOO\n");
}
while (1) {
c = fgetc(stdin);
if (c == 'f') {
fprintf(arduino, "%d", 1);
}
if (c == 'b') {
fprintf(arduino, "%d", 2);
}
fflush(arduino);
if (c == 'q') {
break;
}
}
return 0;
}
I'm pretty sure this isn't a permissions problem, I've run the controller code from root and the tty device opens fine. Also, I've tried both 9600 and 115200 for my baud rate, but no dice. Does anyone have an idea? From googling it really seems like this is all anyone else is doing.

Your controller is sending characters '1' and '2'. Your Arduino is checking for character codes 1 and 2 - in other words, the characters CtrlA and CtrlB. You can make the change at either end, they just need to match.

Related

Pm_Read() can't read VMPK input

I have this problem:
i want to create a midi synthesizer in C,linux. Since I don't have a USB midi keyboard, I thought about using a virtual midi divice like VMPK. I found this code in a book that also explained how to use the portmidi library:
#include <stdio.h>
#include <portmidi.h>
#include <porttime.h>
int main() {
int cnt,i,dev;
PmError retval;
const PmDeviceInfo *info;
PmEvent msg[32];
PortMidiStream *mstream;
Pm_Initialize();
cnt = Pm_CountDevices();
if(cnt) {
for(i=0; i < cnt; i++){
info = Pm_GetDeviceInfo(i);
if(info->input)
printf("%d: %s \n", i, info->name);
}
printf("choose device: ");
scanf("%d", &dev);
Pt_Start(1, NULL, NULL);
retval = Pm_OpenInput(&mstream, dev, NULL, 512L, NULL,NULL);
if(retval != pmNoError)
printf("error: %s \n", Pm_GetErrorText(retval));
else {
while(Pt_Time(NULL) < 60000){
if(Pm_Poll(mstream)) {
cnt = Pm_Read(mstream, msg, 32);
for(i=0; i<cnt; i++) {
printf("status:%d, byte1=%d, "
"byte2=%d, time=%.3f\n",
Pm_MessageStatus(msg[i].message),
Pm_MessageData1(msg[i].message),
Pm_MessageData2(msg[i].message),
msg[i].timestamp/1000.);
}
}
}
}
Pm_Close(mstream);
}
}
else printf("No MIDI devices found\n");
Pm_Terminate();
return 0;
}
In short, once the program connects with a MIDI input device, it listens for 60 all the messages that come from them, (Printing the status byte and the two data bytes, as a midi protocol)
When I launch VMPK, it appears that the program reveals VMPK as midi input, under the name "out"
Program output
I also checked the "JACK audio connection" program to verify that VMPK was revealed as a MIDI input device
JACK audio output
I don't understand why when I press a key from the VMPK keyboard, I don't receive any messages from the program ...
I tried to change the VMPK configuration, but I didn't get any changes.
VMPK configuration menu
Maybe I'm doing something wrong in the VMPK configuration.
Any help is welcome.
I thank you in advance for your availability
ok, I found the problem. As I said, I set VMPK badly. If you set it this way, you can detect MIDI inputs
This is the output of programm:

How to receive 2-byte decimal number from Bluetooth to arduino

I can send 1byte decimal number (0-256) easily over arduino, but I couldn't make it for 2 byte number.
the code below here I used for sending data between 0-256, this is works great.
#include <SoftwareSerial.h>
#include <Servo.h>
Servo myservo;
int bluetoothTx = 10;
int bluetoothRx = 11;
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
void setup()
{
myservo.attach(9);
//Setup usb serial connection to computer
Serial.begin(9600);
//Setup Bluetooth serial connection to android
bluetooth.begin(9600);
}
void loop()
{
//Read from bluetooth and write to usb serial
if(bluetooth.available()> 0 )
{
int servopos = bluetooth.read();
Serial.println(servopos);
myservo.write(servopos);
}
}
I tried to program for 2 byte number , but I couldn't make it successfully , MSB and LSB data are not shifting properly . any help regarding this code will be much help for me go ahead .
#include <SoftwareSerial.h>
#include <Servo.h>
Servo myservo;
int bluetoothTx = 7;
int bluetoothRx = 8;
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
void setup()
{
myservo.attach(9);
//Setup usb serial connection to computer
Serial.begin(9600);
//Setup Bluetooth serial connection to android
bluetooth.begin(9600);
}
void loop()
{
//Read from bluetooth and write to usb serial
if(bluetooth.available()>= 2 )
{
int servopos = bluetooth.read() << 8;
servopos |= bluetooth.read();
Serial.println(servopos);
myservo.write(servopos);
}
}

USB device detection - Windows & Linux (FT232R)

How can I enumerate and identify (get pid, vid and serial) FT232R chips in windows and linux. I need to:
1. at start of program enumerate already plugged devices
2. detect plugging of usb device
3. get PID, VID, Serial
And I need to do that in windows and linux. I know there is libusb for windows as well as for linux, but I don't have that much experience with USB. Code example would be best.
You should use SetupAPIs in Windows for getting device information like hardware id(contains vid and pid both) and to detect the plugging/unplugging see example in this link
Registering for Device Notification
To use SetupAPI you can use below code as reference and add/modify according to your requirement.
#include "stdafx.h"
#include <stdlib.h>
#include <Windows.h>
// Link to setapi.lib
#include <setupapi.h>
void GetDeviceInfo()
{
GUID gUSBGuid;
DWORD ClassGuidListSize = 1;
DWORD RequiredSize = NULL;
//if device shown under "USB" node in Devmgr, else see inf for classname
BOOL bres = SetupDiClassGuidsFromName((PCTSTR)"USB",
&gUSBGuid,//GUID will get populated
ClassGuidListSize,
&RequiredSize);
HDEVINFO hDevInfo = SetupDiGetClassDevs(&gUSBGuid,NULL,NULL,DIGCF_PRESENT);
if (INVALID_HANDLE_VALUE != hDevInfo)
{
BOOL bResult = FALSE;
SP_DEVICE_INTERFACE_DATA tDeviceInterfaceData;
tDeviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
for (int nMemberIndex = 0; TRUE ; nMemberIndex++)
{
SP_DEVINFO_DATA tSpDevInfoData;
tSpDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
//Get the tSpDevInfoData for the instance ID
bResult = SetupDiEnumDeviceInfo(hDevInfo,nMemberIndex,&tSpDevInfoData);
if(bResult)
{
TCHAR *szHardwareId = new TCHAR[128] ;
DWORD dwtype = REG_SZ;
SetupDiGetDeviceRegistryProperty(hDevInfo,&tSpDevInfoData,SPDRP_HARDWAREID
,&dwtype,(PBYTE szHardwareId,256,NULL);
//code to process szHardwareId
delete szHardwareId;
break;
}
}
}
}
I dont have idea for Linux..:(
Hope this helps..

Finding all the devices I can use to play PCM with ALSA

I use ALSA to play PCM samples. I open the PCM stream with this function:
int snd_pcm_open(snd_pcm_t** pcmp,
const char* name,
snd_pcm_stream_t stream,
int mode);
I'm currently using "default" as the name parameter. I would like to be able to choose other devices. What I cannot understand is how I can determine what are the names of the other available devices.
I attached a USB microphone to my system and aplay and amixer seems to detect the new device. How do I determine the name of that device? Is there any ALSA function to get a list of available devices with their respective names?
I think you can use snd_device_name_hint for enumerating devices.
Here is an example. Beware that I haven't compiled it !
char **hints;
/* Enumerate sound devices */
int err = snd_device_name_hint(-1, "pcm", (void***)&hints);
if (err != 0)
return;//Error! Just return
char** n = hints;
while (*n != NULL) {
char *name = snd_device_name_get_hint(*n, "NAME");
if (name != NULL && 0 != strcmp("null", name)) {
//Copy name to another buffer and then free it
free(name);
}
n++;
}//End of while
//Free hint buffer too
snd_device_name_free_hint((void**)hints);
It was my first requirements to a linux/unix projects where I need to know about all of the available audio devices capability and name. Then I need to use these devices to capture and plaback the audio. What I have done is pretty simple. There is a linux/unix command which is used to find the devices through alsa utility in linux.
It is:
aplay -l
Now what I did is just make a programme to give the out as like as this by alsa.
For everyone's help I have made a (.so) library and a sample Application demonstrating the use of this library in c++.
The output of my library is like-
[root#~]# ./IdeaAudioEngineTest
HDA Intel plughw:0,0
HDA Intel plughw:0,2
USB Audio Device plughw:1,0
This library can also capture and playback the real-time audio data.
It is available with documentation in IdeaAudio library with Duplex Alsa Audio
Just for grins, your program reformatted:
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <unistd.h>
#include <alsa/asoundlib.h>
void listdev(char *devname)
{
char** hints;
int err;
char** n;
char* name;
char* desc;
char* ioid;
/* Enumerate sound devices */
err = snd_device_name_hint(-1, devname, (void***)&hints);
if (err != 0) {
fprintf(stderr, "*** Cannot get device names\n");
exit(1);
}
n = hints;
while (*n != NULL) {
name = snd_device_name_get_hint(*n, "NAME");
desc = snd_device_name_get_hint(*n, "DESC");
ioid = snd_device_name_get_hint(*n, "IOID");
printf("Name of device: %s\n", name);
printf("Description of device: %s\n", desc);
printf("I/O type of device: %s\n", ioid);
printf("\n");
if (name && strcmp("null", name)) free(name);
if (desc && strcmp("null", desc)) free(desc);
if (ioid && strcmp("null", ioid)) free(ioid);
n++;
}
//Free hint buffer too
snd_device_name_free_hint((void**)hints);
}
int main(void)
{
printf("PCM devices:\n");
printf("\n");
listdev("pcm");
printf("MIDI devices:\n");
printf("\n");
listdev("rawmidi");
return 0;
}

Having a problem figuring out how to get Ethernet interface info on Mac OS X using ioctl/SIOCGIFADDR/SIOCGIFCONF?

Are you having a problem figuring out how to get interface info on Mac OS X using ioctl/SIOCGIFADDR/SIOCGIFCONF?
I had a lot of trouble getting code that worked fine on Linux to work on Mac OS X today.
Copy-paste to main.c and gcc main.c && ./a.out should work (lists all network interfaces, their ipv4/6 address, netmask and MAC address if associated):
Works fine on Mac OSX and iOS iPad/iPhone:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <ifaddrs.h>
#include <errno.h>
int main() {
struct ifaddrs *if_addrs = NULL;
struct ifaddrs *if_addr = NULL;
void *tmp = NULL;
char buf[INET6_ADDRSTRLEN];
if (0 == getifaddrs(&if_addrs)) {
for (if_addr = if_addrs; if_addr != NULL; if_addr = if_addr->ifa_next) {
printf("name : %s\n", if_addr->ifa_name);
// Address
if (if_addr->ifa_addr->sa_family == AF_INET) {
tmp = &((struct sockaddr_in *)if_addr->ifa_addr)->sin_addr;
} else {
tmp = &((struct sockaddr_in6 *)if_addr->ifa_addr)->sin6_addr;
}
printf("addr : %s\n",
inet_ntop(if_addr->ifa_addr->sa_family,
tmp,
buf,
sizeof(buf)));
// Mask
if (if_addr->ifa_netmask != NULL) {
if (if_addr->ifa_netmask->sa_family == AF_INET) {
tmp = &((struct sockaddr_in *)if_addr->ifa_netmask)->sin_addr;
} else {
tmp = &((struct sockaddr_in6 *)if_addr->ifa_netmask)->sin6_addr;
}
printf("mask : %s\n",
inet_ntop(if_addr->ifa_netmask->sa_family,
tmp,
buf,
sizeof(buf)));
}
// MAC address
if (if_addr->ifa_addr != NULL && if_addr->ifa_addr->sa_family == AF_LINK) {
struct sockaddr_dl* sdl = (struct sockaddr_dl *)if_addr->ifa_addr;
unsigned char mac[6];
if (6 == sdl->sdl_alen) {
memcpy(mac, LLADDR(sdl), sdl->sdl_alen);
printf("mac : %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
}
printf("\n");
}
freeifaddrs(if_addrs);
if_addrs = NULL;
} else {
printf("getifaddrs() failed with errno = %i %s\n", errno, strerror(errno));
return -1;
}
}
The mechanism to get MAC addresses is entirely different on BSD-derived OSes than on Linux. This includes OS X.
Here's code I use that works on Linux and OS X, and probably on the BSDs, too:
#if defined(HAVE_SIOCGIFHWADDR)
bool get_mac_address(char* mac_addr, const char* if_name = "eth0")
{
struct ifreq ifinfo;
strcpy(ifinfo.ifr_name, if_name);
int sd = socket(AF_INET, SOCK_DGRAM, 0);
int result = ioctl(sd, SIOCGIFHWADDR, &ifinfo);
close(sd);
if ((result == 0) && (ifinfo.ifr_hwaddr.sa_family == 1)) {
memcpy(mac_addr, ifinfo.ifr_hwaddr.sa_data, IFHWADDRLEN);
return true;
}
else {
return false;
}
}
#elif defined(HAVE_GETIFADDRS)
bool get_mac_address(char* mac_addr, const char* if_name = "en0")
{
ifaddrs* iflist;
bool found = false;
if (getifaddrs(&iflist) == 0) {
for (ifaddrs* cur = iflist; cur; cur = cur->ifa_next) {
if ((cur->ifa_addr->sa_family == AF_LINK) &&
(strcmp(cur->ifa_name, if_name) == 0) &&
cur->ifa_addr) {
sockaddr_dl* sdl = (sockaddr_dl*)cur->ifa_addr;
memcpy(mac_addr, LLADDR(sdl), sdl->sdl_alen);
found = true;
break;
}
}
freeifaddrs(iflist);
}
return found;
}
#else
# error no definition for get_mac_address() on this platform!
#endif
It's up to you to work out how to get the right HAVE_* macro defined for the platform. I happen to use autoconf for this, but you may have another way of dealing with platform differences.
Notice that the default interface name parameter for these functions is the default for the first Ethernet interface on Linux and OS X boxes. You may need to override this for other OSes, or pass another value if you're interested in the MAC address for a different interface.
This thread matched my problem somewhat:
http://discussions.apple.com/thread.jspa?messageID=10935410&tstart=0
This thread helped a lot:
https://lists.isc.org/pipermail/dhcp-hackers/2007-September/000767.html
because that thread eventually mentions that getifaddrs() should be used instead. The man page on Ubuntu 10.04 had a great example of how to use getifaddrs and using it as a reference helped me figure out code that worked on both Mac and Linux. I don't want anyone else to waste time on something so simple, so I'm posting and answering myself here. Hoping that my post helps you...

Resources