different image for both sides

SpokePOV kit for bikes

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
carmatic1
 
Posts: 22
Joined: Fri Apr 01, 2011 12:40 pm

different image for both sides

Post by carmatic1 »

i dont know if this has been asked before but i would like to be able to make the spokepov display a different image on each side ... is that possible?

User avatar
adafruit_support_bill
 
Posts: 88088
Joined: Sat Feb 07, 2009 10:11 am

Re: different image for both sides

Post by adafruit_support_bill »

It should be possible to modify the firmware to display 2 banks on one side and the other 2 on the other side.

carmatic1
 
Posts: 22
Joined: Fri Apr 01, 2011 12:40 pm

Re: different image for both sides

Post by carmatic1 »

from line 264 to 278 of main.c

Code: Select all

void clock_leds(uint8_t select) {
  uint8_t *leds;

  if (select == FRONT)
    leds = fleds;
  else
    leds = bleds;

  spi_transfer(leds[3]);
  spi_transfer(leds[2]);
  spi_transfer(leds[1]);
  spi_transfer(leds[0]);
  LATCH_SELECT_PORT |= _BV(select);
  NOP; NOP; NOP; NOP;
  LATCH_SELECT_PORT &= ~_BV(select);

by any chance does it involve this part of the code?
as in, is the LED data 'streamed' from the EEPROM straight into the latches, and i do 2 of the spi_transfer operations instead of one

or will having different images on each side not work, because the attiny2313 does not have enough ram to hold 2 images?

User avatar
adafruit_support_bill
 
Posts: 88088
Joined: Sat Feb 07, 2009 10:11 am

Re: different image for both sides

Post by adafruit_support_bill »

Not that familiar with the code myself, but I think this is the section of code you want:

Code: Select all

SIGNAL (SIG_OUTPUT_COMPARE1A) {
  uint16_t eepromaddr;

  sei();

  PORTB |= 0x2;

  eepromaddr = curr_eeprom_addr;

  if (sensor_timer < ((F_CPU/NUM_PIXELS)/256 * STANDBY_TIMEOUT)) {    
    // less than ~5 seconds since last sensor
    PORTA |= 0x1;
    eepromaddr %= NUM_PIXELS * 4;
    spieeprom_read_into_leds(eepromaddr + anim_eeprom_offset, FRONT);
    if (mirror) {
      spieeprom_read_into_leds(anim_eeprom_offset + (1024UL-eepromaddr), BACK);
    } else {
      LATCH_SELECT_PORT |= _BV(BACK);
      NOP; NOP; NOP; NOP;
      LATCH_SELECT_PORT &= ~_BV(BACK);
    }
      

carmatic1
 
Posts: 22
Joined: Fri Apr 01, 2011 12:40 pm

Re: different image for both sides

Post by carmatic1 »

arduwino wrote:Not that familiar with the code myself, but I think this is the section of code you want:
how about something like this...

Code: Select all

SIGNAL (SIG_OUTPUT_COMPARE1A) {
  uint16_t eepromaddr;
  uint16_t eepromaddr1;

  sei();

  PORTB |= 0x2;

  eepromaddr = curr_eeprom_addr;
  eepromaddr1 = curr_eeprom_addr1;

  if (sensor_timer < ((F_CPU/NUM_PIXELS)/256 * STANDBY_TIMEOUT)) {    
    // less than ~5 seconds since last sensor
    PORTA |= 0x1;
    eepromaddr %= NUM_PIXELS * 4;
    eepromaddr1%=NUM_PIXELS*4;
    spieeprom_read_into_leds(eepromaddr + anim_eeprom_offset, FRONT);
    spieeprom_read_into_leds(eepromaddr1 + anim_eeprom_offset, BACK);
    
 
    }
      
its probably all wrong and stuff... there are references to 'eeprom address' and i dont even know the structure of how the images are stored in the eeprom... can anyone who reads this help me out, it would be much appreciated indeed

::edit:: there are some other parts with references to 'front' and 'back', part of IF-ELSE statements, which look like they are responsible for the different images on each side... but i havent figured out how it accesses the four banks of images
just who exactly wrote the firmware?

carmatic1
 
Posts: 22
Joined: Fri Apr 01, 2011 12:40 pm

Re: different image for both sides

Post by carmatic1 »

i think the major problem i have right now is this part

Code: Select all

void delay_ms(unsigned char ms)
{
  unsigned short delay_count = F_CPU / 4000;
  
  unsigned short cnt;
  asm volatile ("\n"
		"L_dl1%=:\n\t"
		"mov %A0, %A2\n\t"
		"mov %B0, %B2\n"
		"L_dl2%=:\n\t"
		"sbiw %A0, 1\n\t"
		"brne L_dl2%=\n\t"
		"wdr\n\t"
		"dec %1\n\t" "brne L_dl1%=\n\t":"=&w" (cnt)
		:"r"(ms), "r"((unsigned short) (delay_count))
		);
}
there is also this part

Code: Select all


int main(void) {
  uint8_t buff[16];
  uint8_t i, n;
  uint8_t cmd;
  uint16_t addr;

  cmd = MCUSR;  // find out why we reset
  // clear reset flags immediately
  MCUSR = 0;
  // turn on watchdog timer immediately, this protects against
  // a 'stuck' system by resetting it
  WDTCSR = _BV(WDE) | _BV(WDP2) | _BV(WDP1); // 1 second
  
  ioinit();
  if ((cmd & _BV(PORF)) != 0)
    test_leds();  // test the LEDs only on power reset


  set_led(cmd+2, FRONT);  // show the reason for the last reset
  //set_led(2, FRONT);
  set_led(2, BACK);

  animation_time = internal_eeprom_read(EEPROM_ANIMATION);

  sei();
  
  // look for computer commands  
  while (1) {
    sei();
    cmd = tx_computer_byte(0);

    if (cmd == 0)
      break;
    else 
      cli();

    sensor_timer = 0;      // overloaded to reset communications timeout

    switch (cmd) {
    case COMP_CMD_RDEEPROM:
    case COMP_CMD_RDEEPROM16:
      if  (cmd == COMP_CMD_RDEEPROM16)
	n = 16;
      else
	n = 1;

      addr = tx_computer_byte(0);
      addr <<= 8;
      addr |= tx_computer_byte(0);
      
      if ((addr & 0x8000) != 0) {
      	tx_computer_byte(internal_eeprom_read(addr & 0xFF));
      } else {
	
	spieeprom_read(addr, buff, n);
	for (i=0; i<n; i++) {
	  tx_computer_byte(buff[i]);
	}
      }
what im thinking is where the animation is defined in the code... i need it to define animations which take up half the eeprom space, since there is going to be 2 animations, one for each side... then i should be able to address them as such

carmatic1
 
Posts: 22
Joined: Fri Apr 01, 2011 12:40 pm

Re: different image for both sides

Post by carmatic1 »

i think i got it figured out
lines 178 - 185

Code: Select all

#ifdef ANIMATE
  if (anim_timer != animation_time) {
    anim_timer++;
  } else {
    anim_timer = 0;
    anim_eeprom_offset += 1024;
  }
#endif
change "anim_eeprom_offset += 1024" to "anim_eeprom_offset +=2048

lines 86 - 105

Code: Select all

  uint16_t eepromaddr;

  sei();

  PORTB |= 0x2;

  eepromaddr = curr_eeprom_addr;

  if (sensor_timer < ((F_CPU/NUM_PIXELS)/256 * STANDBY_TIMEOUT)) {    
    // less than ~5 seconds since last sensor
    PORTA |= 0x1;
    eepromaddr %= NUM_PIXELS * 4;
    spieeprom_read_into_leds(eepromaddr + anim_eeprom_offset, FRONT);
    if (mirror) {
      spieeprom_read_into_leds(anim_eeprom_offset + (1024UL-eepromaddr), BACK);
    } else {
      LATCH_SELECT_PORT |= _BV(BACK);
      NOP; NOP; NOP; NOP;
      LATCH_SELECT_PORT &= ~_BV(BACK);
    }
replace everything bellow "spieeprom_read_into_leds(eepromaddr + anim_eeprom_offset, FRONT)" , beginning with if (mirror) and ending at ~_BV(BACK), with:

spieeprom_read_into_leds(eepromaddr + 1024 + anim_eeprom_offset, BACK)


the idea being that every bank is 1024 units, and the first pair of banks is for the first frame for both sides, and the second pair of banks is for the second frame... and since both sides are going to be displaying different images, the 'mirror' function is deleted

will this work? i havent soldered everything together yet, plus i dont have a serial port on my computer to connect the serial dongle...

User avatar
adafruit_support_bill
 
Posts: 88088
Joined: Sat Feb 07, 2009 10:11 am

Re: different image for both sides

Post by adafruit_support_bill »

It looks like you are on the right track there. :D

carmatic1
 
Posts: 22
Joined: Fri Apr 01, 2011 12:40 pm

Re: different image for both sides

Post by carmatic1 »

i think that having two images for both sides should be a standard feature, like maybe i could put another bit which is something like the 'mirror' bit, but triggers having different images for both sides... this will require modifying the software you install to recognize this 'different images' bit


like, it could be useful for graphics which combine 'forward-pointing' elements like arrows which should be mirrored, with un-mirrorable things like text


or, more importantly, it can be used to display a different image which is warped to compensate for the offset of the row of LED's on one side, so that when it is displayed it will look normal.... i dont think that there is enough resolution to produce a smooth image if this 'warping' is done onboard the spokepov, plus im not sure if it is even possible based on how the spokepov reads from the eeprom and stuff...

User avatar
fred_dot_u
 
Posts: 5
Joined: Tue Aug 21, 2007 9:07 pm

Re: different image for both sides

Post by fred_dot_u »

I've had my SpokePOV kits for quite some time and have not yet begun to build a single one. Other things have gotten in the way and continue to do so, but I'm hopeful that I'll be able to implement the devices on my velomobile wheels eventually. I plan to build a set of black wheel covers, either from lightweight carbon fiber or lightweight fiberglass and attach the SpokePOV boards to the covers with the LEDs protruding through. Since only one side of the wheel is visible, that leaves 30 LEDs without a home.

If one can program the unit to display different images on the second set of LEDs, would it then be possible to wire the second set to a point 180 degrees from the first, shift the second image and have the equivalent of two SpokePov units installed? The magnet would trigger all the lights at the same time, so does that mean that the second image should be rotated by 180 degrees?

I'm also hoping to build a contact disk at the inner hub, with brushes to transfer power from a battery pack inside the vehicle to the wheels, to reduce the rotating mass. I'll probably have to remote the power switch too, just to make things that much more convenient.

I have yet to build the wheels on which this would be mounted and when the wheels are built, I plan to pull a mold for making the covers, then I have to make the covers and then build the kit, so I'm figuring if I get it done by the end of 2012, I'll be doing well enough.

carmatic1
 
Posts: 22
Joined: Fri Apr 01, 2011 12:40 pm

Re: different image for both sides

Post by carmatic1 »

fred_dot_u wrote: If one can program the unit to display different images on the second set of LEDs, would it then be possible to wire the second set to a point 180 degrees from the first, shift the second image and have the equivalent of two SpokePov units installed? The magnet would trigger all the lights at the same time, so does that mean that the second image should be rotated by 180 degrees?
in your case, seeing that you want to have both 'sides' of the spokepov display the same image but offset, i think that the code for that is to leave anim_eeprom_offset at 1024 since you are displaying one bank at a time i.e. one image at a time

then replace the code i replaced, at lines 86 - 105 , with this

Code: Select all

if (eepromaddr > 512) {
      spieeprom_read_into_leds(eepromaddr - 512 + anim_eeprom_offset, BACK);
    } else {
    spieeprom_read_into_leds(eepromaddr + 512 + anim_eeprom_offset, BACK);
    }
since you are going to make the 'back' LED's display the image at halfway across from what the front LED's are doing, so you make it read 512 units away, since each bank is 1024 units ... if the eepromaddr value is less than half then you read it halfway higher, if it is more than half , you read it halfway lower , so it never exceeds the size of a bank

this is based on my very limited understanding of the code... sorry to turn this into another question but can anyone tell me if im missing anything? will this work...

Locked
Please be positive and constructive with your questions and comments.

Return to “SpokePOV (discontinued)”