MEGA48 Baby-O serial out to sparkfun 7seg 4dig serial module

Hello,

First post- hi all, and thanks for this great resource.

Been searching for a while; sorry I have to ask such a seemingly simple question.

I have the mega48 version of the baby-O and a sparkfun 4-dig serial module (http://www.sparkfun.com/products/9766). I am trying to make a program which controls a motor through a potentiometer and displays the value of the pot on the 4 digit display. Below is the code I am using (a mod of one of the example programs). It compiles, but it is too large for the mega48 (because of the string.h lib I guess?). Is there a different way of transferring the motorspeed int into the displayspeed char?

Controlling the motor works just fine, and using “serial_send(“2222”, 4);” in a program does show 2222 on the display… so everything is hooked up and functioning. I just can’t figure out code-wise how to get the motorspeed value on the display.

Thanks all!!!

Extreme noobie to C code.

#include <pololu/orangutan.h>
#include <string.h>


/*
 * motors1: for for the Orangutan LV, SV, SVP, X2, Baby-O and 3pi robot.
 *
 * This example uses the OrangutanMotors functions to drive
 * motors in response to the position of user trimmer potentiometer
 * and blinks the red user LED at a rate determined by the trimmer
 * potentiometer position.  It uses the OrangutanAnalog library to measure
 * the trimpot position, and it uses the OrangutanLEDs library to provide
 * limited feedback with the red user LED.
 *
 * https://www.pololu.com/docs/0J20
 * https://www.pololu.com
 * https://forum.pololu.com
 */

// send_buffer: A buffer for sending bytes on PD1/TXD.
char send_buffer[5];

char display_speed[5];


// wait_for_sending_to_finish:  Waits for the bytes in the send buffer to
// finish transmitting on PD1/TXD.  We must call this before modifying
// send_buffer or trying to send more bytes, because otherwise we could
// corrupt an existing transmission.
void wait_for_sending_to_finish()
{
	while(!serial_send_buffer_empty());
}

unsigned long prevMillis = 0;

int main()
{
	serial_set_baud_rate(9600);

  while(1)
  { 
  	set_analog_mode(MODE_10_BIT);
     int pot = analog_read(6);			//determine 10 bit analog value of pin 6 (0-1023)
     int motorSpeed = pot/4.02; 		//bring 10 bit number between 0 and 255
    set_motors(motorSpeed, motorSpeed);	//set motor speed to number between 0 and 255
  


		//	wait_for_sending_to_finish();
		//	memcpy_P(send_buffer, PSTR(motorSpeed), 4);
		//	serial_send(motorSpeed, 4);

			memset( display_speed, 0x00, sizeof( display_speed) );
			sprintf( display_speed, "%0d5", motorSpeed );
			serial_send(display_speed, 4 );

    int ledDelay = motorSpeed;
	if(ledDelay < 0)
	  ledDelay = -ledDelay;  // make the delay a non-negative number
	ledDelay = 256-ledDelay; // the delay should be short when the speed is high


    red_led(1);       // turn red LED on
    delay_ms(ledDelay);

    red_led(0);       // turn red LED off
	delay_ms(ledDelay);
  }
}

This line might be the problem:

     int motorSpeed = pot/4.02;       //bring 10 bit number between 0 and 255

This may require all the floating point routines to be loaded, which take a lot of memory. Try replacing with

     int motorSpeed = pot/4;       //bring 10 bit number between 0 and 255

Jim you nailed it! That got the program back to a usable size. I have some problems with the registration of the value within the 4 digits, but I think I can figure that out.

Thank you again so much!

Okay, one more bit of help on this same problem please. Below is the code. My intention was to take the 10 bit analog pot value (0-1023) and divide it by 5 to achieve a value between 0 and 204, then assign that number as the motor speed, then show that number on the LED display. But for some reason I am not seeing a number between 0 and 204 on the display:

As I rotate the potentiometer clockwise from full left to full right, the LED display shows digits starting at 0000 going up to 0990 (first and last digit staying constant at 0) through the first 75% of the pot, and then continuing to 100% of the pot the display shows numbers from 0100 to about 0204 (first digit constant at 0).

I’m somewhat confused as to why… for 2 reasons. 1) the number should be 0 to about 200, but the display is acting as if the range is more 0 to 1200. And 2) even if the value does go between 0 and 1200, the display’s right digit is not correct below 1000 and the left digit is not correct above 1000.

Thoughts?

Thanks again.

#include <pololu/orangutan.h>
#include <string.h>


/*
 * motors1: for for the Orangutan LV, SV, SVP, X2, Baby-O and 3pi robot.
 *
 * This example uses the OrangutanMotors functions to drive
 * motors in response to the position of user trimmer potentiometer
 * and blinks the red user LED at a rate determined by the trimmer
 * potentiometer position.  It uses the OrangutanAnalog library to measure
 * the trimpot position, and it uses the OrangutanLEDs library to provide
 * limited feedback with the red user LED.
 *
 * https://www.pololu.com/docs/0J20
 * https://www.pololu.com
 * https://forum.pololu.com
 */

// send_buffer: A buffer for sending bytes on PD1/TXD.
char send_buffer[5];

char display_speed[5];


// wait_for_sending_to_finish:  Waits for the bytes in the send buffer to
// finish transmitting on PD1/TXD.  We must call this before modifying
// send_buffer or trying to send more bytes, because otherwise we could
// corrupt an existing transmission.
void wait_for_sending_to_finish()
{
	while(!serial_send_buffer_empty());
}

//unsigned long prevMillis = 0;   //in example program why?

int main()
{
	serial_set_baud_rate(9600);

  while(1)
  { 
  	set_analog_mode(MODE_10_BIT);
     int pot = analog_read(6);			//determine 10 bit analog value of pin 6 (0-1023)
     int motorSpeed = pot/5; 		//bring 10 bit number between 0 and 255
    set_motors(motorSpeed, motorSpeed);	//set motor speed to number between 0 and 255
  


		//	wait_for_sending_to_finish();
		//	memcpy_P(send_buffer, PSTR(motorSpeed), 4);
		//	serial_send(motorSpeed, 4);

		//	wait_for_sending_to_finish();
		//	memset( display_speed, 0x00, sizeof( display_speed) );
			sprintf( display_speed, "%0d5", motorSpeed );
			serial_send(display_speed, 4 );

    int ledDelay = motorSpeed;
	if(ledDelay < 0)
	  ledDelay = -ledDelay;  // make the delay a non-negative number
	ledDelay = 256-ledDelay; // the delay should be short when the speed is high


    red_led(1);       // turn red LED on
    delay_ms(ledDelay);

    red_led(0);       // turn red LED off
	delay_ms(ledDelay);

			serial_send("v", 4 );

  }
}

Hello,

Your “%0d5” should probably be a “%04d” - if you want 4 digits, zero padded.

-Paul

Thanks Paul! Actually that made the display slightly worse. That made an errant ‘4’ on the right most digit of the display when below 0990 (so, 0994). And above 0994 the left most digit is a fast flickering 4 with the right 3 digits showing between 100 and 200.

Looking more closely at the display’s behavior; the action of the previously quoted program is more easily described like this: I think the display is incorrectly showing the 2 digit pot value here: 0XX0 instead of here: 00XX. Then when the value is 3 digits it displays the value here: 0XXX correctly.

I am still confused as to why. Thoughts?

Thanks all.

Hello,

The previous program is just wrong, so it does not make sense to keep running it. Are you sure that you did “%04d” instead of “%0d4”? The first one means print a four-digit, zero-padded integer. I don’t know what the second means, but it is going to result in something followed by a “4”.

In general, if you want help with code, simplify your program to the simplest thing that does not work (e.g. just a couple of lines) and post the code here. Otherwise I can only guess about what you are doing.

-Paul