Open csurf opened 6 years ago
(linuxslate is RCG user 'carcynic'.)
You can see a picture of my Anarduino-22-433-based receiver in this post: https://www.rcgroups.com/forums/showpost.php?p=38892572&postcount=9465
Here is my wiring:
SDO D12
SDI D11
SCK D13
NSEL D10
NIRQ D2
SDN D4
PPM IN (TX) None (Can be D8)
LED 1 (Red) D9
LED 2 (Green) None
Button None
Buzzer None
PWM 1 A2 also PPM
PWM 2 A4 also SDA
PWM 3 A3 also RSSI
PWM 4 A4 also SCL
PWM 5 A0
PWM 6 A1
Here is a stab at a (BOARD_TYPE == 10) // Anarduino-22-433 as RX.
Only worrying about RX at this time, but there is no reason not to leave the TX code in there.
I'm not a "real" Atmel programmer, so this is going to need some help.
#if (BOARD_TYPE == 10) // Anarduino-22-433 as RX
#if (__AVR_ATmega328P__ != 1) || (F_CPU != 16000000)
#warning Possibly wrong board selected, select Arduino Pro/Pro Mini 5V/16MHz w/ ATMega328
#endif
#if (COMPILE_TX == 1) // TX operation
HardwareSerial *rcSerial = &Serial;
#define USE_ICP1 // use ICP1 for PPM input for less jitter
#define PPM_IN 8 // ICP1
#define TX_AIN0 A4 // SDA
#define TX_AIN1 A5 // SCL
#define TX_MODE1 A1
#define TX_MODE2 A2
#define BUZZER_PAS 3 // OCR2B
#define BTN A0
#define RF_OUT_INDICATOR A3 // only used for Futaba
void buzzerInit()
{
TCCR2A = (1<<WGM21); // mode=CTC
#if (F_CPU == 16000000)
TCCR2B = (1<<CS22) | (1<<CS20); // prescaler = 128
#elif (F_CPU == 8000000)
TCCR2B = (1<<CS22); // prescaler = 64
#else
#errror F_CPU Invalid
#endif
pinMode(BUZZER_PAS, OUTPUT);
digitalWrite(BUZZER_PAS, LOW);
}
void buzzerOn(uint16_t freq)
{
if (freq) {
uint32_t ocr = 125000L / freq;
if (ocr>255) {
ocr=255;
}
if (!ocr) {
ocr=1;
}
OCR2A = ocr;
TCCR2A |= (1<<COM2B0); // enable output
} else {
TCCR2A &= ~(1<<COM2B0); // disable output
}
}
#else
// RX operation
#define PPM_OUT A2 // A2
#define RSSI_OUT A3 // A3
#define PWM_1 A2 // 0 PC1 - also PPM
#define PWM_2 A4 // 1 PC4 - also SDA
#define PWM_3 A3 // 2 PC3 - also RSSI
#define PWM_4 A5 // 3 PC5 - also SCL
#define PWM_5 A0 // 4 PC0
#define PWM_6 A1 // 5 PC1 - Buzzer
#define OUTPUTS 8 // outputs available
const pinMask_t OUTPUT_MASKS[OUTPUTS] = {
{0x00,0x04,0x00}, {0x00,0x10,0x00}, {0x00,0x08,0x00},// CH1/PPM, CH2/SDA, CH3/RSSI
{0x00,0x20,0x00}, {0x00,0x01,0x00}, {0x00,0x02,0x00},// CH4/SCL, CH5/PWM, CH6/PWM
{0x00,0x00,0x01}, {0x00,0x00,0x02}, // CH7/RXD, CH8/TXD - only on 6ch
};
#define PPM_OUTPUT 0
#define RSSI_OUTPUT 2
#define ANALOG0_OUTPUT 1 // actually input
#define ANALOG1_OUTPUT 3 // actually input
#define SDA_OUTPUT 1
#define SCL_OUTPUT 3
#define LLIND_OUTPUT 5
#define RXD_OUTPUT 6
#define TXD_OUTPUT 7
const uint8_t OUTPUT_PIN[OUTPUTS] = { A2, A4, A3, A5, A0, A1, 0, 1};
struct rxSpecialPinMap rxSpecialPins[] = {
{ 0, PINMAP_PPM},
{ 1, PINMAP_SDA},
{ 1, PINMAP_ANALOG}, // AIN0
{ 2, PINMAP_RSSI},
{ 2, PINMAP_LBEEP},
{ 3, PINMAP_SCL},
{ 3, PINMAP_ANALOG}, // AIN1
{ 5, PINMAP_LLIND},
{ 6, PINMAP_RXD},
{ 7, PINMAP_TXD},
{ 7, PINMAP_SPKTRM},
{ 7, PINMAP_SBUS},
{ 7, PINMAP_SUMD},
};
void rxInitHWConfig()
{
rx_config.rx_type = RX_ANARDUINO_6CH;
rx_config.pinMapping[0] = PINMAP_PPM;
rx_config.pinMapping[1] = PINMAP_ANALOG;
rx_config.pinMapping[2] = PINMAP_RSSI;
rx_config.pinMapping[3] = PINMAP_ANALOG;
rx_config.pinMapping[4] = 4;
rx_config.pinMapping[5] = 5;
rx_config.pinMapping[6] = PINMAP_RXD;
rx_config.pinMapping[7] = PINMAP_TXD;
}
#endif
#define Red_LED 9 // D9 PB1
#define Green_LED 5 // D5 PD5
#define buzzerOff(foo) buzzerOn(0)
#define Red_LED_ON PORTB |= _BV(1);
#define Red_LED_OFF PORTB &= ~_BV(1);
#define Green_LED_ON PORTD |= _BV(5);
#define Green_LED_OFF PORTD &= ~_BV(5);
#define RF_OUT_INDICATOR A3 // only used for Futaba
//## RFM22B Pinouts for Public Edition (M2)
#define nIRQ_1 (PIND & 0x04)==0x04 //D2
#define nIRQ_0 (PIND & 0x04)==0x00 //D2
#define nSEL_on PORTB |= (1<<2) //B2
#define nSEL_off PORTB &= 0xFB //B2 Need help with value here
#define SCK_on PORTB |= _BV(5) //B5
#define SCK_off PORTB &= ~_BV(5) //B5
#define SDI_on PORTB |= _BV(3) //B3
#define SDI_off PORTB &= ~_BV(3) //B3
#define SDO_1 (PINB & _BV(4)) == _BV(4) //B4
#define SDO_0 (PINB & _BV(4)) == 0x00 //B4
#define SDO_pin 12
#define SDI_pin 11
#define SCLK_pin 13
#define IRQ_pin 2
#define nSel_pin 10
#define SDN_pin 4
void setupSPI()
{
pinMode(SDO_pin, INPUT); //SDO
pinMode(SDI_pin, OUTPUT); //SDI
pinMode(SCLK_pin, OUTPUT); //SCLK
pinMode(IRQ_pin, INPUT); //IRQ
pinMode(nSel_pin, OUTPUT); //nSEL
}
#define IRQ_interrupt 0
void setupRfmInterrupt()
{
attachInterrupt(IRQ_interrupt, RFM22B_Int, FALLING);
}
#endif
Note also:
Above code edited to change:
x_config.rx_type = RX_ANARDUINO_6CH
Add:
#define RX_ANARDUINO_6CH 0x09
To the top.
In dialog.h, add:
else if (rx_config.rx_type == RX_ANARDUINO_6CH) {
Serial.println(F("Anarduino-22"));
}
This looks like an exciting new option. Thanks for putting in the effort to add this, @linuxslate.
Would you be able to open a pull request for these changes?
Currently, with the above code, I can bind, and connect through the TX to the RX on the configurator. I can configure the RX, and it retains the configuration, but I do not get any servo movement.
(I know I have to disconnect from the configruator) to get servo movement. I don't have a O-Scope anymore so I cannot see what is going on on any of the pins.
I am wired directly from the Anarduino lines to the servo connector pins.
@mikeller ;
I am not a git pro, but I can try.
@linuxslate: No problem. There's people here who can help. :-)
@linuxslate, once you get something closer to a final product, let me know, and I can setup a branch on my repo so that we can do the pull request from it.
As far as testing the outputs, first see if you can get PPM output working, and forget about trying to get the PWM outputs working. Send the PPM output to a flight controller and use the FC's config software to inspect the PPM signal. You could also look into setting up a software o-scope using your PC's soundcard via the line-in/microphone input. There are plenty of guides online on how to do this...
I noticed the anarduino has an RTC IC and flash memory. That might be pretty cool to use for RX stats logging (something I've messed with in the past).
Good idea about using a Flight controller. I kinda got out of the quad racing thing, so it's been a while since I messed with those types of Flight Controllers, but I think there is a loose one around here someplace, or I will have to enlist what remains of my 250 racer to help me.
It's is interesting that it seems to bind. Even connected to a terminator, it will bind and configure from one end of the house to the other, but after it binds, nothing happens.
I enabled #define DEBUG_DUMP_PPM, and I get nothing after "entering normal mode" (Receiver connected to minicom.)
@linuxslate yeah, that was going to be my other suggestion: to try turning on the serial debug for the PPM signal. The fact that you're not seeing anything makes me wonder if the board isn't somehow crashing/hanging, or perhaps the TX is bombing and not actually sending any RC data over. You might want to have a look at the TX side first and make sure that things are setup correctly. Can you see valid channel data in the signal analyzer within the Configurator app?
I do not see any significant peaks in the configurator Spectrum Analyzer. The TX does not seem to transmit when I go to that tab.
Should the SA tab work without a receiver? Should I see hop spikes without a PPM input to the TX?
Anytime the unit is looking for the receiver -- Bind mode by pressing the button, or bind mode by disconnecting from the configurator, or when I connect to the configurator and go to the Receiver tab, I can see a strong spike on my RF Explorer on a single frequency (>+25db, 435mhz).
When in the SA tab, I do not see any signals on my RF Explorer either. The TX never seems to transmit when I am on the SA tab.
The configurator SA, and the Transmitter receiver portion both work, because I can see it if key my ham radio nearby.
Having exhausted all other options, I am ordering some new RFM23BP's even though mine certainly seems to both transmit and receive.
I can confirm that the Anarduino-22-433 works as a receiver. The code above should be essentially correct, but I will either do a pull request, or cut and paste my current code here.
It is tested only as a receiver with 6 PWM outputs. PPM appears to/should work, but I haven't tested telemetry or anything else yet.
Transmitter operation is not tested, but I think the
... would have to be removed. My understanding of the code is that this is for a physical switch, and to save size/weight/complexity, I would not implement this on a device that is intended for the flight side.
On the other hand, an Anarduino is small enough to be point-to-point wired inside almost any transmitter without a bulge on the back, so others are welcome to test the transmitter portion.
Also, if you do not mind a little spaghetti in your aircraft, the Anarduino could be point to point wired to the flight controller (or servos), without modification or external components, making it by far the smallest/lightest OpenRLSng receiver.
Mine is built on a small daughter board so that is it essentially like any common R/C receiver, and is comparable in size. It's a little heavy due to it actually being 3 PCB's thick.
https://static.rcgroups.net/forums/attachments/4/9/8/9/8/7/a10613279-110-IMG_20171229_19000_sm.jpg
Current, Working (RX only) code for (BOARD_TYPE == 10) // Anarduino-22-433 as RX
#if (BOARD_TYPE == 10) // Anarduino-22-433 as RX
#if (__AVR_ATmega328P__ != 1) || (F_CPU != 16000000)
#warning Possibly wrong board selected, select Arduino Pro/Pro Mini 5V/16MHz w/ ATMega328
#endif
#if (COMPILE_TX == 1) // TX operation
HardwareSerial *rcSerial = &Serial;
#define USE_ICP1 // use ICP1 for PPM input for less jitter
#define PPM_IN 8 // ICP1
#define TX_AIN0 A4 // SDA
#define TX_AIN1 A5 // SCL
//#define TX_MODE1 A1
//#define TX_MODE2 A2
// No mode switch
#define BUZZER_PAS 3 // OCR2B
#define BTN A0
#define RF_OUT_INDICATOR A3 // only used for Futaba
void buzzerInit()
{
TCCR2A = (1<<WGM21); // mode=CTC
#if (F_CPU == 16000000)
TCCR2B = (1<<CS22) | (1<<CS20); // prescaler = 128
#elif (F_CPU == 8000000)
TCCR2B = (1<<CS22); // prescaler = 64
#else
#error F_CPU Invalid
#endif
pinMode(BUZZER_PAS, OUTPUT);
digitalWrite(BUZZER_PAS, LOW);
}
void buzzerOn(uint16_t freq)
{
if (freq) {
uint32_t ocr = 125000L / freq;
if (ocr>255) {
ocr=255;
}
if (!ocr) {
ocr=1;
}
OCR2A = ocr;
TCCR2A |= (1<<COM2B0); // enable output
} else {
TCCR2A &= ~(1<<COM2B0); // disable output
}
}
#else
// RX operation
#define PPM_OUT A2 // A2
#define RSSI_OUT A3 // A3
#define PWM_1 A2 // 0 PC1 - also PPM
#define PWM_2 A4 // 1 PC4 - also SDA
#define PWM_3 A3 // 2 PC3 - also RSSI
#define PWM_4 A5 // 3 PC5 - also SCL
#define PWM_5 A0 // 4 PC0
#define PWM_6 A1 // 5 PC1 - Buzzer
#define OUTPUTS 8 // outputs available
const pinMask_t OUTPUT_MASKS[OUTPUTS] = {
{0x00,0x04,0x00}, {0x00,0x10,0x00}, {0x00,0x08,0x00},// CH1/PPM, CH2/SDA, CH3/RSSI
{0x00,0x20,0x00}, {0x00,0x01,0x00}, {0x00,0x02,0x00},// CH4/SCL, CH5/PWM, CH6/PWM
{0x00,0x00,0x01}, {0x00,0x00,0x02}, // CH7/RXD, CH8/TXD - only on 6ch
};
#define PPM_OUTPUT 0
#define RSSI_OUTPUT 2
#define ANALOG0_OUTPUT 1 // actually input
#define ANALOG1_OUTPUT 3 // actually input
#define SDA_OUTPUT 1
#define SCL_OUTPUT 3
#define LLIND_OUTPUT 5
#define RXD_OUTPUT 6
#define TXD_OUTPUT 7
const uint8_t OUTPUT_PIN[OUTPUTS] = { A2, A4, A3, A5, A0, A1, 0, 1};
struct rxSpecialPinMap rxSpecialPins[] = {
{ 0, PINMAP_PPM},
{ 1, PINMAP_SDA},
{ 1, PINMAP_ANALOG}, // AIN0
{ 2, PINMAP_RSSI},
{ 3, PINMAP_SCL},
{ 3, PINMAP_ANALOG}, // AIN1
{ 5, PINMAP_LLIND},
{ 6, PINMAP_RXD},
{ 7, PINMAP_TXD},
// { 7, PINMAP_SPKTRM},
// { 7, PINMAP_SBUS},
// { 7, PINMAP_SUMD},
};
void rxInitHWConfig()
{
rx_config.rx_type = RX_ANARDUINO_6CH;
rx_config.pinMapping[0] = PINMAP_PPM;
rx_config.pinMapping[1] = PINMAP_ANALOG;
rx_config.pinMapping[2] = PINMAP_RSSI;
rx_config.pinMapping[3] = PINMAP_ANALOG;
rx_config.pinMapping[4] = 4;
rx_config.pinMapping[5] = 5;
rx_config.pinMapping[6] = PINMAP_RXD;
rx_config.pinMapping[7] = PINMAP_TXD;
}
#endif
#define Red_LED 5 // 9 PB1
#define Green_LED 9 // 5 PD5
#define buzzerOff(foo) buzzerOn(0)
#define Red_LED_ON PORTD |= _BV(5); //B1
#define Red_LED_OFF PORTD &= ~_BV(5);
#define Green_LED_ON PORTB |= _BV(1); //D5
#define Green_LED_OFF PORTB &= ~_BV(1);
//## LED's reversed. The LED on the Anarduino (which is actually Red)
//## is more useful acting as the Green LED.
//## RFM22B Pinouts for Public Edition (M2)
#define nIRQ_1 (PIND & 0x04)==0x04 //D2
#define nIRQ_0 (PIND & 0x04)==0x00 //D2
#define nSEL_on PORTB |= (1<<2) //B2
#define nSEL_off PORTB &= 0xFB //B2
#define SCK_on PORTB |= _BV(5) //B5
#define SCK_off PORTB &= ~_BV(5) //B5
#define SDI_on PORTB |= _BV(3) //B3
#define SDI_off PORTB &= ~_BV(3) //B3
#define SDO_1 (PINB & _BV(4)) == _BV(4) //B4
#define SDO_0 (PINB & _BV(4)) == 0x00 //B4
#define SDO_pin 12
#define SDI_pin 11
#define SCLK_pin 13
#define IRQ_pin 2
#define nSel_pin 10
#define SDN_pin 4
void setupSPI()
{
pinMode(SDO_pin, INPUT); //SDO
pinMode(SDI_pin, OUTPUT); //SDI
pinMode(SCLK_pin, OUTPUT); //SCLK
pinMode(IRQ_pin, INPUT); //IRQ
pinMode(nSel_pin, OUTPUT); //nSEL
}
#define IRQ_interrupt 0
void setupRfmInterrupt()
{
attachInterrupt(IRQ_interrupt, RFM22B_Int, FALLING);
}
#endif
@linuxslate not sure, but I think that your PR might have got screwed up. I will try to take a look at it later.
I meant to say "signal monitor" up above and not "analyzer." The idea was to check the signal monitor for valid PPM channel data coming into the RX, but it seems like you got it figured out.
FYI, this might not have worked for you anyway because there's currently a bug in the code that breaks the signal monitor in configurator until you hit the "save EEPROM" button (I'm gonna need to open a separate issue for this).
@linuxslate is this working? Should we close this out, or are you still testing?
I am still testing, but I have gotten far enough to know that the Anarduino-22-433 does work as a receiver. Especially with the discussions here in the issue tracker, as well as other forums, which indicate a lack of hardware being currently produced for OpenLRSng, I think this module should be supported. I am pretty sure it is also the smallest and lightest hardware for OpenLRSng. It would easily fit on a racing drone, or small airplane. I hope to do a ground test video soon, followed by flight videos. I have submitted my code above, but I do not plan to create a separate branch. I would like to see my code added as a hardware profile, and maintained just like the other hardware profiles are. There is not a separate branch or developer for each board/hardware profile. If someone uses this board, and has a problem, then they can submit a new issue. If there is a reason to cull boards that are not used, then an issue can be open to cull this board -- if no one but me uses the board, then I am OK with it not being included, or culled later.
@linuxslate: I am all on board for adding this as an additional target. Even if it is just you using it (initially), if we don't add it as a target, the chance of others picking it up and using it is even slimmer.
Update: Good news: I finally have a modern flight controller to test with. Bad news: PPM out does not work. Also likely that RSSI out on a pin does not work either. This may force a change in pin choices.
Haven't tried telemetry yet, but I plan to test at least serial (MSP passthru?) telemetry.
By looking at the code, I have found out why I was having difficulty with PPM.
Declarations like:
PPM_OUT is never referenced.
The only thing that can change the PPM Output pin is the declaration:
This would move PPM to OC1B (D10), Which will not help us because the Anarduino-22 uses D10 as NSEL.
The Anardino has an internal (Red) LED connected to D9, but this does not interfere with it's use for a PPM Output. The LED in effect becomes a PPM/PWM activity indicator. (See -- It's a feature!)
LEDs can be wired to pins D5,D6 if/as hardware builders would like.
As soon as I connected D9 to my iNav FC, PPM worked. (Receiver settings such as "Limit PPM out to 8 channels" may still be necessary, depending on your flight controller.)
I can also confirm (OK, I am really stating it -- I need others to confirm) that RSSI on a PPM channel works.
RSSI/PWM_3 must also move to D3. On Anarduino, this seems to be connected to an internal pull-up, but this should not cause any issue with it being used as an output.
This is needed because #define RSSI_OUT 3 is also never used. Changing it to another pin in hardware.h will not do anything.
It also seems that none of the #define PWM_
The only thing that defines pin numbers is the: const uint8_t OUTPUT_PIN[OUTPUTS] = { 9, A4, 3, A5, A0, A1, 0, 1}; and the pinMask const
Bottom line is that there is a lot of dead code in hardware.h (Try grep'ing -r for some of the defined constants).
I am not sure if opening another issue for dead code in hardware.h is constructive, or just complaining. Since I don't own the other hardware to test it, I cannot really "fix" all of the other boards.
Sorry; Edited above several times.
Anarduino used as an openLRSng receiver ends up being really similar to BOARD_TYPE == 5, but it still needs a separate BOARD_TYPE == 10 because the RFM22 pins are hardwired and are different than BOARD _TYPE == 5.
New wiring table and code to follow shortly.
The Anardino has an internal (Red) LED connected to D9, but this does not interfere with it's use for a PPM Output. The LED in effect becomes a PPM/PWM activity indicator. (See -- It's a feature!)
I like that. :-D Also, you now can use the red led for an optically attached slave tx. ;-)
I am not sure if opening another issue for dead code in hardware.h is constructive, or just complaining. Since I don't own the other hardware to test it, I cannot really "fix" all of the other boards.
I suspect that this is a big part of the reason why hardware.h
is such a mess - changes will be difficult to test by any one person due to lack of having access to all of the hardware modules.
I like that. :-D Also, you now can use the red led for an optically attached slave tx. ;-)
Not sure about that, but you do bring up a good point. Given the size and cost of the Anarduino, It almost does not make sense not to use it in a diversity arrangement.
I suspect that this is a big part of the reason why hardware.h is such a mess - changes will be difficult to test by any one person due to lack of having access to all of the hardware modules.
W/o an easy solution, perhaps we could open an issue where we keep a list list of testers with appropriate HW 🤷♂️
https://github.com/Brotronics/subMicroLRS (Type 5)
https://github.com/openLRSng/openLRSngWiki/wiki/HawkEye-DTF-UHF-JR-Deluxe-TX-module (Type 4)
Also willing to purchase LoRA HW once it's determined which is most appropriate for 433 and 900.
Good point, @fiveangle!
+1 vote for a 'hardware testers' issue/thread
I'm not too familiar with github, but it would be great to be able to setup some kind of automated build script that automatically notifies a 'tester group' that there's a fix/patch/PR that needs to be tested for their hardware. Not sure if this is possible through github, but something like this would be pretty cool.
Updated Wiring: "*" = Hardwired on Anarduino-22-433
SDO D12*
SDI D11*
SCK D13*
NSEL D10*
NIRQ D2*
SDN D4*
PPM IN (TX) None (Can be D8 - 2.2K Resistor in series Recommended.) TX not tested.
LED 1 (Red) D6 (Optional - Add 220 Ohm Resistor and LED to ground)
LED 2 (Green) D7 (Optional - Add 220 Ohm Resistor and LED to ground)
Button None. TX not tested.
Buzzer None. TX not tested.
PWM 1 D9 also PPM *On Board LED
PWM 2 A4 also SDA
PWM 3 D3 also RSSI
PWM 4 A5 also SCL
PWM 5 A0
PWM 6 A1
RX Data D0 (*FTDI RX)
TX Data D1 (*FTDI TX)
Thanks @linuxslate. We are currently having some discussion about moving to a better way of maintaining the definition for the different hardware targets (#139). I think the best course of action for this new target is to wait until we've concluded this discussion, and implemented the outcome (better structured hardware definitions), before we are adding a definition for your new target. No point in clobbering the new target into hardware.h
, only to then have to spend more time separating it out again. If you want to provide testers with a version of your target, you can always do so by posting a (zipped) test build for it.
Add hardware profile support for 'Anarduino MiniWireless' modules based on RFM22B. More info can be found here: http://www.anarduino.com/miniwireless/
This would be setup as hardware type '10', and would include support for both a 'TX' and 'RX' profile.
Pin mappings & testing to be done by RCG user 'carcynic'. If things get complicated, I will consider ordering a pair of boards myself in order to do some testing.
more info to follow...