Control servo with keyboard or other hardware buttons? - c

I have just gotten started with Arduino and barely have any idea about more of the advanced stuff. It seems pretty straightforward. Now I'm one who usually likes to integrate two devices together, so i was wondering if i could control a servo with the computer's keyboard or two hardware push buttons attached to the Arduino board.
In case it helps, I'm using an Arduino Uno board. Here is the example code i am using to sweep the servo for now
// Sweep
// by BARRAGAN <http://barraganstudio.com>
// This example code is in the public domain.
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
int pos = 0; // variable to store the servo position
void setup()
{
myservo.attach(11); // attaches the servo on pin 9 to the servo object
}
void loop()
{
for(pos = 0; pos < 45; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(10); // waits 15ms for the servo to reach the position
}
for(pos = 45; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(10); // waits 15ms for the servo to reach the position
}
}
Now, let's say I wanted to change the servo's angle via pressing the
left/right arrow keys on my computer's keyboard. How would i go
about doing that?
Alternatively, what if i attached two push buttons to the Arduino,
and pressing one would move the servo either left or right depending
on the the button. Which ports would i plug the buttons into? Any
code samples or diagrams would greatly help!

To move a servo attached to an arduino attached to a computer you will need two components.
You will need software on your computer to accept keyboard commands and send commands to the arduino via the serial port. I would recommend a language like python or java to do that as a simple app can written quite easily.
Check this playground link for an example of using Java. And for an example in python check out this project.
There is a bug/feature built into the arduino that will give you grief as you go on here. The arduino is designed to auto reset when a serial connection is made to it via usb. This page has a detailed description of the issue and cites several ways to deal with it.
You will need to modify the sketch on the arduino to listen to the serial port and adjust the servo's position based on the commands received from your computer. Check out the python link above. It is an complete (hardware, pc software and arduino sketch) project designed to do something very similar to what you are trying to do.
I recommend you start with either component and try to get it going. As you run into problems, post your code and someone will be glad to help further.
As for the second question, adding buttons to the arduino is fairly simple. You will connect them to digital inputs. There are hundreds of examples on the web. Search for "add button to arduino" and see what you get. (lol... 1.3 million hits). Here again, try it and post specifics for more help.

For serial communication use putty
it is a cross platform Serial and ssh client
for the left and right arrow commands:
there are no ascii characters for arrow's: but there are utf-8;
putty or an other client sends utf-8 characters for the basic ascii characters are utf-8 and ascii exactly the same;
and the arduino reads only ascii characters;
the arduino reads
--> : 27, 91, 67
<-- : 27, 91, 68
so it is not that simple to read that.
you could use something like this
int pos = 0;
Serial.flush(); // flush all received data
while(Serial.avaialble()<3); // wait for the 3 ascii chars
if(Serial.read()==27){ // first char
if(Serial.read()==91){ //second char
switch (Serial.read()){
case 67: // Right arrow
myservo.write(++pos); // increment pos with 1 before write it
break;
case 68: // left arrow
myservo.write(--pos); // derement pos with 1 before write it
break;
case 65: // up arrow
myservo.write(++pos); // increment pos with 1 before write it
break;
case 66: // down arrow
myservo.write(--pos); // decrement pos with 1 before write it
break;
case default:
break;
}
}
}
but this is not a good solution
because of the arrow character is send in 3 bytes en when you flush it can flush the 27 so you read 91, 97, 27; and that is no valid so in doesn't work
you could write a algorithm to subtract the arrow command out of 5 ascii char's
or you can use 4 to move left and 6 to move right; which are ascii characters and in a numeric keypad are arrows drawn on those keys

Related

Audio Programming using SDL2 - Setting Up Audio Device

I'm writing an old-school game engine in C and SDL2. I'm designing the audio portion now. Instead of playing .wav samples and the like for sound, I want to implement a sound generator, kind of like a SID chip in software (if you're familiar with the Commodore 64).
Here is my initialization code for setting up the sound device:
void initialize_audio(void) {
SDL_AudioSpec want, have;
SDL_memset(&want, 0, sizeof(want)); //initializes the 'want' struct
want.freq = 44100;
want.format = AUDIO_U8; // 8-bit sound
want.channels = 1; // 1 = mono, 2 = stereo
want.samples = 2048; // how to decide on this? must be power of 2
want.callback = my_callback_function;
// capture global audio_device_id here
audio_device_id = SDL_OpenAudioDevice(
NULL, // choose best device based on 'want' struct
0, // want a playback device, not a recording device
&want,
&have,
SDL_AUDIO_ALLOW_FORMAT_CHANGE);
}
My question is (or what I need help with): I'm not sure what to ask for in terms of the buffer size in the audio device (the 'samples' parameter). I know this will effect how often SDL calls my callback function to feed more audio data into the sound device's buffer.
My guess is to keep it as small as a number as I can afford to do. The smaller the number here, the more frequently the callback function gets called, but I'm not sure what benefit this would give me.

Sending AT Commands via LabWindows code to SPBT2632C2A

I am trying to make a LabWindows/CVI program that talks with SPBT2632C2A Bluetooth chip. I am using a st eval spbt3atv3 dongle. I am trying to push a button and send a command to chip, but chip do not answer to me. I know my LabWindows program can receive messages from dongle, because every time I press reset button on dongle it shows me the boot up message. As I searched I need to add \n\r to end of my string, but it still didn't work. Chip does not send even error message.
CODE
int CVICALLBACK rasti (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
sprintf(discovery,"AT+AB discovery\n\r");
if(ComWrt (4,discovery, 18)!= 18){
SetCtrlVal (panelHandle, PANEL_TEXTBOX, "Nesekmingas duomenu siuntimas");
//Unsuccessful sending data
}
else {
SetCtrlVal (panelHandle, PANEL_TEXTBOX, discovery);
}
break;
}
return 0;
}
It's event called by button. It appends my discovery string to text box. So I think it's sending data correctly to serial port. But I think my string is wrong so I don't get the answer from chip.
Any ideas how to solve this to get responses from chip?
Make sure to call OpenComConfig with the correct parameters before invoking ComWrt. You can look for the correct port settings in the Hyperterminal (since you mentioned it communicates correctly with the device).
Refer to NI's documentation for more on this.
Also, trying different types of line termination characters might help (try using \r\n, \n or \r).

Sending the same variable to multiple client processes using a socket

I've been scouring the internet for more information on sockets in C, but I couldn't find exactly what I was looking for.
So here's the problem:
We have to create a server that starts up two client processes that play a game.
It's a simple memory-style game that takes two numbers as inputs
if both of those two numbers correspond to the same letters,
then that spot is set to white space
else set to the letter that it corresponded to.
Where the trouble comes in is sending the same array to both clients.
Both clients can play the game fine by themselves, however, they can't play the game together.
Player 1's guesses do not appear on player 2's console.
So my question is: how can you update the array in each child process so that the same array is written to both clients?
I'm not really looking for any sample code or anything, but more of a conceptual answer/ more resources on this topic.
Thanks!
A rough pseudo code concept would be
Initialization
connectPlayers();
if(player1)
{
generateGame();
do
{
bytesSent = sendArray to other players
} while (!allBytesSent)
}
else
{
do
{
bytesRead = readArray from server
} while (!allBytesRead)
}
Game Loop
while(!gameComplete)
{
if(!firstTime through as player 1)
{
waitforyourTurn();
read and update Game State; //reads another players guess and update array
}
result = doAGuess();
sendGuess(result); //sends guess to other player
passTurnToNextPlayer();
}

Jpeg restart markers

I made jpeg decoder, but I didn't implement restart markers logic. That is reason why my program don't work on some images (for example images saved with Photoshop: File->Save As->jpeg). I want to implement restart marker logic, but there is no detailed online explanation how restart marker logic works. Please can anyone tell me more about restart markers, or suggest me online resource where I can read more about it. Thx!
Restart markers are quite simple. They were designed to allow resynchronization after an error. Since most JPEG images are transmitted over error-free channels, they're rarely needed. A restart interval is defined with the FFDD marker as a 2-byte number. This tells how many MCUs between restart markers. When you encounter a restart marker (FFD0-FFD7), reset the DC values (Y,Cr,Cb) to 0 and the bitstream is started on a byte boundary (after the FFDx). It's simply a matter of counting through the restart interval over and over as you decode the image. The restart marker values will increment from FFD0 to FFD7 and then start again at FFD0. The marker value itself is not terribly important, but it can indicate if large chunks of data is missing. Here's an example of how I do it in my decoder. I throw away the restart markers in my bitstream reader.
iRestartCount = iRestartInterval;
for (y=0; y<Height_in_MCUs; y++)
{
for (x=0; x<Width_in_MCUs; x++)
{
<decode an MCU>
if (iRestartInterval) // if there is a restart interval defined
{
if (--iRestartCount == 0)
{
iRestartCount = iRestartInterval; // reset restart inverval counter
iDCPred0 = iDCPred1 = iDCPred2 = 0; // reset DC predictors
if (*iBit & 7) // adjust bitstream to start on the next byte boundary
{
*iBit += (8 - (*iBit & 7));
}
} // if restart interval expired
} // if restart interval defined
} // for x
} // for y
Update: Restart markers now serve a new purpose - to allow multi-threaded JPEG encoders and decoders. Since each "strip" of MCUs has its DC values reset at the beginning of each restart interval and starts on a byte boundary, each restart interval can be independently encoded or decoded by a different thread. An encoder can now arbitrarily divide the task into N threads and then 'glue' the data together with restart markers. For decoders, it's not as easy. If restart markers are present, then each interval can be assigned to a different thread. If not present, you can still do some pre-decoding tricks to split the job into multiple threads.

MJPEG internet streaming - accurate fps

I want to write MJPEG picture internet stream viewer. I think getting jpeg images using sockets it's not very hard problem. But i want to know how to make accurate streaming.
while (1)
{
get_image()
show_image()
sleep (SOME_TIME) // how to make it accurate?
}
Any suggestions would be great.
In order to make it accurate, there are two possibilities:
Using framerate from the streaming server. In this case, the client needs to keep the same framerate (calculate each time when you get frame, then show and sleep for a variable amount of time using feedback: if the calculated framerate is higher than on server -> sleep more; if lower -> sleep less; then, the framerate on the client side will drift around the original value from server). It can be received from server during the initialization of streaming connection (when you get picture size and other parameters) or it can be configured.
The most accurate approach, actually, is using of timestamps from server per each frame (which is either taken from file by demuxer or generated in image sensor driver in case of camera device). If MJPEG is packeted into RTP stream, these timestamps are already in RTP header. So, client's task is trivial: show picture using time calculating from time offset, current timestamp and time base.
Update
For the first solution:
time_to_sleep = time_to_sleep_base = 1/framerate;
number_of_frames = 0;
time = current_time();
while (1)
{
get_image();
show_image();
sleep (time_to_sleep);
/* update time to sleep */
number_of_frames++;
cur_time = current_time();
cur_framerate = number_of_frames/(cur_time - time);
if (cur_framerate > framerate)
time_to_sleep += alpha*time_to_sleep;
else
time_to_sleep -= alpha*time_to_sleep;
time = cur_time;
}
, where alpha is a constant parameter of reactivity of the feedback (0.1..0.5) to play with.
However, it's better to organize queue for input images to make the process of showing smoother. The size of queue can be parametrized and could be somewhere around 1 sec time of showing, i.e. numerically equal to framerate.

Resources