Buy an Axon, Axon II, or Axon Mote and build a great robot, while helping to support SoR.

0 Members and 1 Guest are viewing this topic.

Hey I was looking into the kilobytes per second thing.Turns out with oscilloscopes you are supposed to use ksps, or kilosamples per second.So basically count the number of datapoints collected per second and display that instead.

And I was thinking. Can you make a button that automatically runs the bootloader exe? That way with a single click someone can automatically bootload up a DAQ .hex seamlessly. Sound yummy?

Here's a dumb question: What's keeping you from setting up the Axon at 1,000,000 baud? Or at 500,000 baud? 256,000 baud? All those settings would give 0% baud error and are supported by the CP2102.

But I've got a few more ideas that would make our toy oscilloscope actually quite usefull in the realm of hobby robotics: A 1-bit (yep, 1 bit) "DAC" usefull for sampling servo signals: The "DAC" would be retrograded to just "D", we'd read an digital input 8 times, make an byte and send that over the serial line. This would give 80 kilosamples per second for a resolution of 12 us - enough to properly "see" the servo signal. The primary reason I wanted to buy an oscilloscope was to be able to see servo signals.An other option would be an smart Axon application that not only sends data but also receives commands from the GUI. It would default to sending nothing and we could have a command in the GUI to select the kind of output we want from the Axon: 10bit / 8bit / 4bit / 1bit, including selection of channels. So the user might select 4 bit output from channel ADC3; The Axon would start sampling ADC3, putting together the upper 4 bits of two samples and send that over as an 8 bit byte Smiley A nice way to speed things up while still providing an fair amount of information.

QuoteHere's a dumb question: What's keeping you from setting up the Axon at 1,000,000 baud? Or at 500,000 baud? 256,000 baud? All those settings would give 0% baud error and are supported by the CP2102.Thats a good question.The ATmega640 datasheet says .5M and 1M, while the CP2102 datasheet, your software, and hyperterminal say 460800 and 921600. So I just went with 115200 to avoid any confusion - it was fast enough for the time anyway. Perhaps the ATmega datasheet was just rounding off?But now looking into it, Device Manager won't let me go above 128000.Just for the heck of it I tried to do it at 460800, and 921600, but whether I have the Axon turned on or not, your software gives an 'Unknown baud-rate.' error.

A radio button could be used to let the user define which type of auto-scaling is best for him.

What would be the options here?

function D1_ArcCos(const X : Double) : Double;function D1_ArcSin(const X : Double) : Double;function D1_Tan(const X: Double): Double;function D1_Cotan(const X: Double): Double;function D1_Secant(const X: Double): Double;function D1_Cosecant(const X: Double): Double;function D1_RadToDeg(const Radians: Double): Double;function D1_RadToGrad(const Radians: Double): Double;function D1_RadToCycle(const Radians: Double): Double;function D1_DegToRad(const Degrees: Double): Double;function D1_DegToGrad(const Degrees: Double): Double;function D1_DegToCycle(const Degrees: Double): Double;function D1_GradToRad(const Grads: Double): Double;function D1_GradToDeg(const Grads: Double): Double;function D1_GradToCycle(const Grads: Double): Double;function D1_CycleToRad(const Cycles: Double): Double;function D1_CycleToDeg(const Cycles: Double): Double;function D1_CycleToGrad(const Cycles: Double): Double;function D1_Cot(const X: Double): Double;function D1_Sec(const X: Double): Double;function D1_Csc(const X: Double): Double;function D1_Cosh(const X: Double): Double;function D1_Sinh(const X: Double): Double;function D1_Tanh(const X: Double): Double;function D1_CotH(const X: Double): Double;function D1_SecH(const X: Double): Double;function D1_CscH(const X: Double): Double;function D1_ArcCot(const X: Double): Double;function D1_ArcSec(const X: Double): Double;function D1_ArcCsc(const X: Double): Double;function D1_ArcCosh(const X: Double): Double;function D1_ArcSinh(const X: Double): Double;function D1_ArcTanh(const X: Double): Double;function D1_ArcCotH(const X: Double): Double;function D1_ArcSecH(const X: Double): Double;function D1_ArcCscH(const X: Double): Double;function D1_Log10(const X: Double): Double;function D1_Log2(const X: Double): Double;function D1_Sign(const AValue: Double): TValueSign;function D2_ArcTan2(const Y, X: Double): Double;function D2_Hypot(const X, Y: Double): Double;function D2_LogN(const Base, X: Double): Double;function D2_Power(const Base, Exponent: Double): Double;function D2_RoundTo(const AValue, ADigit: Double): Double;

1384.4*pow(X,-.9988)(15*8_bit_value-180)

1384.4*power(V,-.9988)15*V-180

rprintf("%d, %d%d, %d%d, %d%d",sharp_ir, scan_angle, wheel_left, wheel_right);

rprintf("%d %d %d %d\n",sharp_ir, scan_angle, wheel_left, wheel_right);

rprintf("%d %d %d %d",sharp_ir, scan_angle, wheel_left, wheel_right);

int angle_left;angle_left=convert_to_angle(wheel_left);rprintf("%d %d %d %d\n",sharp_ir, scan_angle, angle_left, wheel_right);

Thanks, I got it now. Although I don't see why you converted wheel_left to angle_left.

Then why didn't you convert wheel_right to an int as well?

I'm really curios how fast the Axon's DAQ is: I haven't had the time to take it out of it's envelope

Sending out constant data to the USB port (ie: rprinf("1 2 3\n")Wink I got precisely 53.4 kilobytes per second (as shown by the SoR Scope). Next I modified the super-simple loop to read a value from the ADC and then rprint-it to the USART - data rate dropped to just 17 kilobytes

Another solution - don't use the ADC for reading PWM, use a digital pin instead.

Do you, by any chance, know how I can make the ADC faster if I only want 8 bit or 4 bit precision? (I'm lazy, I'm sure it's in the datasheet!). Is there a configuration option for this or do I simply read ADCH when I feel it's time to read it? Do I tweak the ADC clock?

void axon_DAQ_fast(void) { int a9; //select speed/accuracy of data conversion a2dSetPrescaler(ADC_PRESCALE_DIV4); // configure ADC scaling while(1) { //gather data a9=a2dConvert8bit(9); //report data, add time stamp and overflow count at end of data rprintf("%d\r\n",a9); //uart2SendByte(m2);//even faster, but doesn't have carriage return } }

//select speed/accuracy of data conversion a2dSetPrescaler(ADC_PRESCALE_DIV32); // configure ADC scaling, 32 default // A2D clock prescaler select // *selects how much the CPU clock frequency is divided // to create the A2D clock frequency // *lower division ratios make conversion go faster // *higher division ratios make conversions more accurate // ADC_PRESCALE_DIV2 -> CPU clk/2 // ADC_PRESCALE_DIV4 -> CPU clk/4 // ADC_PRESCALE_DIV8 -> CPU clk/8 // ADC_PRESCALE_DIV16 -> CPU clk/16 // ADC_PRESCALE_DIV32 -> CPU clk/32 // ADC_PRESCALE_DIV64 -> CPU clk/64 // ADC_PRESCALE_DIV128 -> CPU clk/128

/****************************************************************************** Copyright (c) 2008 www.societyofrobots.com* (please link back if you use this code!)** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License version 2 as* published by the Free Software Foundation.** Alternatively, this software may be distributed under the terms of BSD* license.*****************************************************************************/void read8bit(void){ //uartSetBaudRate(1, 500000); outb(UBRR1L, 1); outb(UBRR1H, 0); a2dSetPrescaler(ADC_PRESCALE_DIV16); // Set the ADC prescale so we get fast conversions // Prepare ADC to convert from port "1" - sorry by this, that's where my inter-mcu cable lands, ADCSRB &= ~_BV(MUX5); outb(ADMUX, (inb(ADMUX) & ~7) | (1 & 7)); // the (1 & 7) part selects the port, change the 1 to something else (between 0 and 7 that is!) sbi(ADCSR, ADIF); sbi(ADCSR, ADSC); while( bit_is_set(ADCSR, ADSC) ); // Send an start byte uartSendByte(1,0); // ADC result volatile unsigned char ADCR; while (1) { while( bit_is_set(ADCSR, ADSC) ); // wait until previous conversion completes ADCR = ADC >> 2; // Start next conversion sbi(ADCSR, ADIF); sbi(ADCSR, ADSC); while(!(UCSR1A & (1<<UDRE1))); // wait until previous byte got sent outb(UDR1, ADCR); }}void read4bit(void){ //uartSetBaudRate(1, 500000); outb(UBRR1L, 1); outb(UBRR1H, 0); a2dSetPrescaler(ADC_PRESCALE_DIV8); // Set the ADC prescale so we get fast conversions // Prepare ADC to convert from port "1" - sorry by this, that's where my inter-mcu cable lands, ADCSRB &= ~_BV(MUX5); outb(ADMUX, (inb(ADMUX) & ~7) | (1 & 7)); // the (1 & 7) part selects the port, change the 1 to something else (between 0 and 7 that is!) sbi(ADCSR, ADIF); sbi(ADCSR, ADSC); while( bit_is_set(ADCSR, ADSC) ); // Send an start byte uartSendByte(1,0); // ADC result volatile unsigned char ADCR_1; volatile unsigned char ADCR_2; while (1) { while( bit_is_set(ADCSR, ADSC) ); // wait until previous conversion completes ADCR_1 = ADC >> 2; // Start next conversion sbi(ADCSR, ADIF); sbi(ADCSR, ADSC); while( bit_is_set(ADCSR, ADSC) ); // wait until previous conversion completes ADCR_2 = ADC >> 2; ADCR_1 = (ADCR_1 & 0b11110000) | (ADCR_2 >> 4); while(!(UCSR1A & (1<<UDRE1))); // wait until previous byte got sent outb(UDR1, ADCR_1); }}void control(void){ read4bit();}