Так в чем проблема-то? Читаете датчик, пусть =1 или "многа" (есть просвет) ставите флаг "просвет" и читаете датчик до тех пор пока он не скажет =0 или "мало" (темно, зубец). Сбрасываете флаг "просвет" и ждете пока он не появится повторно.
Смысл в том, что надо ловить состояния перехода между зубцом и дыркой. Пока движется зубец или пока его нет, ваш датчик прочитает одно и тоже состояние "многа раз". Чтобы исключить это, требуется флаг, типа "ты такое уже видел, жди"..
Итого, примерный алгоритм:
Устанавливаем в сетапе:
1. флагПросвета = 0 (зубец, оно же "темно")
Повторяем в лупе:
2. Пока чтение датчика == флагПросвета { пусто, тупо ждем }
3. Упс .. светло, стало быть зубец кончился флагПросвета = 1 (просвет, оно же "светло")
4 тут .. считаем количество, управляем двиглом и т.д.
Условие 2 можно инвертировать, тогда можно состояние "тупо ждем" реализовывать проходом того же loop() делая что-то "попутно" или реализовать что-то ещё через idle() .. в общем, как основа.
Дальше Ваша фантазия.