Show Posts
|
|
Pages: 1 2 [3] 4 5 6
|
|
31
|
Forum 2005-2010 (read only) / Syntax & Programs / How can I write a custom data structure to EEPROM
|
on: March 26, 2010, 10:12:43 pm
|
Hello all you clever folk. I have a project underway to construct an RC transmitter using an Arduino for the PPM encoder board. What I want to do is to be able to have the user change certain paramenters (servo end-stops, direction, mix properties etc) and to then be able to save these to the eeprom. I have several custom data structures, such as: typedef struct { int top; //stick top value int center; //stick center value int bottom; //stick bottom value int dead_zone; //stick dead zone. A zero value disables the dead zone feature int input; //stick input port int type; //stick type (0: center/deflection, 1: end/offset) int trim; //stick trim int rates; //stick rate switch bool exponential; //exponential int position; //current stick position } stick;
typedef struct { int top; //servo top value (micro seconds) int center; //servo center value int bottom; //serve bottom value float prop_throw_adjust; //proportial throw reduction float neg_throw_adjust; //negative throw adjust float pos_throw_adjust; //positive throw adjust bool reverse; //servo reverse } tx_output_channel;
typedef struct { int idle_point; //Throttle idle point int mid_point; //Throttle mid point int top_point; //Throttle top point bool allow_negative; //allow negative throttle, useful for cutting the engine on an IC plane } throttle;
typedef struct { bool enable; //mixer enabled float differential; //Amount of differential int mix_dir; //mix direction int secondary_channel; //The channel on which to output the second aileron signal int secondary_direction; //The direction in which to deflect the second servo. can be 1 or -1. bool reverse_ailerons; //reverse ailerons. } diff_mixer;
typedef struct { bool enable; //mixer enable float e_ratio; //mix elevator ratio, 0 - 0.5 float r_ratio; //mix rudder ratio, 0 - 0.5 int mix_direction; //mix direction } vtail_mixer;
typedef struct { bool enable; //mixer enable float e_ratio; //elevator ratio float a_ratio; //aileron ratio float differential; //Amount of differential int dmix_dir; //differentail mix direction int emix_dir; //elevator mix direction int secondary_direction; //The direction in which to deflect the second servo. can be 1 or -1. bool reverse_ailerons; //reverse ailerons. bool reverse_elevators; //reverse elevators } delta_mixer;
I want to be able to write and read data using these data types to the EEPROM. Now the £1,000,000 question: Is there a way to do this relativly easily? A little information:All the float values contain no more than 2 decimal places. The majority of int values are between 0 and 100, the only exceptions being the 'stick' top, center and bottom values, and the 'output' top, center and bottom values which go to a maximum of 1023 and 2000 respectivly. The '_mixer' and 'throttle' types only have one instance of each, the 'stick' and 'tx_output_channel' have 4 and 7 instances respectivly. Answers on the back of a postcard..... Chris Parish
|
|
|
|
|
35
|
Forum 2005-2010 (read only) / Syntax & Programs / Problem with custom data types
|
on: March 23, 2010, 07:57:33 pm
|
Hello all! I am trying to get some code to work using custom data types. The types is defined like this: typedef struct { int top; int center; int bottom; int input; int type; int trim; int rates; int position; } stick;
I then create an array: stick sticks[4];
I then try to set the contents of the array using this function void set_sticks() { for (int i = 0; i < 5; i++) { sticks[i].top = stick_limits[i][0]; sticks[i].center = stick_limits[i][1]; sticks[i].bottom = stick_limits[i][2]; sticks[i].type = stick_types[i]; sticks[i].input = stick_inputs[i]; sticks[i].trim = stick_trims[i]; sticks[i].rates = stick_rates[i]; sticks[i].position = 0; } }
but when I do the arduino crashes.  I can access any item in the array from any other point like this: sticks[0].top = 200;
or using a look like in the set_sticks() function. Does anyone have any idea why this might not be working? I can't get my head around it.
|
|
|
|
|
36
|
Forum 2005-2010 (read only) / Interfacing / Re: Aquarium Reef Controller, stage 1, the LCD shield,
|
on: March 30, 2010, 10:54:55 am
|
Hi Luke, That look like an interesting project. I have a freshwater tank myself and you have got me thinking about the automation possabilities. All the temperature monitoring should be really easy, the difficult point is deciding which of about ten million methods to use!  I look forward to seeing your code, and I hope I can help you with your project. Keep us posted! Chris
|
|
|
|
|
37
|
Forum 2005-2010 (read only) / Interfacing / Re: Aquarium Reef Controller, stage 1, the LCD shield,
|
on: March 30, 2010, 10:27:08 am
|
|
If the LCD is visibly flickering then the chances are that you are clearing the LCD screen on each loop. Simply removing the clear statement and just overwriting will get rid of the flicker.
Also, if the sheild is blocking the pins then just make yourself some leads to connect it instead of plugging it straight in on top of the arduino.
What are you hoping to achive with the Aquarium Reef Controller?
Can't really do much more without seeing your code; any chance you could post it?
Chris
|
|
|
|
|
38
|
Forum 2005-2010 (read only) / Interfacing / Re: tryiing to get a stepper motor to work on ardiuno
|
on: March 30, 2010, 10:12:58 am
|
Closer inspection of your picture leads me to think that you have a L239D H bridge chip. Assuming you have then try running the MotorKnob example bundled with the Arduino IDE, you might need to change some of the pin bindings. If this works then replace the code in setup() and loop() with this: void setup() { stepper.setSpeed(30); }
loop() { stepper.step(100); }
watch your motor turn, if it goes more than one turn, then reduce the number of steps set by #define STEPS on line 13. If it goes less then a turn then increase the number of steps. Once you have found the number of steps per turn then you can follow the code suggested by PaulS Chris
|
|
|
|
|
40
|
Forum 2005-2010 (read only) / Troubleshooting / Re: Difference between using cli() sei() and TIMSK
|
on: April 01, 2010, 11:34:38 pm
|
the compiler will take care of 16bits, but it does not disable interrupts...
on closer inspection of the datasheet I see that you are quite right. My apologies :-[ The AVR contains special hacks in its 16bit registers that require that the two bytes be written by consecutive instructions.
Quick question: How can it be a hack if it is the way it is designed?  Also, having read the datasheet more carefully it can be seen that the second part of that statement is not strictly correct; The updating of the 16 bit registers is triggered by writing to the low byte and it is possible to re-use the high byte, therefore it does not require the bytes to be written by consecutive instructions but just that the high byte be written before the low byte. From the datasheet:If writing to more than one 16-bit register where the high byte is the same for all registers written, then the high byte only needs to be written once.
The reason to disable the interrupts prior to updating the 16bit registers is not to ensure that the two instructions take place consecutively, but to ensure that nothing else updates the registers in between the two instructions. If an interrupt did occur, but it didn't access the 16bit register you were previously in the middle of updating, the 16bit register would still be updated correctly. But generally speaking it would be a bloomin' good idea to disable interrupts prior to writing to the 16bit registers. I'm off to update some of my code accordingly...... oops! Chris
|
|
|
|
|
42
|
Forum 2005-2010 (read only) / Troubleshooting / Re: Problem with timers
|
on: March 21, 2010, 03:18:44 am
|
Thanks for the reply, Are you sure you don't have a timebase stretch knob twiddled on your scope or something like that? This was my first thought, but I can find no such knob to twiddle. I hooked up a RTC chip I have that can output a square wave at 4.097kHz and that appeared to be correct. I am glad that the code appears to work on a different unit, at least I now know that it is either my arduino or my scope.
|
|
|
|
|
44
|
Forum 2005-2010 (read only) / Troubleshooting / Problem with timers
|
on: March 19, 2010, 11:37:02 pm
|
Hello Folks! I am experimenting with timers at the moment, and I have set up timer 1 to give me a 10ms pulse every 10ms using PMW Phase and Frequency correct mode (PFCPWM). My maths went like this: CPU Frequency: 16,000,000 Prescaler: 8 Therefore there are 2,000,000 timer clock pluses per second. With me so far? Because PFCPWM mode counts both up and down, the required 'TOP' value to get a frame length of 20ms (50Hz) should be 20000. 16000000/(2*8*20000) = 50Hz using the formula on page 133 of the datasheet. I used a compare value of 10000 for the OCR1A register to generate the pulse within the frame. And now we get the problem: I measured the length of fame and the pulse using an oscilloscope but both values were 10% lower than they should be.  If I add a correction factor of 1.1 then it gives the expected result. Given that the timer uses the CPU clock frequency as its basis, is my arduino running too quickly or am I doing something fundamentally wrong. The code I have used is as follows: /* Experiments with timers Version 1 */
int top = 20000; int oca = 10000;
float crf = 1.1;
void setup() { TCCR1A = B11000000; // COM1A1 and COM1A0 set to 1 TCCR1B = B00010010; // WGM13 and CS11 set to 1 TCCR1C = B00000000; // All set to 0 TIMSK1 = B00000000; // Not using interrupts yet TIFR1 = B00000000; // Not using interrupts yet ICR1 = top * crf; OCR1A = oca * crf;
pinMode(9, OUTPUT);
}
void loop() {
}
Any ideas? I have checked the oscilloscope using a clock generator and at a frequency of 4.096kHz I am masuring a frame width of 240 micro seconds. The actual value should be 244.1 micro seconds, but my eyes won't resolve it any higher than 240 on my very old farnell oscilloscope.
|
|
|
|
|