DIY helicopter

Hello everyone,
I want to make a helicopter using a attiny85. :slight_smile:
I have some HC11 modules that function as wireless serial bridges.
There will be some transistors to control the motors.
At the base station there would be a atmega328-p-pu that would read 2 pots and send the values to the attiny85 through serial.
My problem is how do I send two pieces information (POT1 and POT2) to the attiny 85. :confused:
Thank you,
12458

Do you know how to read the Voltage on POT1 and POT 2 and convert from A2D values ?
Do you know how to send a serial packets from the atmeag328 to the attiny85?

Do you know how to read the Voltage on POT1 and POT 2 and convert from A2D values ?

Yes.

Do you know how to send a serial packets from the atmeag328 to the attiny85?

Same as sending serial data to another Arduino but with software serial.
my question is how do I send two pieces of info.
Here is an example of controlling 1 motor but I don't know how to control two

int motorPin = 3;
#include <SoftwareSerial.h>

SoftwareSerial mySerial(0, 1); // RX, TX
 
void setup() 
{ 
  pinMode(motorPin, OUTPUT);
  mySerial.begin(9600);
} 
 
 
void loop() 
{ 
  if (mySerial.available())
  {
    int speed = mySerial.parseInt();
    if (speed >= 0 && speed <= 255)
    {
      analogWrite(motorPin, speed);
    }
  }
}

12458:
My problem is how do I send two pieces information (POT1 and POT2) to the attiny 85.

So you read the pots using AnalogRead(), then send the data byte-by-byte using SoftwareSerial.write().
If you plan to send the full 10-bit data from each pot, you'll need to send two bytes per pot. You could store the results of the analogReads in unsigned int variables, use highByte() and lowByte() to split them into 2 x 8-bit values, send the bytes to the ATtiny, then re-assemble them into 16-bit values in the ATtiny85. ie Write the first byte to a 16-bit value, shift left 8 bits, then OR the second value into the low byte.
Is this what you wanted to know? Obviously not, since in the code you posted as I was typing, you're handling 8-bit, not 16-bit data.

The analog read is 10-bit, yet you handle it in your code as 8-bit, I just saw. Are you scaling it before sending?
If so, what's the problem? You just send two bytes, not four, then store each in it's own variable, one per motor.

Ok I'll try to explain.
Using the code in my post above, I want to send the pot infomation but I can't make the microcontroller differentiate motor 1 and motor 2 as I use analogWrite(motorPin, speed); in the code.

12458:
Ok I'll try to explain.
Using the code in my post above, I want to send the pot infomation but I can't make the microcontroller differentiate motor 1 and motor 2 as I use

analogWrite(motorPin, speed);

in the code.

That's not what you asked, that's why you didn't get the answers you expected. You asked how to 'send' the data, not how to use it to control a motor.

You're still not providing enough info. After you do the analogRead() of the pots with the ATMega328, are you scaling the 10-bit data to 8-bit before sending it?

Perhaps you should post both sketches, so we can get up to speed.

And in direct response to the last post, you set up a second pin for the second motor, for example:-

const byte motor2Pin=4;

then receive the data values, into 'speed1' and 'speed2' for instance, and do this:-

analogWrite(motorPin, speed1);
analogWrite(motor2Pin, speed2);

Are we getting anywhere yet?

12458:
Yes.Same as sending serial data to another Arduino but with software serial.
my question is how do I send two pieces of info.
Here is an example of controlling 1 motor but I don't know how to control two

int motorPin = 3;

#include <SoftwareSerial.h>

SoftwareSerial mySerial(0, 1); // RX, TX

void setup()
{
  pinMode(motorPin, OUTPUT);
  mySerial.begin(9600);
}

void loop()
{
  if (mySerial.available())
  {
    int speed = mySerial.parseInt();
    if (speed >= 0 && speed <= 255)
    {
      analogWrite(motorPin, speed);
    }
  }
}

You will need to design some kind of protocol.
Why not send a Comma Separated STRING ?

Create the appropriate string in the Base.
Send String via Serial port.
Receive and Build String until End-Of-Message Code ( CRLF )
Then Parse string at the Copter

Example Command Strings:
"P1,1234CRLF" to send POT 1 value
"P2,1234CRLF" to send POT 2 value

P1 means POT #1 value next
1234 = value of POT #1

P2 means POT #2 value next
1234 = value of POT #2

use CRLF for end-of-message flag.
CRLF means "Carriage Return + Line Feed" codes.

The protocol you choose is totally up to you.

Just add more CODES like ...
"UD,1234CRLF"

Which can be interpreted "Up/Down" propeller speed.

Another set of protocols ...
"P,1234CRLF" means Pitch
"R,1234CRLF" means Roll
"Y,1234CRLF" means Yaw
"U,1234CRLF" means Up

Parse the string up to the comma and that is the COMMAND.
Parse the string up to CRLF and that is the VALUE.

If no Comma in string then throw away = Bad Data.
If more than one Comma in string then throw away = Bad Data.
If no CRLF at end of string then throw away = Bad Data.

The sky is the limit!

Can I use this

int motorPin = 3;
#include <SoftwareSerial.h>

SoftwareSerial mySerial(0, 1); // RX, TX
 
void setup() 
{ 
  pinMode(motorPin, OUTPUT);
  mySerial.begin(9600);
} 
 
 
void loop() 
{ 
  if (mySerial.available())
  {
    int speed = mySerial.read();
    if (speed >= 0 && speed <= 255)
    {
      analogWrite(motorPin, speed);
    }
    if (speed >= 256 && speed <= 510)
    {
      int motor2 =0;
      motor2 = speed = 255;
      analogWrite(motorPin, motor2);
    }
  }
}

So the atmega328 will read pot2 at 8 bit and add 255 to the value and send it over serial. Then the attiny will receive it and subtract 255 from pot 2 value and store in a new variable and will apply it to the transistor.

12458:
So the atmega328 will read pot2 at 8 bit and add 255 to the value and send it over serial. Then the attiny will receive it and subtract 255 from pot 2 value and store in a new variable and will apply it to the transistor.

Why mess about like that ? Send an identifier then the value. Use different identifiers for each axis so that the message looks like X123Y200 and so on. That makes it easy to separate the 2 values on the receiving end. Better still add a start of packet and end of packet identifier to make it even easier.

Read reply #6 for more detail.

12458:
So the atmega328 will read pot2 at 8 bit

If you mean "as 8-bit", analogRead() returns a value from 0 to 1023, a 10-bit value that will need to be stored in a 16-bit variable. Are you mapping the 10-bit value to 8-bit, or reading it directly into a byte/unsigned char variable?

UKHeliBob:
Why mess about like that ? Send an identifier then the value. Use different identifiers for each axis so that the message looks like X123Y200 and so on. That makes it easy to separate the 2 values on the receiving end. Better still add a start of packet and end of packet identifier to make it even easier.

Read reply #6 for more detail.

I wrap mine in < >, to make it easy to find the beginning and end of the packet

I wrap mine in < >, to make it easy to find the beginning and end of the packet

It's just as well that I know the context of the comment !

UKHeliBob:
It's just as well that I know the context of the comment !

I thought it was pretty clear for anyone reading the thread, in direct response to "Better still add a start of packet and end of packet identifier to make it even easier."

But in case it wasn't for some, when I send bytes serially, I send '<', byte 1, byte 2, '>'.
'<' is the start of packet identifier, and '>' is the end of packet identifier, byte 1 and byte 2 are the two data bytes.
Better?

Steve - I understood exactly what you meant in the context of the thread and I fully agree with you. What I was alluding to was that out of context your comment could perhaps be read with sexual connotations .....

I should, perhaps, have put a smiley on my comment :slight_smile:

Apologies for any confusion caused and my sense of humour.

UKHeliBob:
Steve - I understood exactly what you meant in the context of the thread and I fully agree with you. What I was alluding to was that out of context your comment could perhaps be read with sexual connotations .....

I should, perhaps, have put a smiley on my comment :slight_smile:

Apologies for any confusion caused and my sense of humour.

Oh @#$%, sorry Bob. I totally misunderstood you, and thought you were saying I should have added more info.
No need for apologies, either, it's my fault - I had to put my 16yo dog to sleep a couple of days ago, so my humour is lacking a bit right now. Everything seems serious. :frowning:
I've been trying to keep my mind occupied by spending heaps of time here on the forums.

Sorry to hear about your dog. We had 2 cats for 18 years, brother and sister, and had to have both of them put to sleep in the same year. It was a bad time for us so I know how you feel.

UKHeliBob:
Sorry to hear about your dog. We had 2 cats for 18 years, brother and sister, and had to have both of them put to sleep in the same year. It was a bad time for us so I know how you feel.

Thanks Bob. Hard at first, after 16 years with him by my side 24 hours a day, but I'm getting used to the idea. :slight_smile:
Keeping occupied on the forums has helped a lot.

mrsummitville:
You will need to design some kind of protocol.
Why not send a Comma Separated STRING ?

Create the appropriate string in the Base.
Send String via Serial port.
Receive and Build String until End-Of-Message Code ( CRLF )
Then Parse string at the Copter

Example Command Strings:
"P1,1234CRLF" to send POT 1 value
"P2,1234CRLF" to send POT 2 value

P1 means POT #1 value next
1234 = value of POT #1

P2 means POT #2 value next
1234 = value of POT #2

use CRLF for end-of-message flag.
CRLF means "Carriage Return + Line Feed" codes.

The protocol you choose is totally up to you.

Just add more CODES like ...
"UD,1234CRLF"

Which can be interpreted "Up/Down" propeller speed.

Another set of protocols ...
"P,1234CRLF" means Pitch
"R,1234CRLF" means Roll
"Y,1234CRLF" means Yaw
"U,1234CRLF" means Up

Parse the string up to the comma and that is the COMMAND.
Parse the string up to CRLF and that is the VALUE.

If no Comma in string then throw away = Bad Data.
If more than one Comma in string then throw away = Bad Data.
If no CRLF at end of string then throw away = Bad Data.

The sky is the limit!

How do I distinguish the two values? I don't know. How do I use \n\r? How do I use Serial.read to tell the difference? That is what stopping me.

Have a look at Serial input basics