Hello all!
First I wanted to thank you for this wonderful forum!
I am a reader since years, but never dared to join.
Im having a problem since years, but first some details:
Im using a TEENSY 1.0 with the attached code.
A 433,92MHz transmitter is connected to PIN C6, and I can successfully control my low-budget-home-automation
A Fritz!Box with the modded Freetz-FW serves a Webserver for a CGI-Perl-script which communicates with teensy.
CGI-CODE:
Now I can successfully send my commands via http. Then I wrote an android app with "AppInventor" and now I can control my home via voice commands.
The Problem:
When I send too many commands too fast, the teensy hangs up. Only way to get it back is to plug out the teensy and replug it :/
[For a workaround I used a 2nd teensy with 2 relays for an automated plug-out-plug-in-function]
Tried to slim down the code to a minimum, but I cant figure out how to solve the "crash".
Sorry for beeing such a noob <3
Complete Code:
Attempt to delete unnecessary functions:
I know its a mess. Cherrypicked codesnippets and modified them. Felt like an 8th wonder, that it actually worked.
If anybody has got an idea how to optimize it, or even knows how to eliminate the hang-bug, I would be very happy.
Goal:
teensy gets a 13-chars command [First is identifier, other 12 is the Code to process]
Send processed code to the 433,92Mhz transmitter.
Since I don't need the teensy to answer on serial, I thought perhaps one could use the transmitting-usb-serial-buffer to double recieving-buffer?
But I don't know, if its even a buffer problem.
Gratefully
Blade
First I wanted to thank you for this wonderful forum!
I am a reader since years, but never dared to join.
Im having a problem since years, but first some details:
Im using a TEENSY 1.0 with the attached code.
A 433,92MHz transmitter is connected to PIN C6, and I can successfully control my low-budget-home-automation
A Fritz!Box with the modded Freetz-FW serves a Webserver for a CGI-Perl-script which communicates with teensy.
CGI-CODE:
Code:
#!/bin/sh
FC=`echo "$QUERY_STRING" | sed -n 's/^.*FC=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"`
FC1="$FC\r\n"
echo "$FC1" > /dev/ttyACM0
The Problem:
When I send too many commands too fast, the teensy hangs up. Only way to get it back is to plug out the teensy and replug it :/
[For a workaround I used a 2nd teensy with 2 relays for an automated plug-out-plug-in-function]
Tried to slim down the code to a minimum, but I cant figure out how to solve the "crash".
Sorry for beeing such a noob <3
Complete Code:
Code:
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdint.h>
#include <util/delay.h>
#include <usb_serial.h>
#include <stdlib.h>
#include <string.h>
#define OUTPUT_ON (PORTC |= (1<<6))
#define OUTPUT_OFF (PORTC &= ~(1<<6))
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
char* kompletterCode="1234567890123";
void send_str(const char *s);
uint8_t recv_str(char *buf, uint8_t size);
void parse_and_execute_command(const char *buf, uint8_t num);
void sendeCodes( char* code );
#if 0
// Very simple character echo test
int main(void)
{
CPU_PRESCALE(0);
usb_init();
while (1) {
int n = usb_serial_getchar();
if (n >= 0) usb_serial_putchar(n);
}
}
#else
// Basic command interpreter for controlling port pins
int main(void)
{
char buf[16];
uint8_t n;
// set for 16 MHz clock, and turn on the LED
CPU_PRESCALE(0);
// initialize the USB, and then wait for the host
// to set configuration. If the Teensy is powered
// without a PC connected to the USB port, this
// will wait forever.
usb_init();
while (!usb_configured()) /* wait */ ;
_delay_ms(1000);
while (1) {
while (1) {
n = recv_str(buf, sizeof(buf));
if (n == 255) break;
parse_and_execute_command(buf, n);
}
}
}
#endif
void send_str(const char *s)
{
char c;
while (1) {
c = pgm_read_byte(s++);
if (!c) break;
usb_serial_putchar(c);
}
}
void sender(int state) {
if (state == '0') {
*(uint8_t *)(0x21 + ('C' - 'A') * 3) |= (1 << 6);
*(uint8_t *)(0x22 + ('C' - 'A') * 3) &= ~(1 << 6);
return;
}
else if (state == '1') {
*(uint8_t *)(0x21 + ('C' - 'A') * 3) |= (1 << 6);
*(uint8_t *)(0x22 + ('C' - 'A') * 3) |= (1 << 6);
return;
} else {
return;}
}
uint8_t recv_str(char *buf, uint8_t size)
{
int16_t r;
uint8_t count=0;
while (count < size) {
r = usb_serial_getchar();
if (r != -1) {
if (r == '\r' || r == '\n') return count;
if (r >= ' ' && r <= '~') {
*buf++ = r;
usb_serial_putchar(r);
count++;
}
} else {
if (!usb_configured() ||
!(usb_serial_get_control() & USB_SERIAL_DTR)) {
// user no longer connected
return 255;
}
// just a normal timeout, keep waiting
}
}
return count;
}
void wait(void){
_delay_us(345);
return;
}
void sendeNull(void)
{
sender('1');
wait();
sender('0');
wait();
// sender('0')
wait();
// sender('0')
wait();
// die nächsten 4 Tasks
sender('1');
wait();
sender('0');
wait();
// sender('0')
wait();
// sender('0')
wait();
return;
}
void sendeFloat(void)
{
sender('1');
wait();
sender('0');
wait();
wait();
wait();
sender('1');
wait();
wait();
wait();
sender('0');
wait();
return;
}
void sendeEins(void)
{
sender('1');
wait();
sender('1');
wait();
sender('1');
wait();
sender('0');
wait();
// die nächsten 4 tasks
sender('1');
wait();
sender('1');
wait();
sender('1');
wait();
sender('0');
wait();
return;
}
void sendeSync(void)
{
// Gesamtlänge 32 Takte
sender('1');
wait();
sender('0');
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
return;
}
void sendeCodes( char* code ) {
char ch;
for (int i=1; i<=5; i++)
{
for(int i2=0; i2<=11; i2++)
{
ch = code[i2];
if (ch == '1') {
sendeEins();
} else if (ch == '0'){
sendeNull();
} else if (ch == 'F'){
sendeFloat();
}
}
sendeSync();
}
}
void parse_and_execute_command(const char *buf, uint8_t num)
{
if (buf[0] == 'a') {
const char* from = buf;
char *to = (char*) malloc(13);;
strncpy(to, from+1, 12);
kompletterCode=to;
sendeCodes( kompletterCode );
usb_serial_flush_input();
} else {
usb_serial_flush_input();
return;
}
}
Attempt to delete unnecessary functions:
Code:
#include <avr/io.h>
#include <util/delay.h>
#include <usb_serial.h>
#define OUTPUT_ON (PORTC |= (1<<6))
#define OUTPUT_OFF (PORTC &= ~(1<<6))
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
char* kompletterCode="1234567890123";
uint8_t recv_str(char *buf, uint8_t size);
void parse_and_execute_command(const char *buf, uint8_t num);
void sendeCodes( char* code );
int main(void)
{
char buf[13];
uint8_t n;
// set for 16 MHz clock, and turn on the LED
CPU_PRESCALE(0);
// initialize the USB, and then wait for the host
// to set configuration. If the Teensy is powered
// without a PC connected to the USB port, this
// will wait forever.
usb_init();
while (!usb_configured()) /* wait */ ;
_delay_ms(1000);
while (1) {
while (1) {
n = recv_str(buf, sizeof(buf));
if (n == 255) break;
parse_and_execute_command(buf, n);
}
}
}
void sender(int state) {
if (state == '0') {
*(uint8_t *)(0x21 + ('C' - 'A') * 3) |= (1 << 6);
*(uint8_t *)(0x22 + ('C' - 'A') * 3) &= ~(1 << 6);
return;
}
else if (state == '1') {
*(uint8_t *)(0x21 + ('C' - 'A') * 3) |= (1 << 6);
*(uint8_t *)(0x22 + ('C' - 'A') * 3) |= (1 << 6);
return;
} else {
return;}
}
uint8_t recv_str(char *buf, uint8_t size)
{
int16_t r;
uint8_t count=0;
while (count < size) {
r = usb_serial_getchar();
if (r != -1) {
if (r == '\r' || r == '\n') return count;
if (r >= ' ' && r <= '~') {
*buf++ = r;
count++;
}
} else {
if (!usb_configured() ||
!(usb_serial_get_control() & USB_SERIAL_DTR)) {
// user no longer connected
return 255;
}
// just a normal timeout, keep waiting
}
}
return count;
}
void wait(void){
_delay_us(345);
return;
}
void sendeNull(void)
{
sender('1');
wait();
sender('0');
wait();
// sender('0')
wait();
// sender('0')
wait();
// die nächsten 4 Tasks
sender('1');
wait();
sender('0');
wait();
// sender('0')
wait();
// sender('0')
wait();
return;
}
void sendeFloat(void)
{
sender('1');
wait();
sender('0');
wait();
wait();
wait();
sender('1');
wait();
wait();
wait();
sender('0');
wait();
return;
}
void sendeEins(void)
{
sender('1');
wait();
sender('1');
wait();
sender('1');
wait();
sender('0');
wait();
// die nächsten 4 tasks
sender('1');
wait();
sender('1');
wait();
sender('1');
wait();
sender('0');
wait();
return;
}
void sendeSync(void)
{
// Gesamtlänge 32 Takte
sender('1');
wait();
sender('0');
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
wait();
return;
}
void sendeCodes( char* code ) {
char ch;
for (int i=1; i<=3; i++)
{
for(int i2=0; i2<=11; i2++)
{
ch = code[i2];
if (ch == '1') {
sendeEins();
} else if (ch == '0'){
sendeNull();
} else if (ch == 'F'){
sendeFloat();
}
}
sendeSync();
}
}
void parse_and_execute_command(const char *buf, uint8_t num)
{
if (buf[0] == 'a') {
const char* from = buf;
char *to = (char*) malloc(13);;
strncpy(to, from+1, 12);
kompletterCode=to;
sendeCodes( kompletterCode );
usb_serial_flush_input();
} else {
usb_serial_flush_input();
return;
}
}
I know its a mess. Cherrypicked codesnippets and modified them. Felt like an 8th wonder, that it actually worked.
If anybody has got an idea how to optimize it, or even knows how to eliminate the hang-bug, I would be very happy.
Goal:
teensy gets a 13-chars command [First is identifier, other 12 is the Code to process]
Send processed code to the 433,92Mhz transmitter.
Since I don't need the teensy to answer on serial, I thought perhaps one could use the transmitting-usb-serial-buffer to double recieving-buffer?
But I don't know, if its even a buffer problem.
Gratefully
Blade