Sitemize Hoşgeldiniz sitemizin kuruluş sebebi Eğitim Öğretim Bilgilendirme amaçlıdır Site içerik ve kaynalar Çeşitli Web Sitelerinden Derlenmişolup Teylif Hakları Çerçevesinde Korunuyor Olabilir Şayet bugibi durumlarda lütfen Site Yönetimiyle İrtibata geçiniz Saygılar Hikmet TURNA

Articles by "instrumentation"

MARG (Magnetic, Angular Rate, and Gravity) sensor array used for AHRS (Attitude and Heading Reference Systems).










Android OpenGL 3D display on Samsung Spica (i5700).








Sparkfun 9DOF sensor stick SEN-10389, later replaced by SEN-10321.





Using ATmega328P, operated at 3.3V supply and 8MHz crystal. At this speed, reading sensors' measurements and computing "AHRSupdate" take about 31ms to complete. Default compiler setting is used on WinAVR. With 25Hz sampling rate, this leaves mega328p extra 9ms to do other tasks. Bluetooth SPP (serial) communication is buffered and interrupt driven, so no processing time is wasted in reading and sending data to the android phone.










References:


(1) Sebastian Madgwick's Alternative AHRS (MARG) algorithm - Quaternion implementation of Mayhony's DCM filter incorporating magnetic distortion compensation.


(2) Fabio Varesano's FreeIMU. Also using Madgwick's implementation of the DCM filter on Arduino platform.


(3) Rotation convertions by Martin Baker. Very good discussion on quaternions and other 3D representation like Euler angles and transformation matrix.


(4) OpenGL Transformation Matrix by Song Ho Ahn


(5) Similar discusion on diydrones.com started by Harinath




Android project examples:


Android Bluetooth


Bluetooth Chat


Android OpenGL Projects


OpenGL ES tutorial


Android Bluetooth Oscilloscope




Special thanks to the generous guy who gave me these toys, Thank you very much!








Inductance and Capacitance Meter using Microchip's PIC18F2550 connected to USB using HID class (Plug-n-Play).







* f1, f2. and f3 are the frequencies defined by the equations stated on Digital LC Meter.






























diagram using internal Analog Comparator and Timer Peripherals of PIC18:






schematic with actual values:




*simulation on Proteus 7 is NOT working (particularly the LC oscillator part and internal pull-up on RB0)



download link (HEX and PC app): PIC18F2550_USB-HID_LC-Meter.zip

elab.ph forum link:  




PIC18F2550 USB LC Meter



 # edit (10-20-10)




added "Calibration option" ( same PIC18F firmware )


  • reference capacitance range is 1.0nF +/- 5%

  • Fosc (20MHz crystal with PLL) frequency range is 48MHz +/- 200ppm








*This application is tested only with Samsung Galaxy GT-i5700 Spica (rooted Android 2.1 OS, i570EXXJD1 Baseband version).

The transmitter circuit uses Microchip's dsPIC33FJ16GS504 for the analog-to-digital conversion of the input signals on two channels.
The processed data on the dsPIC are then transmitted to the phone (for waveform display) via the LMX9838 bluetooth SPP module.






































specs/ranges:


  • time per division: {5us, 10us, 20us, 50us, 100us, 200us, 500us, 1ms, 2ms, 5ms, 10ms, 20ms, 50ms }

  • volt per division: {10mV, 20mV, 50mV, 100mV, 200mV, 500mV, 1V, 2V, GND}

  • analog input (depends on external pre-amplifier configuration): {-8V to +8V }








The source codes for the bluetooth communication is based on Bluetooth Chat example from http://developer.android.com.
That example contains three java source files. And, I've completely copied the "DeviceListActivity.java", which is used for searching remote bluetooth devices.
Then I've modified the "BluetoothChatService.java" to use only the RFCOMM Client functions,
and used the well-known UUID "00001101-0000-1000-8000-00805F9B34FB" for the Bluetooth RFCOMM/SPP.

 

For the plotting of waveforms, I'm using SurfaceView object to draw on its canvas.
This tutorial found on www.helloandroid.com helps me a lot for this task:
"How to use canvas in your android".









The rest of the job mainly involves porting of my previous Python S60 script to JAVA language.
It was too painful on my side, because I had to convert a single script file to multiple java + xml source files!
Nonetheless, it was a good experience for me on learning the Android SDK (JAVA programming).



Project source codes for Android and dsPIC (with APK and HEX) :

AndroidBluetoothOscilloscope.zip



Electronicslab.ph forum link : Android Bluetooth Oscilloscope



Here are some interesting projects that are also based on the Bluetooth Chat example:

Bluetooth Controlled Model Car

SPRIME



Special thanks to:

Samdroid Forum  for the customized/rooted firmwares for our Spica.

Tipidcp Spica users for sharing their tips and experiences with this android phone.



----------------------------------------------------------------------

#edit (10-15-2010)

Here's now my circuit. Nothing special on it, all are based on existing circuits.







*The dsPIC I have used is most probably NOT the best choice for this project because of the many left unused peripherals (extra pins). But, this is the only part readily available in my bin and it has the fastest ADC (2 x 2MSps) among the chips I have.

*If you prefer to change the input range via the op-amp preamp, the computation is located on the "adc.xmcd" file.

*You can use other SPP bluetooth modules aside from LMX. (accdg to manufacturer, it's already obsolete)






This is NOT considered as an oscilloscope yet. It's just a preparation of making a real PIC18F USB-based oscilloscope. For my initial testing, I used my PIC18F and PyUSB demo, same hardware and firmware for the 18F2550. The only difference is in the GUI, instead of PyQt QDial, I use PyQwt PlotCurve widget.

the Python script: (compatible with my Portable Eric 4 Python IDE (v2))
 #################################  
# USB-based oscillpscope (beta)
# using pyUSB and PyQt/PyQwt
#################################

import sys, usb
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.Qwt5 import *
from PyQt4.Qwt5.anynumpy import *

class UsbPic:
def __init__(self, vendor_id, product_id):
busses = usb.busses() # enumerate busses
self.handle = None
for bus in busses:
devices = bus.devices
for dev in devices:
if dev.idVendor==vendor_id and dev.idProduct==product_id: # device matches
self.dev = dev
self.conf = self.dev.configurations[0]
self.intf = self.conf.interfaces[0][0]
self.endpoints = []
for endpoint in self.intf.endpoints:
self.endpoints.append(endpoint)
return

def open(self):
if self.handle:
self.handle = None
try:
self.handle = self.dev.open()
self.handle.detachKernelDriver(0)
self.handle.detachKernelDriver(1)
self.handle.setConfiguration(self.conf)
self.handle.claimInterface(self.intf)
self.handle.setAltInterface(self.intf)
return True
except:
return False

def write(self, ep, buff, timeout = 100):
try:
return self.handle.interruptWrite(ep, buff, timeout) #return bytes written
except:
return 0
def read(self, ep, size, timeout = 100):
try:
return self.handle.interruptRead(ep, size, timeout) # return data read
except:
return []
def getDeviceName(self):
return self.handle.getString(2, 40)

class AmplitudevsTime(QwtPlot):
def __init__(self):
QwtPlot.__init__(self)
self.setTitle("<font size=1 color=darkblue>Potentiometer Position ( 8-bit ADC value )</font>")
self.setCanvasBackground(Qt.black)
#grid
grid = QwtPlotGrid()
#grid.enableXMin(True)
#grid.enableYMin(True)
grid.setMajPen(QPen(Qt.darkGreen, 0, Qt.DotLine))
grid.setMinPen(QPen(Qt.darkGreen, 0 , Qt.DotLine))
grid.attach(self)
# x-axis
self.setAxisTitle(QwtPlot.xBottom, "<font size=1 color=darkred>time (seconds)</font>")
self.timerange = arange(0.0, 60, 0.2) #60 seconds, 200 ms interval
self.amplitudes = zeros(len(self.timerange), Float)
# curve
self.amplitude_plot = QwtPlotCurve('Amplitude')
self.setAxisScale(QwtPlot.yLeft, 0, 255) #amplitude range : 0 to 255
self.setAxisScale(QwtPlot.xBottom, 0, 60) #time range: 0 to 60 seconds
self.amplitude_plot.setPen(QPen(Qt.yellow))
self.amplitude_plot.attach(self)

def updatePlot(self, new_value=0):
# shift amplitude array left and assign new value to z[n-1].
self.amplitudes = concatenate((self.amplitudes[1:], self.amplitudes[:1]), 1)
self.amplitudes[-1] = new_value
self.amplitude_plot.setData(self.timerange, self.amplitudes)
self.replot()

class MyForm(QDialog):
def __init__(self, parent = None):
super(MyForm, self).__init__(parent)
self.setWindowTitle("USB-based Oscilloscope (Beta) - pYUSb + PIC18F2550")
self.setMinimumSize(560, 300)
# create widgets/controls
self.connect_btn = QPushButton('Connect')
self.toggle1_btn = QPushButton('Toggle LED1')
self.toggle2_btn = QPushButton('Toggle LED2')
self.status_label = QLabel('press "Connect" button')
self.update_timer = QTimer()

self.display = AmplitudevsTime()

layout = QGridLayout()
layout.addWidget(self.display, 0, 0, 10, 15)
layout.addWidget(self.toggle1_btn, 2, 15)
layout.addWidget(self.toggle2_btn, 2, 16)
layout.addWidget(self.connect_btn, 7, 15)
layout.addWidget(self.status_label, 4, 15, 2, 2)
self.setLayout(layout)
# widgets initial condition
self.toggle1_btn.setEnabled(False)
self.toggle2_btn.setEnabled(False)
# signals
self.connect(self.connect_btn, SIGNAL("clicked()"), self.DeviceConnect)
self.connect(self.toggle1_btn, SIGNAL("clicked()"), self.toggleLED1)
self.connect(self.toggle2_btn, SIGNAL("clicked()"), self.toggleLED2)
self.connect(self.update_timer, SIGNAL("timeout()"), self.updateDisplay)

def DeviceConnect(self):
self.device = UsbPic(0x04d8, 0x0204) # Microchip Vendor ID and Product ID
if self.device.open():
self.toggle1_btn.setEnabled(True)
self.toggle2_btn.setEnabled(True)
self.update_timer.start(200) # update every 200ms
self.status_label.setText('Connected to:\n %s' %self.device.getDeviceName())
else:
self.toggle1_btn.setEnabled(False)
self.toggle2_btn.setEnabled(False)
self.update_timer.stop()
self.status_label.setText('Warning:\n No Device Found!')
def toggleLED1(self):
self.device.write(1, [0x80], 1000)
def toggleLED2(self):
self.device.write(1, [0x82], 1000)
def updateDisplay(self):
self.device.write(1, [0x81])
byteread = self.device.read(0x81, 64)
if len(byteread)>1:
self.display.updatePlot(byteread[1])

if __name__ == "__main__":
app = QApplication(sys.argv)
form = MyForm()
form.show()
sys.exit(app.exec_())

Right now, my problem is on the 18F2550 side. I still don't know how to use both the USB and ADC interrupts together. My first modification on PIC's firmware was no success. When I enabled the ADC interrupt routine, the whole program response slows down. I still have to read properly the datasheet(plus application notes), and ask for help of the 'masters'. What I'm currently doing on the code is reading a single byte of ADC value every 200ms (very slow!). From what I've understand, the PIC can (it should) send 64 bytes for every USB interrupt read request. I don't know how fast it is, but it will surely improve the PIC18F USB-based oscilloscope.



MKRdezign

İletişim Formu

Ad

E-posta *

Mesaj *

Blogger tarafından desteklenmektedir.
Javascript DisablePlease Enable Javascript To See All Widget