Übung in Echtzeitsysteme: PWM für Servo erzeugen
(EN google-translate)
(PL google-translate)
Ausgehend von einem einfachen Programm und einer einfachen Verstärkerschaltung für den Audioausgang, soll ein Programm entwickelt werden, das es erlaubt direkt zwei Servos über den Auduiausgang angesteuert werden.
Teil 1 - Nachvollziehen eines einfachen Tests, um digitale Pulse an einen Mikrocontroller zu schicken
package processing.test.avrconnect1;
import processing.core.*;
import android.media.AudioTrack;
import android.media.AudioFormat;
import android.media.AudioManager;
public class avrconnect1 extends PApplet {
boolean aktiv = false;
int sr;
int buffsize;
//create an audiotrack object
AudioTrack audioTrack;
public int PULSE = 15;
public int pulse = 0;
short[] samples;
int amp = 10000;
float twopi = 2.0f*PI;
float fr = 440.0f;
float fr2 = 4.4f;
float fr4 = 1.1f;
float fr3 = 220.0f;
float ph = 0.0f;
float ph2 = 0.0f;
float ph3 = 0.0f;
float ph4 = 0.0f;
float change=0.0f;
float change2=0.0f;
Tonspieler tonspieler;
public void setup()
{
sr = 44100;
buffsize = AudioTrack.getMinBufferSize(sr, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
//create an audiotrack object
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sr,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT,
buffsize,
AudioTrack.MODE_STREAM);
samples= new short[buffsize];
tonspieler = new Tonspieler();
Thread t = new Thread(tonspieler);
t.start();
audioTrack.play();
}
public void draw()
{
clear();
background(0);
if(aktiv)
fill(0,255,0);
else
fill(255,0,0);
ellipse(width/2,height/2,width/2,height/2);
}
public void mousePressed()
{
aktiv = !aktiv;
pulse=0;
}
private class Tonspieler implements Runnable
{
public void run()
{
int zaehler = 0;
while(true)
{
if(aktiv)
{
for(int i=0;i<buffsize;i++)
{
if(zaehler<2 && pulse<PULSE)
{
samples[i] = Short.MAX_VALUE;
}
else
samples[i] = Short.MIN_VALUE;
// samples[i] = (short)0;
zaehler++;
if(zaehler>=4)
{
pulse++;
zaehler=0;
}
}
audioTrack.write(samples, 0, buffsize);
}
}
}
}
}
Code 0-1: Quelltext - Android-seitig
|
Das Programm verschickt bei jedem Einschalten ( mousePressed(), aktiv==true ) 15 Rechteckpulse an den verbundenen Mikrocontroller.
android_eclipse_projekt.zip - Android/ Eclipse-Projekt zu obigem Quelltext.
#include<avr/io.h>
int main()
{
unsigned char akku;
unsigned char x;
unsigned char zahl;
DDRB=0;
DDRA=0;
// PORTA=255;
PORTA=0;
DDRC=255;
akku=0;
zahl=0;
x=0;
PORTC=zahl;
while(1)
{
akku=PINB;
x=PINA;
if((akku & 0b00000001)>0)
zahl=0;
if( (x & 0b00000001)>0)
{
zahl++;
while( (x & 0b00000001)>0)
{
x=PINA;
DDRD=0;
}
}
PORTC=zahl;
}
}
Code 0-2: Mikrocontroller-Quelltext zum Versuch digitale Pulse über den Audio-Ausgang zu übertragen.
mikrocontroller_projekt.zip - zugehöriges Mikrocontroller-Projekt
Bild 0-1: Versuchsaufbau - digitale Pulse an Mikrocontroller übertragen.
Bild 0-2: Verwendete Verstärkerschaltung.
Musterlösung
Bild 0-3: Verwendete Verstärkerschaltung für Servo-PWM-Signale.
musterloesung.zip - Musterlösung: Wechsel zwischen -45 Grad, 0 Grad, +45 Grad über Touchscreen
package processing.test.avrconnect1;
import processing.core.*;
import android.media.AudioTrack;
import android.media.AudioFormat;
import android.media.AudioManager;
public class avrconnect1 extends PApplet {
boolean aktiv = false;
int sr;
int buffsize;
long PUFFERZEIT=0;
//create an audiotrack object
AudioTrack audioTrack;
public int PULSE = 400;
public int pulse = 0;
short[] samples;
int amp = 10000;
float twopi = 2.0f*PI;
float fr = 440.0f;
float fr2 = 4.4f;
float fr4 = 1.1f;
float fr3 = 220.0f;
float ph = 0.0f;
float ph2 = 0.0f;
float ph3 = 0.0f;
float ph4 = 0.0f;
float change=0.0f;
float change2=0.0f;
Tonspieler tonspieler;
int WERT = 0;
public void setup()
{
sr = 44100;
buffsize = AudioTrack.getMinBufferSize(sr, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
PUFFERZEIT = (1000*(long)buffsize)/sr;
//create an audiotrack object
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sr,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT,
buffsize,
AudioTrack.MODE_STREAM);
samples= new short[buffsize];
tonspieler = new Tonspieler();
Thread t = new Thread(tonspieler);
t.start();
audioTrack.play();
}
public void draw()
{
clear();
background(0);
if(WERT==0)
fill(255,0,0);
else if(WERT==1)
fill(0,255,0);
else
fill(0,0,255);
ellipse(width/2,height/2,width/2,height/2);
}
public void mousePressed()
{
WERT++;
WERT%=3;
}
private class Tonspieler implements Runnable
{
public void run()
{
int zaehler = 0;
long zeit = System.currentTimeMillis();
while(true)
{
for(int i=0;i<buffsize;i++)
{
if(zaehler<44+WERT*22)
samples[i] = Short.MAX_VALUE;
else
samples[i] = Short.MIN_VALUE;
zaehler++;
if(zaehler>=500)
zaehler=0;
}
audioTrack.write(samples, 0, buffsize);
long restzeit = PUFFERZEIT-(System.currentTimeMillis()-zeit);
zeit=System.currentTimeMillis();
if(restzeit>0)
{
try
{
Thread.sleep(restzeit);
}
catch(Exception e)
{
}
}
}
}
}
}
Code 0-3: Quelltext Musterlösung